diff --git a/CMakeLists.txt b/CMakeLists.txt index de5b86f2655056eb73e1eff34e01e2ec3fce1067..87f693ce8f15040dec97208f3d0ec55173b55224 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,7 @@ endif() if(NOT DEFINED CELLFRAME_MODULES) include (dap-sdk/cmake/OS_Detection.cmake) - set(CELLFRAME_MODULES "core chains mining network srv cs-dag-poa cs-block-poa cs-dag-pos cs-block-pos cs-esbocs cs-none srv-app srv-app-db srv-datum srv-stake srv-xchange") + set(CELLFRAME_MODULES "core chains mining network srv cs-dag-poa cs-block-poa cs-dag-pos cs-block-pos cs-esbocs cs-none srv-app srv-app-db srv-datum srv-stake srv-voting srv-bridge srv-xchange") if(LINUX OR DARWIN) set(CELLFRAME_MODULES "${CELLFRAME_MODULES} srv-vpn") @@ -183,6 +183,19 @@ if (CELLFRAME_MODULES MATCHES "srv-stake") set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_net_srv_stake) endif() + +# Enable service bridge +if (CELLFRAME_MODULES MATCHES "srv-bridge") + message("[+] Module 'srv-bridge'") + set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_net_srv_bridge) +endif() + +# Enable service voting +if (CELLFRAME_MODULES MATCHES "srv-voting") + message("[+] Module 'srv-voting'") + set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_net_srv_voting) +endif() + # Enable service for dynamic modules if (CELLFRAME_MODULES MATCHES "modules-dynamic") message("[+] Module 'dap_modules_dynamic_cdb'") diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 1aca3bdd4b20b06554a6cc296a9731a0bcbd42e9..3b4079665a1c524cb670301839d79682a042ca25 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -20,7 +20,6 @@ if (CELLFRAME_MODULES MATCHES "network") add_subdirectory(mempool) add_subdirectory(net) add_subdirectory(net/srv) - add_subdirectory(json_rpc) # Stream channels add_subdirectory(channel/chain-net) endif() @@ -110,7 +109,12 @@ if (CELLFRAME_MODULES MATCHES "srv-stake") add_subdirectory(service/stake) endif() -# Unit tests -if( BUILD_TESTS) - add_subdirectory(test) +# Service for polls and voting +if (CELLFRAME_MODULES MATCHES "srv-voting") + add_subdirectory(service/voting) +endif() + +# Service for bridge +if (CELLFRAME_MODULES MATCHES "srv-bridge") + add_subdirectory(service/bridge) endif() diff --git a/modules/chain/dap_chain.c b/modules/chain/dap_chain.c index e6bef0653720859c136c9b607a419afa3f017c95..e8450ad2d2ef98a5ef9ad78bdc3fb00dc347d5ec 100644 --- a/modules/chain/dap_chain.c +++ b/modules/chain/dap_chain.c @@ -248,7 +248,7 @@ static dap_chain_type_t s_chain_type_from_str(const char *a_type_str) return CHAIN_TYPE_DECREE; if (!dap_strcmp(a_type_str, "anchor")) return CHAIN_TYPE_ANCHOR; - return CHAIN_TYPE_LAST; + return CHAIN_TYPE_INVALID; } /** @@ -445,7 +445,7 @@ dap_chain_t *dap_chain_load_from_cfg(const char *a_chain_net_name, dap_chain_net for (uint16_t i = 0; i < l_datum_types_count; i++) { dap_chain_type_t l_chain_type = s_chain_type_from_str(l_datum_types[i]); - if (l_chain_type != CHAIN_TYPE_LAST) + if (l_chain_type != CHAIN_TYPE_INVALID) { l_chain->datum_types[l_count_recognized] = l_chain_type; l_count_recognized++; @@ -470,7 +470,7 @@ dap_chain_t *dap_chain_load_from_cfg(const char *a_chain_net_name, dap_chain_net for (uint16_t i = 0; i < l_default_datum_types_count; i++) { dap_chain_type_t l_chain_type = s_chain_type_from_str(l_default_datum_types[i]); - if (l_chain_type != CHAIN_TYPE_LAST + if (l_chain_type != CHAIN_TYPE_INVALID && s_chain_in_chain_types(l_chain_type, l_chain->datum_types, l_chain->datum_types_count))// <<--- check this chain_type in readed datum_types { l_chain->default_datum_types[l_count_recognized] = l_chain_type; @@ -542,6 +542,21 @@ bool dap_chain_has_file_store(dap_chain_t * a_chain) } +/** + * @brief get type of chain + * + * @param l_chain + * @return char* + */ +const char *dap_chain_get_cs_type(dap_chain_t *l_chain) +{ + if (!l_chain){ + log_it(L_DEBUG, "dap_get_chain_type. Chain object is 0"); + return NULL; + } + return (const char *)DAP_CHAIN_PVT(l_chain)->cs_name; +} + /** * @brief dap_chain_save_all * @param l_chain @@ -723,8 +738,9 @@ ssize_t dap_chain_atom_save(dap_chain_cell_t *a_chain_cell, const uint8_t *a_ato dap_cluster_t *l_net_cluster = dap_cluster_find(dap_guuid_compose(l_chain->net_id.uint64, 0)); if (l_net_cluster) { size_t l_pkt_size = a_atom_size + sizeof(dap_chain_ch_pkt_t); - dap_chain_ch_pkt_t *l_pkt = dap_chain_ch_pkt_new(l_chain->net_id.uint64, l_chain->id.uint64, - a_chain_cell->id.uint64, a_atom, a_atom_size); + dap_chain_ch_pkt_t *l_pkt = dap_chain_ch_pkt_new(l_chain->net_id, l_chain->id, + a_chain_cell->id, a_atom, a_atom_size, + DAP_CHAIN_CH_PKT_VERSION_CURRENT); if (l_pkt) { dap_gossip_msg_issue(l_net_cluster, DAP_CHAIN_CH_ID, l_pkt, l_pkt_size, a_new_atom_hash); DAP_DELETE(l_pkt); @@ -738,7 +754,7 @@ ssize_t dap_chain_atom_save(dap_chain_cell_t *a_chain_cell, const uint8_t *a_ato dap_chain_atom_notifier_t *l_notifier = (dap_chain_atom_notifier_t*)l_iter->data; struct chain_thread_notifier *l_arg = DAP_NEW_Z(struct chain_thread_notifier); if (!l_arg) { - log_it(L_CRITICAL, g_error_memory_alloc); + log_it(L_CRITICAL, "%s", g_error_memory_alloc); continue; } *l_arg = (struct chain_thread_notifier) { .callback = l_notifier->callback, .callback_arg = l_notifier->arg, @@ -746,7 +762,7 @@ ssize_t dap_chain_atom_save(dap_chain_cell_t *a_chain_cell, const uint8_t *a_ato l_arg->atom = DAP_DUP_SIZE(a_atom, a_atom_size); if (!l_arg->atom) { DAP_DELETE(l_arg); - log_it(L_CRITICAL, g_error_memory_alloc); + log_it(L_CRITICAL, "%s", g_error_memory_alloc); continue; } dap_proc_thread_callback_add_pri(NULL, s_notify_atom_on_thread, l_arg, DAP_QUEUE_MSG_PRIORITY_LOW); @@ -808,3 +824,25 @@ const char* dap_chain_get_path(dap_chain_t *a_chain) return DAP_CHAIN_PVT(a_chain)->file_storage_dir; } +const char *dap_chain_type_to_str(const dap_chain_type_t a_default_chain_type) { + switch (a_default_chain_type) + { + case CHAIN_TYPE_INVALID: + return "invalid"; + case CHAIN_TYPE_TOKEN: + return "token"; + case CHAIN_TYPE_EMISSION: + return "emission"; + case CHAIN_TYPE_TX: + return "transaction"; + case CHAIN_TYPE_CA: + return "ca"; + case CHAIN_TYPE_SIGNER: + return "signer"; + case CHAIN_TYPE_DECREE: + return "decree"; + case CHAIN_TYPE_ANCHOR: + return "anchor"; + } + return "invalid"; +} diff --git a/modules/chain/dap_chain_ch.c b/modules/chain/dap_chain_ch.c index 2a8d8a77d79f1d099acf73b71a559a94bcf0f3af..171fbd1bf6b0c6359037d0c670151cd4da1d21ba 100644 --- a/modules/chain/dap_chain_ch.c +++ b/modules/chain/dap_chain_ch.c @@ -23,41 +23,17 @@ along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. */ -#include <stdlib.h> -#include <stdio.h> -#include <stdlib.h> -#include <stddef.h> -#include <stdint.h> - -#ifdef WIN32 -#include <winsock2.h> -#include <windows.h> -#include <mswsock.h> -#include <ws2tcpip.h> -#include <io.h> -#include <pthread.h> -#endif - #include "dap_common.h" -#include "dap_strfuncs.h" #include "dap_list.h" #include "dap_config.h" #include "dap_hash.h" #include "dap_time.h" -#include "utlist.h" - #include "dap_worker.h" -#include "dap_events.h" #include "dap_proc_thread.h" -#include "dap_client_pvt.h" - #include "dap_chain.h" -#include "dap_chain_datum.h" -#include "dap_chain_cs.h" #include "dap_chain_cell.h" - -#include "dap_global_db.h" - +#include "dap_global_db_legacy.h" +#include "dap_global_db_ch.h" #include "dap_stream.h" #include "dap_stream_pkt.h" #include "dap_stream_worker.h" @@ -70,30 +46,7 @@ #define LOG_TAG "dap_chain_ch" -struct sync_request -{ - dap_worker_t * worker; - dap_stream_ch_uuid_t ch_uuid; - dap_chain_ch_sync_request_old_t request; - dap_chain_ch_pkt_hdr_t request_hdr; - dap_chain_pkt_item_t pkt; - - dap_chain_ch_hash_item_t *remote_atoms; // Remote atoms - dap_chain_ch_hash_item_t *remote_gdbs; // Remote gdbs - - uint64_t stats_request_elemets_processed; - int last_err; - union{ - struct{ - //dap_db_log_list_t *db_log; // db log - dap_list_t *db_iter; - char *sync_group; - } gdb; - struct{ - dap_chain_atom_iter_t *request_atom_iter; - } chain; - }; -}; +#define DAP_CHAIN_PKT_EXPECT_SIZE DAP_STREAM_PKT_FRAGMENT_SIZE enum sync_context_state { SYNC_STATE_IDLE, @@ -114,45 +67,83 @@ struct sync_context { dap_time_t last_activity; }; -static void s_ch_chain_go_idle(dap_chain_ch_t *a_ch_chain); -static inline bool s_ch_chain_get_idle(dap_chain_ch_t *a_ch_chain) { return a_ch_chain->state == DAP_CHAIN_CH_STATE_IDLE; } +typedef struct dap_chain_ch_hash_item { + dap_hash_fast_t hash; + uint32_t size; + UT_hash_handle hh; +} dap_chain_ch_hash_item_t; -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 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); +struct legacy_sync_context { + dap_stream_worker_t *worker; + dap_stream_ch_uuid_t ch_uuid; + dap_stream_node_addr_t remote_addr; + dap_chain_ch_pkt_hdr_t request_hdr; -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); -static void s_sync_out_chains_first_worker_callback(dap_worker_t *a_worker, void *a_arg); + _Atomic(dap_chain_ch_state_t) state; + dap_chain_ch_error_type_t last_error; + + bool is_type_of_gdb; + union { + struct { + dap_chain_ch_hash_item_t *remote_atoms; // Remote atoms + dap_chain_atom_iter_t *atom_iter; // Atom iterator + uint64_t stats_request_atoms_processed; // Atoms statictic + }; + struct { + dap_chain_ch_hash_item_t *remote_gdbs; // Remote gdbs + dap_global_db_legacy_list_t *db_list; // DB iterator + uint64_t stats_request_gdbs_processed; // DB statictic + }; + }; -static bool s_sync_out_gdb_proc_callback(void *a_arg); + dap_time_t last_activity; + dap_chain_ch_state_t prev_state; + size_t enqueued_data_size; +}; -static bool s_sync_in_chains_callback(void *a_arg); +typedef struct dap_chain_ch { + void *_inheritor; + dap_timerfd_t *sync_timer; + struct sync_context *sync_context; + + // Legacy section // + dap_timerfd_t *activity_timer; + uint32_t timer_shots; + int sent_breaks; + struct legacy_sync_context *legacy_sync_context; +} dap_chain_ch_t; + +#define DAP_CHAIN_CH(a) ((dap_chain_ch_t *) ((a)->internal) ) +#define DAP_STREAM_CH(a) ((dap_stream_ch_t *)((a)->_inheritor)) + +static void s_ch_chain_go_idle(dap_chain_ch_t *a_ch_chain); + +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 bool s_stream_ch_packet_in(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 bool s_sync_in_chains_callback(void *a_arg); +static bool s_sync_out_chains_proc_callback(void *a_arg); static bool s_gdb_in_pkt_proc_callback(void *a_arg); -static bool s_gdb_in_pkt_proc_set_raw_callback(dap_global_db_instance_t *a_dbi, - int a_rc, const char *a_group, - const size_t a_values_total, const size_t a_values_count, - dap_store_obj_t *a_values, void *a_arg); -static void s_gdb_in_pkt_error_worker_callback(dap_worker_t *a_thread, void *a_arg); +static bool s_sync_out_gdb_proc_callback(void *a_arg); static void s_stream_ch_chain_pkt_write(dap_stream_ch_t *a_ch, uint8_t a_type, uint64_t a_net_id, uint64_t a_chain_id, uint64_t a_cell_id, const void * a_data, size_t a_data_size); + static void s_gossip_payload_callback(void *a_payload, size_t a_payload_size, dap_stream_node_addr_t a_sender_addr); static bool s_chain_iter_callback(void *a_arg); static bool s_chain_iter_delete_callback(void *a_arg); static bool s_sync_timer_callback(void *a_arg); -static bool s_debug_more = false; +static bool s_debug_more = false, s_debug_legacy = false; static uint32_t s_sync_timeout = 30; static uint32_t s_sync_packets_per_thread_call = 10; static uint32_t s_sync_ack_window_size = 100; // atoms -static uint_fast16_t s_update_pack_size=100; // Number of hashes packed into the one packet -static uint_fast16_t s_skip_in_reactor_count=50; // Number of hashes packed to skip in one reactor loop callback out packet +// Legacy +static uint_fast16_t s_update_pack_size = 100; // Number of hashes packed into the one packet #ifdef DAP_SYS_DEBUG @@ -170,8 +161,12 @@ static const char *s_error_type_to_string(dap_chain_ch_error_type_t a_error) return "SYNC_REQUEST_ALREADY_IN_PROCESS"; case DAP_CHAIN_CH_ERROR_INCORRECT_SYNC_SEQUENCE: return "INCORRECT_SYNC_SEQUENCE"; + case DAP_CHAIN_CH_ERROR_SYNC_TIMEOUT: + return "SYNCHRONIZATION TIMEOUT"; case DAP_CHAIN_CH_ERROR_CHAIN_PKT_DATA_SIZE: - return "IVALID_PACKET_SIZE"; + return "INVALID_PACKET_SIZE"; + case DAP_CHAIN_CH_ERROR_LEGACY_PKT_DATA_SIZE: + return "INVALID_LEGACY_PACKET_SIZE"; case DAP_CHAIN_CH_ERROR_NET_INVALID_ID: return "INVALID_NET_ID"; case DAP_CHAIN_CH_ERROR_CHAIN_NOT_FOUND: @@ -200,12 +195,12 @@ 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 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); + dap_stream_ch_proc_add(DAP_CHAIN_CH_ID, s_stream_ch_new, s_stream_ch_delete, s_stream_ch_packet_in, NULL); s_sync_timeout = dap_config_get_item_uint32_default(g_config, "chain", "sync_timeout", s_sync_timeout); s_sync_ack_window_size = dap_config_get_item_uint32_default(g_config, "chain", "sync_ack_window_size", s_sync_ack_window_size); s_sync_packets_per_thread_call = dap_config_get_item_int16_default(g_config, "chain", "pack_size", s_sync_packets_per_thread_call); s_debug_more = dap_config_get_item_bool_default(g_config, "chain", "debug_more", false); + s_debug_legacy = dap_config_get_item_bool_default(g_config, "chain", "debug_legacy", false); #ifdef DAP_SYS_DEBUG for (int i = 0; i < MEMSTAT$K_NR; i++) dap_memstat_reg(&s_memstat[i]); @@ -226,7 +221,7 @@ void dap_chain_ch_deinit() * @param a_ch * @param arg */ -void s_stream_ch_new(dap_stream_ch_t* a_ch, void* a_arg) +void s_stream_ch_new(dap_stream_ch_t *a_ch, void *a_arg) { UNUSED(a_arg); if (!(a_ch->internal = DAP_NEW_Z(dap_chain_ch_t))) { @@ -235,7 +230,6 @@ void s_stream_ch_new(dap_stream_ch_t* a_ch, void* a_arg) }; dap_chain_ch_t *l_ch_chain = DAP_CHAIN_CH(a_ch); l_ch_chain->_inheritor = a_ch; - a_ch->stream->esocket->callbacks.write_finished_callback = s_stream_ch_io_complete; #ifdef DAP_SYS_DEBUG atomic_fetch_add(&s_memstat[MEMSTAT$K_STM_CH_CHAIN].alloc_nr, 1); @@ -261,313 +255,342 @@ static void s_stream_ch_delete(dap_stream_ch_t *a_ch, void *a_arg) #endif } +// *** Legacy support code *** // + /** - * @brief s_stream_ch_chain_delete + * @brief dap_chain_ch_create_sync_request_gdb * @param a_ch_chain + * @param a_net */ -static void s_sync_request_delete(struct sync_request * a_sync_request) +struct legacy_sync_context *s_legacy_sync_context_create(dap_chain_ch_pkt_t *a_chain_pkt, dap_stream_ch_t *a_ch) { - if (!a_sync_request) { - //already NULL'ed - return; - } - if (a_sync_request->pkt.pkt_data) { - DAP_DEL_Z(a_sync_request->pkt.pkt_data); - } + dap_chain_ch_t * l_ch_chain = DAP_CHAIN_CH(a_ch); + dap_return_val_if_fail(l_ch_chain, NULL); - if (a_sync_request->gdb.db_iter) { - a_sync_request->gdb.db_iter = dap_list_first( a_sync_request->gdb.db_iter); - dap_list_free_full( a_sync_request->gdb.db_iter, NULL); - a_sync_request->gdb.db_iter = NULL; + struct legacy_sync_context *l_context; + DAP_NEW_Z_RET_VAL(l_context, struct legacy_sync_context, NULL, NULL); + + *l_context = (struct legacy_sync_context) { + .worker = a_ch->stream_worker, + .ch_uuid = a_ch->uuid, + .remote_addr = *(dap_stream_node_addr_t *)a_chain_pkt->data, + .request_hdr = a_chain_pkt->hdr, + .state = DAP_CHAIN_CH_STATE_IDLE, + .last_activity = dap_time_now() + }; + dap_stream_ch_uuid_t *l_uuid = DAP_DUP(&a_ch->uuid); + if (!l_uuid) { + log_it(L_CRITICAL, "%s", g_error_memory_alloc); + DAP_DELETE(l_context); + return NULL; } - DAP_DEL_Z(a_sync_request); + l_ch_chain->sync_timer = dap_timerfd_start_on_worker(a_ch->stream_worker->worker, 1000, s_sync_timer_callback, l_uuid); + a_ch->stream->esocket->callbacks.write_finished_callback = s_stream_ch_io_complete; + a_ch->stream->esocket->callbacks.arg = l_context; + if (l_context->worker->worker->_inheritor != a_ch->stream_worker) + log_it(L_CRITICAL, "Corrupted stream worker %p", a_ch->stream_worker); + return l_context; } /** - * @brief s_sync_out_chains_worker_callback - * @param a_worker - * @param a_arg + * @brief s_stream_ch_chain_delete + * @param a_ch_chain */ -static void s_sync_out_chains_first_worker_callback(dap_worker_t *a_worker, void *a_arg) +static void s_legacy_sync_context_delete(void *a_arg) { - struct sync_request * l_sync_request = (struct sync_request *) a_arg; - dap_stream_ch_t *l_ch = dap_stream_ch_find_by_uuid_unsafe( DAP_STREAM_WORKER(a_worker) , l_sync_request->ch_uuid); - if( l_ch == NULL ){ - log_it(L_INFO,"Client disconnected before we sent the reply"); - s_sync_request_delete(l_sync_request); - return; - } + struct legacy_sync_context *l_context = a_arg; + dap_return_if_fail(l_context); - dap_chain_ch_t * l_ch_chain = DAP_CHAIN_CH(l_ch); - if (!l_ch_chain) { - log_it(L_CRITICAL, "Channel without chain, dump it"); - s_sync_request_delete(l_sync_request); - return; - } - if (l_ch_chain->state != DAP_CHAIN_CH_STATE_UPDATE_CHAINS_REMOTE) { - log_it(L_INFO, "Timeout fired before we sent the reply"); - s_sync_request_delete(l_sync_request); - return; - } + dap_chain_ch_hash_item_t *l_hash_item, *l_tmp; - l_ch_chain->state = DAP_CHAIN_CH_STATE_SYNC_CHAINS; - l_ch_chain->request_atom_iter = l_sync_request->chain.request_atom_iter; + if (l_context->is_type_of_gdb) { + HASH_ITER(hh, l_context->remote_gdbs, l_hash_item, l_tmp) { + // Clang bug at this, l_hash_item should change at every loop cycle + HASH_DEL(l_context->remote_gdbs, l_hash_item); + DAP_DELETE(l_hash_item); + } + l_context->remote_atoms = NULL; + + if (l_context->db_list) + dap_global_db_legacy_list_delete(l_context->db_list); + } else { + HASH_ITER(hh, l_context->remote_atoms, l_hash_item, l_tmp) { + // Clang bug at this, l_hash_item should change at every loop cycle + HASH_DEL(l_context->remote_atoms, l_hash_item); + DAP_DELETE(l_hash_item); + } + l_context->remote_gdbs = NULL; - if (s_debug_more ) - log_it(L_INFO,"Out: DAP_CHAIN_CH_PKT_TYPE_FIRST_CHAIN"); + if (l_context->atom_iter) + l_context->atom_iter->chain->callback_atom_iter_delete(l_context->atom_iter); + } - dap_chain_ch_pkt_write_unsafe(l_ch, DAP_CHAIN_CH_PKT_TYPE_FIRST_CHAIN, - 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)); - DAP_DELETE(l_sync_request); + dap_stream_ch_t *l_ch = dap_stream_ch_find_by_uuid_unsafe(l_context->worker, l_context->ch_uuid); + if (l_ch) { + DAP_CHAIN_CH(l_ch)->legacy_sync_context = NULL; + l_ch->stream->esocket->callbacks.write_finished_callback = NULL; + l_ch->stream->esocket->callbacks.arg = NULL; + } + DAP_DELETE(l_context); } -/** - * @brief s_sync_out_chains_last_worker_callback - * @param a_worker - * @param a_arg - */ -static void s_sync_out_chains_last_worker_callback(dap_worker_t *a_worker, void *a_arg) +static bool s_sync_out_gdb_proc_callback(void *a_arg) { - struct sync_request * l_sync_request = (struct sync_request *) a_arg; - dap_stream_ch_t *l_ch = dap_stream_ch_find_by_uuid_unsafe(DAP_STREAM_WORKER(a_worker), l_sync_request->ch_uuid); - if( l_ch == NULL ){ - log_it(L_INFO,"Client disconnected before we sent the reply"); - s_sync_request_delete(l_sync_request); - return; + struct legacy_sync_context *l_context = a_arg; + dap_chain_ch_state_t l_cur_state = l_context->state; + if (l_cur_state != DAP_CHAIN_CH_STATE_UPDATE_GLOBAL_DB && l_cur_state != DAP_CHAIN_CH_STATE_SYNC_GLOBAL_DB) { + // Illegal context + assert(l_cur_state == DAP_CHAIN_CH_STATE_IDLE); + goto context_delete; + } + dap_list_t *l_list_out = dap_global_db_legacy_list_get_multiple(l_context->db_list, s_update_pack_size); + if (!l_list_out) { + dap_chain_ch_sync_request_old_t l_payload = { .node_addr = g_node_addr }; + uint8_t l_type = l_cur_state == DAP_CHAIN_CH_STATE_UPDATE_GLOBAL_DB ? DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_END + : DAP_CHAIN_CH_PKT_TYPE_SYNCED_GLOBAL_DB; + debug_if(s_debug_legacy, L_INFO, "Out: %s", dap_chain_ch_pkt_type_to_str(l_type)); + dap_chain_ch_pkt_write_mt(l_context->worker, l_context->ch_uuid, l_type, + l_context->request_hdr.net_id, l_context->request_hdr.chain_id, l_context->request_hdr.cell_id, + &l_payload, sizeof(l_payload), DAP_CHAIN_CH_PKT_VERSION_LEGACY); + if (l_cur_state == DAP_CHAIN_CH_STATE_SYNC_GLOBAL_DB) { + log_it(L_INFO, "Synchronized database: items synchronized %" DAP_UINT64_FORMAT_U " from %zu", + l_context->stats_request_gdbs_processed, l_context->db_list->items_number); + l_context->state = DAP_CHAIN_CH_STATE_IDLE; + goto context_delete; + } + dap_global_db_legacy_list_rewind(l_context->db_list); + if (atomic_compare_exchange_strong(&l_context->state, &l_cur_state, DAP_CHAIN_CH_STATE_SYNC_GLOBAL_DB_REMOTE)) + return false; + goto context_delete; } - dap_chain_ch_t * l_ch_chain = DAP_CHAIN_CH(l_ch); - if (!l_ch_chain) { - log_it(L_CRITICAL, "Channel without chain, dump it"); - s_sync_request_delete(l_sync_request); - return; + void *l_data = NULL; + size_t l_data_size = 0; + uint8_t l_type = DAP_CHAIN_CH_PKT_TYPE_GLOBAL_DB; + if (l_cur_state == DAP_CHAIN_CH_STATE_UPDATE_GLOBAL_DB) { + l_type = DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB; + l_data_size = dap_list_length(l_list_out) * sizeof(dap_chain_ch_update_element_t); + l_data = DAP_NEW_Z_SIZE(dap_chain_ch_update_element_t, l_data_size); + if (!l_data) { + log_it(L_CRITICAL, "%s", g_error_memory_alloc); + l_context->state = DAP_CHAIN_CH_STATE_ERROR; + goto context_delete; + } } - l_ch_chain->request_atom_iter = l_sync_request->chain.request_atom_iter; - // last packet - 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); - DAP_DELETE(l_sync_request); -} -/** - * @brief s_sync_chains_callback - * @param a_thread - * @param a_arg - * @return - */ -static bool s_sync_out_chains_proc_callback(void *a_arg) -{ - struct sync_request * l_sync_request = (struct sync_request *) a_arg; - - dap_chain_t * l_chain = dap_chain_find_by_id(l_sync_request->request_hdr.net_id, l_sync_request->request_hdr.chain_id); - assert(l_chain); - l_sync_request->chain.request_atom_iter = l_chain->callback_atom_iter_create(l_chain, l_sync_request->request_hdr.cell_id, NULL, false); - size_t l_first_size = 0; - dap_chain_atom_ptr_t l_atom = l_chain->callback_atom_iter_get(l_sync_request->chain.request_atom_iter, DAP_CHAIN_ITER_OP_FIRST, &l_first_size); - if (l_atom && l_first_size) { - // first packet - dap_chain_hash_fast_t l_hash_from = l_sync_request->request.hash_from; - if (!dap_hash_fast_is_blank(&l_hash_from)) { - (void ) l_chain->callback_atom_find_by_hash(l_sync_request->chain.request_atom_iter, - &l_hash_from, &l_first_size); - } - dap_worker_exec_callback_on(dap_events_worker_get(l_sync_request->worker->id), s_sync_out_chains_first_worker_callback, l_sync_request ); - } else { - dap_worker_exec_callback_on(dap_events_worker_get(l_sync_request->worker->id),s_sync_out_chains_last_worker_callback, l_sync_request ); + bool l_go_wait = false; + size_t i = 0; + for (dap_list_t *it = l_list_out; it; it = it->next, i++) { + dap_global_db_pkt_old_t *l_pkt = it->data; + if (l_context->db_list->items_rest) + --l_context->db_list->items_rest; + dap_hash_t l_pkt_hash; + dap_hash_fast(l_pkt->data, l_pkt->data_size, &l_pkt_hash); + if (l_cur_state == DAP_CHAIN_CH_STATE_UPDATE_GLOBAL_DB) { + dap_chain_ch_update_element_t *l_hashes = l_data; + l_hashes[i].hash = l_pkt_hash; + l_hashes[i].size = l_pkt->data_size; + } else { // l_cur_state == DAP_CHAIN_CH_STATE_SYNC_GLOBAL_DB + dap_chain_ch_hash_item_t *l_hash_item = NULL; + HASH_FIND(hh, l_context->remote_gdbs, &l_pkt_hash, sizeof(dap_hash_fast_t), l_hash_item); + if (!l_hash_item) { + dap_global_db_pkt_old_t *l_pkt_pack = l_data; + size_t l_cur_size = l_pkt_pack ? l_pkt_pack->data_size : 0; + if (l_cur_size + sizeof(dap_global_db_pkt_old_t) + l_pkt->data_size >= DAP_CHAIN_PKT_EXPECT_SIZE) { + l_context->enqueued_data_size += l_data_size; + if (!l_go_wait && l_context->enqueued_data_size > DAP_EVENTS_SOCKET_BUF_SIZE / 2) { + if (!atomic_compare_exchange_strong(&l_context->state, &l_cur_state, DAP_CHAIN_CH_STATE_WAITING)) + goto context_delete; + l_context->prev_state = l_cur_state; + l_go_wait = true; + } + dap_chain_ch_pkt_write_mt(l_context->worker, l_context->ch_uuid, l_type, + l_context->request_hdr.net_id, l_context->request_hdr.chain_id, l_context->request_hdr.cell_id, + l_data, l_data_size, DAP_CHAIN_CH_PKT_VERSION_LEGACY); + debug_if(s_debug_legacy, L_INFO, "Send one global_db packet len=%zu (rest=%zu/%zu items)", l_data_size, + l_context->db_list->items_rest, l_context->db_list->items_number); + l_context->last_activity = dap_time_now(); + DAP_DEL_Z(l_pkt_pack); + l_cur_size = 0; + } + l_pkt_pack = dap_global_db_pkt_pack_old(l_pkt_pack, l_pkt); + if (!l_pkt_pack || l_cur_size == l_pkt_pack->data_size) { + log_it(L_CRITICAL, "%s", g_error_memory_alloc); + l_context->state = DAP_CHAIN_CH_STATE_ERROR; + goto context_delete; + } + l_context->stats_request_gdbs_processed++; + l_data = l_pkt_pack; + l_data_size = sizeof(dap_global_db_pkt_old_t) + l_pkt_pack->data_size; + } /* else // Over-extended debug + debug_if(s_debug_legacy, L_DEBUG, "Skip GDB hash %s because its already present in remote GDB hash table", + dap_hash_fast_to_str_static(&l_pkt_hash)); + */ + } + } + dap_list_free_full(l_list_out, NULL); + + if (l_data && l_data_size) { + dap_chain_ch_pkt_write_mt(l_context->worker, l_context->ch_uuid, l_type, + l_context->request_hdr.net_id, l_context->request_hdr.chain_id, l_context->request_hdr.cell_id, + l_data, l_data_size, DAP_CHAIN_CH_PKT_VERSION_LEGACY); + if (l_cur_state == DAP_CHAIN_CH_STATE_UPDATE_GLOBAL_DB) + debug_if(s_debug_legacy, L_INFO, "Out: %s, %zu records", dap_chain_ch_pkt_type_to_str(l_type), i); + else + debug_if(s_debug_legacy, L_INFO, "Send one global_db packet len=%zu (rest=%zu/%zu items)", l_data_size, + l_context->db_list->items_rest, l_context->db_list->items_number); + l_context->last_activity = dap_time_now(); + DAP_DELETE(l_data); + } else if (l_context->last_activity + 3 < dap_time_now()) { + l_context->last_activity = dap_time_now(); + debug_if(s_debug_more, L_INFO, "Send one GlobalDB no freeze packet"); + dap_chain_ch_pkt_write_mt(l_context->worker, l_context->ch_uuid, DAP_CHAIN_CH_PKT_TYPE_GLOBAL_DB_NO_FREEZE, + l_context->request_hdr.net_id, l_context->request_hdr.chain_id, + l_context->request_hdr.cell_id, NULL, 0, DAP_CHAIN_CH_PKT_VERSION_LEGACY); } + if (!l_go_wait) + return true; + return false; +context_delete: + dap_worker_exec_callback_on(l_context->worker->worker, s_legacy_sync_context_delete, l_context); return false; } +struct record_processing_args { + dap_stream_worker_t *worker; + dap_stream_ch_uuid_t uuid; + dap_chain_ch_pkt_hdr_t hdr; + dap_global_db_pkt_old_t *pkt; + bool new; +}; -/** - * @brief s_sync_out_gdb_first_gdb_worker_callback - * @param a_worker - * @param a_arg - */ -static void s_sync_out_gdb_first_worker_callback(dap_worker_t *a_worker, void *a_arg) +static bool s_gdb_in_pkt_proc_callback(void *a_arg) { - struct sync_request *l_sync_request = (struct sync_request *) a_arg; - - dap_stream_ch_t *l_ch = dap_stream_ch_find_by_uuid_unsafe(DAP_STREAM_WORKER(l_sync_request->worker), l_sync_request->ch_uuid); - if( l_ch == NULL ){ - log_it(L_INFO,"Client disconnected before we sent the reply"); - s_sync_request_delete(l_sync_request); - return; - } - - dap_chain_ch_t *l_ch_chain = DAP_CHAIN_CH( l_ch ); - - if (!l_ch_chain) { - log_it(L_CRITICAL, "Channel without chain, dump it"); - s_sync_request_delete(l_sync_request); - return; - } - - if (l_ch_chain->state != DAP_CHAIN_CH_STATE_UPDATE_GLOBAL_DB_REMOTE) { - log_it(L_INFO, "Timeout fired before we sent the reply"); - s_sync_request_delete(l_sync_request); - return; - } - - // Add it to outgoing list - l_ch_chain->state = DAP_CHAIN_CH_STATE_SYNC_GLOBAL_DB; - if (s_debug_more ) - log_it(L_INFO,"Out: DAP_CHAIN_CH_PKT_TYPE_FIRST_GLOBAL_DB"); - 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( a_worker){ // We send NULL to prevent delete - s_sync_request_delete(l_sync_request); + struct record_processing_args *l_args = a_arg; + size_t l_objs_count = 0; + dap_store_obj_t *l_objs = dap_global_db_pkt_deserialize_old(l_args->pkt, &l_objs_count); + DAP_DELETE(l_args->pkt); + if (!l_objs || !l_objs_count) { + log_it(L_WARNING, "Deserialization of legacy global DB packet failed"); + DAP_DELETE(l_args); + return false; } + bool l_success = false; + dap_stream_node_addr_t l_blank_addr = { .uint64 = 0 }; + for (uint32_t i = 0; i < l_objs_count; i++) + if (!(l_success = dap_global_db_ch_check_store_obj(l_objs + i, &l_blank_addr))) + break; + if (l_args->new && l_objs_count == 1) + l_objs[0].flags |= DAP_GLOBAL_DB_RECORD_NEW; + if (l_success) + dap_global_db_set_raw_sync(l_objs, l_objs_count); + dap_store_obj_free(l_objs, l_objs_count); + DAP_DELETE(l_args); + return false; } -/** - * @brief s_sync_out_gdb_synced_data_worker_callback - * @param a_worker - * @param a_arg - */ -static void s_sync_out_gdb_last_worker_callback(dap_worker_t *a_worker, void *a_arg) +static bool s_sync_out_chains_proc_callback(void *a_arg) { - struct sync_request * l_sync_request = (struct sync_request *) a_arg; - dap_stream_ch_t *l_ch = dap_stream_ch_find_by_uuid_unsafe(DAP_STREAM_WORKER(a_worker), l_sync_request->ch_uuid); - if( l_ch == NULL ){ - log_it(L_INFO,"Client disconnected before we sent the reply"); - s_sync_request_delete(l_sync_request); - return; - } - - dap_chain_ch_t *l_ch_chain = DAP_CHAIN_CH( l_ch ); - if (!l_ch_chain) { - log_it(L_CRITICAL, "Channel without chain, dump it"); - s_sync_request_delete(l_sync_request); - return; + struct legacy_sync_context *l_context = a_arg; + dap_chain_ch_state_t l_cur_state = l_context->state; + if (l_cur_state != DAP_CHAIN_CH_STATE_UPDATE_CHAINS && l_cur_state != DAP_CHAIN_CH_STATE_SYNC_CHAINS) { + // Illegal context + assert(l_cur_state == DAP_CHAIN_CH_STATE_IDLE); + goto context_delete; } - s_sync_out_gdb_first_worker_callback(NULL,a_arg); // NULL to say callback not to delete request - - if (s_debug_more ) - log_it(L_INFO,"Out: DAP_CHAIN_CH_PKT_TYPE_SYNCED_GLOBAL_DB"); - dap_chain_ch_pkt_write_unsafe(DAP_STREAM_CH(l_ch_chain), 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, NULL, 0); - s_ch_chain_go_idle(l_ch_chain); - s_sync_request_delete(l_sync_request); -} -/** - * @brief s_sync_out_gdb_callback - * @param a_thread - * @param a_arg - * @return - */ -static bool s_sync_out_gdb_proc_callback(void *a_arg) -{ - /* - struct sync_request *l_sync_request = (struct sync_request *)a_arg; - dap_chain_net_t *l_net = dap_chain_net_by_id(l_sync_request->request_hdr.net_id); - dap_stream_ch_t *l_ch = dap_stream_ch_find_by_uuid_unsafe(DAP_STREAM_WORKER(l_sync_request->worker), l_sync_request->ch_uuid); - if (l_ch == NULL) { - log_it(L_INFO, "Client disconnected before we sent the reply"); - s_sync_request_delete(l_sync_request); - return true; + dap_chain_ch_update_element_t *l_hashes = NULL; + if (l_cur_state == DAP_CHAIN_CH_STATE_UPDATE_CHAINS) { + l_hashes = DAP_NEW_Z_SIZE(dap_chain_ch_update_element_t, s_update_pack_size * sizeof(dap_chain_ch_update_element_t)); + if (!l_hashes) { + log_it(L_CRITICAL, "%s", g_error_memory_alloc); + l_context->state = DAP_CHAIN_CH_STATE_ERROR; + goto context_delete; + } } - dap_chain_ch_t *l_ch_chain = DAP_CHAIN_CH(l_ch); - if (!l_ch_chain) { - log_it(L_CRITICAL, "Channel without chain, dump it"); - s_sync_request_delete(l_sync_request); - return true; + size_t l_data_size = 0; + bool l_chain_end = false, l_go_wait = false; + for (uint_fast16_t i = 0; i < s_update_pack_size; i++) { + if (!l_context->atom_iter->cur || !l_context->atom_iter->cur_size) { + l_chain_end = true; + break; + } + if (l_cur_state == DAP_CHAIN_CH_STATE_UPDATE_CHAINS) { + l_hashes[i].hash = *l_context->atom_iter->cur_hash; + l_hashes[i].size = l_context->atom_iter->cur_size; + l_data_size += sizeof(dap_chain_ch_update_element_t); + } else { // l_cur_state == DAP_CHAIN_CH_STATE_SYNC_CHAINS + dap_chain_ch_hash_item_t *l_hash_item = NULL; + HASH_FIND(hh, l_context->remote_atoms, l_context->atom_iter->cur_hash, sizeof(dap_hash_fast_t), l_hash_item); + if (!l_hash_item) { + l_context->enqueued_data_size += l_context->atom_iter->cur_size; + if (l_context->enqueued_data_size > DAP_EVENTS_SOCKET_BUF_SIZE / 2) { + if (!atomic_compare_exchange_strong(&l_context->state, &l_cur_state, DAP_CHAIN_CH_STATE_WAITING)) + goto context_delete; + l_context->prev_state = l_cur_state; + l_go_wait = true; + } + dap_chain_ch_pkt_write_mt(l_context->worker, l_context->ch_uuid, DAP_CHAIN_CH_PKT_TYPE_CHAIN_OLD, + l_context->request_hdr.net_id, l_context->request_hdr.chain_id, l_context->request_hdr.cell_id, + l_context->atom_iter->cur, l_context->atom_iter->cur_size, DAP_CHAIN_CH_PKT_VERSION_LEGACY); + debug_if(s_debug_legacy, L_INFO, "Out CHAIN pkt: atom hash %s (size %zd)", dap_hash_fast_to_str_static(l_context->atom_iter->cur_hash), + l_context->atom_iter->cur_size); + l_context->last_activity = dap_time_now(); + l_context->stats_request_atoms_processed++; + } /* else // Over-extended debug + debug_if(s_debug_legacy, L_DEBUG, "Skip atom hash %s because its already present in remote atoms hash table", + dap_hash_fast_to_str_static(&l_context->atom_iter->cur_hash)); + */ + } + l_context->atom_iter->chain->callback_atom_iter_get(l_context->atom_iter, DAP_CHAIN_ITER_OP_NEXT, NULL); + if (l_go_wait) + break; } - int l_flags = 0; - if (dap_chain_net_get_extra_gdb_group(l_net, l_sync_request->request.node_addr)) - l_flags |= F_DB_LOG_ADD_EXTRA_GROUPS; - if (!l_sync_request->request.id_start) - l_flags |= F_DB_LOG_SYNC_FROM_ZERO; - if (l_ch_chain->request_db_log != NULL) - dap_db_log_list_delete(l_ch_chain->request_db_log); - l_ch_chain->request_db_log = dap_db_log_list_start(l_net->pub.name, l_sync_request->request.node_addr.uint64, l_flags); - - if (l_ch_chain->request_db_log) { - if (s_debug_more) - log_it(L_DEBUG, "Sync out gdb proc, requested %"DAP_UINT64_FORMAT_U" records from address "NODE_ADDR_FP_STR, - l_ch_chain->request_db_log->items_number, NODE_ADDR_FP_ARGS_S(l_sync_request->request.node_addr)); - l_sync_request->gdb.db_log = l_ch_chain->request_db_log; - dap_worker_exec_callback_on(dap_events_worker_get(l_sync_request->worker->id), s_sync_out_gdb_first_worker_callback, l_sync_request ); - } else { - dap_worker_exec_callback_on(dap_events_worker_get(l_sync_request->worker->id), s_sync_out_gdb_last_worker_callback, l_sync_request ); - } */ - return false; -} - -static void s_sync_update_gdb_start_worker_callback(dap_worker_t *a_worker, void *a_arg) -{ - struct sync_request *l_sync_request = (struct sync_request *) a_arg; - dap_stream_ch_t *l_ch = dap_stream_ch_find_by_uuid_unsafe(DAP_STREAM_WORKER(a_worker), l_sync_request->ch_uuid); - if( l_ch == NULL ){ - log_it(L_INFO,"Client disconnected before we sent the reply"); - s_sync_request_delete(l_sync_request); - return; + if (l_hashes) { + dap_chain_ch_pkt_write_mt(l_context->worker, l_context->ch_uuid, DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS, + l_context->request_hdr.net_id, l_context->request_hdr.chain_id, l_context->request_hdr.cell_id, + l_hashes, l_data_size, DAP_CHAIN_CH_PKT_VERSION_LEGACY); + debug_if(s_debug_legacy, L_INFO, "Out: DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS, %zu records", l_data_size / sizeof(dap_chain_ch_update_element_t)); + DAP_DELETE(l_hashes); + } else if (l_context->last_activity + 3 < dap_time_now()) { + l_context->last_activity = dap_time_now(); + debug_if(s_debug_more, L_INFO, "Send one chain no freeze packet"); + dap_chain_ch_pkt_write_mt(l_context->worker, l_context->ch_uuid, DAP_CHAIN_CH_PKT_TYPE_CHAINS_NO_FREEZE, + l_context->request_hdr.net_id, l_context->request_hdr.chain_id, + l_context->request_hdr.cell_id, NULL, 0, DAP_CHAIN_CH_PKT_VERSION_LEGACY); } - dap_chain_ch_pkt_write_unsafe(l_ch, DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_START, - l_sync_request->request_hdr.net_id.uint64, l_sync_request->request_hdr.chain_id.uint64, - l_sync_request->request_hdr.cell_id.uint64, NULL, 0); - if (s_debug_more) - log_it(L_INFO, "Out: DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_START for net_id 0x%016"DAP_UINT64_FORMAT_x" " - "chain_id 0x%016"DAP_UINT64_FORMAT_x" cell_id 0x%016"DAP_UINT64_FORMAT_x"", - 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_DELETE(l_sync_request); -} -static bool s_sync_update_gdb_proc_callback(void *a_arg) -{ - /* - struct sync_request *l_sync_request = (struct sync_request *)a_arg; - log_it(L_DEBUG, "Prepare request to gdb sync from %s", l_sync_request->request.id_start ? "last sync" : "zero"); - dap_chain_net_t *l_net = dap_chain_net_by_id(l_sync_request->request_hdr.net_id); - if (!l_net) { - log_it(L_ERROR, "Network ID 0x%016"DAP_UINT64_FORMAT_x" not found", l_sync_request->request_hdr.net_id.uint64); - DAP_DELETE(l_sync_request); - return true; + if (l_chain_end) { + dap_chain_ch_sync_request_old_t l_payload = { .node_addr = g_node_addr }; + uint8_t l_type = l_cur_state == DAP_CHAIN_CH_STATE_UPDATE_CHAINS ? DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_END + : DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAINS; + debug_if(s_debug_legacy, L_INFO, "Out: %s", dap_chain_ch_pkt_type_to_str(l_type)); + dap_chain_ch_pkt_write_mt(l_context->worker, l_context->ch_uuid, l_type, + l_context->request_hdr.net_id, l_context->request_hdr.chain_id, l_context->request_hdr.cell_id, + &l_payload, sizeof(l_payload), DAP_CHAIN_CH_PKT_VERSION_LEGACY); + debug_if(l_cur_state == DAP_CHAIN_CH_STATE_UPDATE_CHAINS, L_INFO, + "Synchronized chain: items synchronized %" DAP_UINT64_FORMAT_U, l_context->stats_request_atoms_processed); + if (l_cur_state == DAP_CHAIN_CH_STATE_SYNC_CHAINS) { + l_context->state = DAP_CHAIN_CH_STATE_IDLE; + goto context_delete; + } + l_context->atom_iter->chain->callback_atom_iter_get(l_context->atom_iter, DAP_CHAIN_ITER_OP_FIRST, NULL); + if (atomic_compare_exchange_strong(&l_context->state, &l_cur_state, DAP_CHAIN_CH_STATE_SYNC_CHAINS_REMOTE)) + return false; + goto context_delete; } - dap_stream_ch_t *l_ch = dap_stream_ch_find_by_uuid_unsafe(DAP_STREAM_WORKER(l_sync_request->worker), l_sync_request->ch_uuid); - if (!l_ch) { - log_it(L_INFO, "Client disconnected before we sent the reply"); - DAP_DELETE(l_sync_request); + if (!l_go_wait) return true; - } else if (!DAP_CHAIN_CH(l_ch)) { - log_it(L_CRITICAL, "Channel without chain, dump it"); - DAP_DELETE(l_sync_request); - return true; - } - - dap_chain_ch_t *l_ch_chain = DAP_CHAIN_CH(l_ch); - int l_flags = 0; - if (dap_chain_net_get_extra_gdb_group(l_net, l_sync_request->request.node_addr)) - l_flags |= F_DB_LOG_ADD_EXTRA_GROUPS; - if (!l_sync_request->request.id_start) - l_flags |= F_DB_LOG_SYNC_FROM_ZERO; - if (l_ch_chain->request_db_log != NULL) - dap_db_log_list_delete(l_ch_chain->request_db_log); - l_ch_chain->request_db_log = dap_db_log_list_start(l_net->pub.name, l_sync_request->request.node_addr.uint64, l_flags); - l_ch_chain->state = DAP_CHAIN_CH_STATE_UPDATE_GLOBAL_DB; - l_sync_request->gdb.db_log = l_ch_chain->request_db_log; - l_sync_request->request.node_addr.uint64 = dap_chain_net_get_cur_addr_int(l_net); - dap_worker_exec_callback_on(dap_events_worker_get(l_sync_request->worker->id), s_sync_update_gdb_start_worker_callback, l_sync_request); - */ return false; -} - -static bool s_gdb_in_pkt_proc_callback(void *a_arg) -{ +context_delete: + dap_worker_exec_callback_on(l_context->worker->worker, s_legacy_sync_context_delete, l_context); return false; } +// *** End of legacy support code *** // + + struct atom_processing_args { dap_stream_node_addr_t addr; bool ack_req; @@ -615,7 +638,7 @@ static bool s_sync_in_chains_callback(void *a_arg) 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); break; case ATOM_ACCEPT: - 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); + 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); else @@ -639,8 +662,8 @@ static bool s_sync_in_chains_callback(void *a_arg) } 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_chain_ch_pkt_t *l_pkt = dap_chain_ch_pkt_new(l_chain_pkt->hdr.net_id, l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + &l_ack_num, sizeof(uint64_t), DAP_CHAIN_CH_PKT_VERSION_CURRENT); 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, @@ -664,7 +687,7 @@ static void s_gossip_payload_callback(void *a_payload, size_t a_payload_size, da } struct atom_processing_args *l_args = DAP_NEW_SIZE(struct atom_processing_args, a_payload_size + sizeof(struct atom_processing_args)); if (!l_args) { - log_it(L_CRITICAL, g_error_memory_alloc); + log_it(L_CRITICAL, "%s", g_error_memory_alloc); return; } l_args->addr = a_sender_addr; @@ -673,116 +696,13 @@ static void s_gossip_payload_callback(void *a_payload, size_t a_payload_size, da dap_proc_thread_callback_add(NULL, s_sync_in_chains_callback, l_args); } -/** - * @brief s_gdb_in_pkt_error_worker_callback - * @param a_thread - * @param a_arg - */ -static void s_gdb_in_pkt_error_worker_callback(dap_worker_t *a_worker, void *a_arg) -{ - struct sync_request *l_sync_request = (struct sync_request *) a_arg; - - dap_stream_ch_t *l_ch = dap_stream_ch_find_by_uuid_unsafe(DAP_STREAM_WORKER(a_worker), l_sync_request->ch_uuid); - if (l_ch == NULL) - log_it(L_INFO,"Client disconnected before we sent the reply"); - else - 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); - DAP_DELETE(l_sync_request); -} - -/** - * @brief dap_chain_ch_create_sync_request_gdb - * @param a_ch_chain - * @param a_net - */ -struct sync_request *dap_chain_ch_create_sync_request(dap_chain_ch_pkt_t *a_chain_pkt, dap_stream_ch_t* a_ch) -{ - dap_chain_ch_t * l_ch_chain = DAP_CHAIN_CH(a_ch); - if (!l_ch_chain) { - log_it(L_CRITICAL, "Channel without chain, dump it"); - return NULL; - } - struct sync_request *l_sync_request = DAP_NEW_Z(struct sync_request); - if (!l_sync_request) { - log_it(L_CRITICAL, "%s", g_error_memory_alloc); - return NULL; - } - *l_sync_request = (struct sync_request) { - .worker = a_ch->stream_worker->worker, - .ch_uuid = a_ch->uuid, - .request = l_ch_chain->request, - .request_hdr = a_chain_pkt->hdr, - .remote_atoms = l_ch_chain->remote_atoms, - .remote_gdbs = l_ch_chain->remote_gdbs }; - return l_sync_request; -} - -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) +void dap_stream_ch_write_error_unsafe(dap_stream_ch_t *a_ch, dap_chain_net_id_t a_net_id, dap_chain_id_t a_chain_id, dap_chain_cell_id_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) { - log_it(L_CRITICAL, "Channel without chain, dump it"); - return; - } + dap_return_if_fail(l_ch_chain); + const char *l_err_str = s_error_type_to_string(a_error); + dap_chain_ch_pkt_write_unsafe(a_ch, DAP_CHAIN_CH_PKT_TYPE_ERROR, a_net_id, a_chain_id, a_cell_id, l_err_str, strlen(l_err_str) + 1, DAP_CHAIN_CH_PKT_VERSION_LEGACY); s_ch_chain_go_idle(l_ch_chain); - dap_chain_ch_pkt_write_error_unsafe(a_ch, a_net_id, a_chain_id, a_cell_id, "%s", s_error_type_to_string(a_error)); -} - -static bool s_chain_timer_callback(void *a_arg) -{ - dap_worker_t *l_worker = dap_worker_get_current(); - dap_stream_ch_t *l_ch = dap_stream_ch_find_by_uuid_unsafe(DAP_STREAM_WORKER(l_worker), *(dap_stream_ch_uuid_t*)a_arg); - if (!l_ch) { - DAP_DELETE(a_arg); - return false; - } - dap_chain_ch_t *l_ch_chain = DAP_CHAIN_CH(l_ch); - if (!l_ch_chain) { - log_it(L_CRITICAL, "Channel without chain, dump it"); - DAP_DELETE(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)) - s_ch_chain_go_idle(l_ch_chain); - DAP_DELETE(a_arg); - l_ch_chain->activity_timer = NULL; - return false; - } - if (l_ch_chain->state != DAP_CHAIN_CH_STATE_WAITING && l_ch_chain->sent_breaks) { - s_stream_ch_packet_out(l_ch, a_arg); - if (l_ch_chain->activity_timer == NULL) - return false; - } - // Sending dumb packet with nothing to inform remote thats we're just skiping atoms of GDB's, nothing freezed - if (l_ch_chain->state == DAP_CHAIN_CH_STATE_SYNC_CHAINS && l_ch_chain->sent_breaks >= 3 * DAP_SYNC_TICKS_PER_SECOND) { - debug_if(s_debug_more, L_INFO, "Send one chain TSD packet"); - dap_chain_ch_pkt_write_unsafe(l_ch, DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_TSD, - 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); - l_ch_chain->sent_breaks = 0; - l_ch_chain->timer_shots = 0; - } - return true; -} - -static void s_chain_timer_reset(dap_chain_ch_t *a_ch_chain) -{ - a_ch_chain->timer_shots = 0; - if (!a_ch_chain->activity_timer) - dap_chain_ch_timer_start(a_ch_chain); -} - -void dap_chain_ch_timer_start(dap_chain_ch_t *a_ch_chain) -{ - dap_stream_ch_uuid_t *l_uuid = DAP_DUP(&DAP_STREAM_CH(a_ch_chain)->uuid); - a_ch_chain->activity_timer = dap_timerfd_start_on_worker(DAP_STREAM_CH(a_ch_chain)->stream_worker->worker, - 1000 / DAP_SYNC_TICKS_PER_SECOND, - s_chain_timer_callback, (void *)l_uuid); - a_ch_chain->sent_breaks = 0; } /** @@ -807,41 +727,49 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) dap_chain_ch_pkt_t *l_chain_pkt = (dap_chain_ch_pkt_t *)l_ch_pkt->data; size_t l_chain_pkt_data_size = l_ch_pkt->hdr.data_size - sizeof(l_chain_pkt->hdr); - if (l_chain_pkt->hdr.version > DAP_CHAIN_CH_PKT_VERSION) { + if (!l_chain_pkt->hdr.version || l_chain_pkt->hdr.version > DAP_CHAIN_CH_PKT_VERSION_CURRENT) { debug_if(s_debug_more, L_ATT, "Unsupported protocol version %d, current version %d", - l_chain_pkt->hdr.version, DAP_CHAIN_CH_PKT_VERSION); + l_chain_pkt->hdr.version, DAP_CHAIN_CH_PKT_VERSION_CURRENT); return false; } - if (l_chain_pkt->hdr.version >= 2 && + if (l_chain_pkt->hdr.version > DAP_CHAIN_CH_PKT_VERSION_LEGACY && 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 false; } - s_chain_timer_reset(l_ch_chain); - switch (l_ch_pkt->hdr.type) { /* *** New synchronization protocol *** */ - case DAP_CHAIN_CH_PKT_TYPE_ERROR:{ - char * l_error_str = (char*)l_chain_pkt->data; - if(l_chain_pkt_data_size>1) - l_error_str[l_chain_pkt_data_size-1]='\0'; // To be sure that nobody sends us garbage - // without trailing zero - log_it(L_WARNING, "In: from remote addr %s chain id 0x%016"DAP_UINT64_FORMAT_x" got error on his side: '%s'", + case DAP_CHAIN_CH_PKT_TYPE_ERROR: { + if (!l_chain_pkt_data_size || l_chain_pkt->data[l_chain_pkt_data_size - 1] != 0) { + log_it(L_WARNING, "Incorrect format with data size %zu in packet %s", l_chain_pkt_data_size, + dap_chain_ch_pkt_type_to_str(l_ch_pkt->hdr.type)); + return false; + } + log_it(L_WARNING, "In: from remote addr %s chain id 0x%016" DAP_UINT64_FORMAT_x " got error on his side: '%s'", DAP_STREAM_CH(l_ch_chain)->stream->esocket->remote_addr_str, - l_chain_pkt->hdr.chain_id.uint64, l_chain_pkt_data_size ? l_error_str : "<empty>"); + l_chain_pkt->hdr.chain_id.uint64, (char *)l_chain_pkt->data); + s_ch_chain_go_idle(l_ch_chain); } break; case DAP_CHAIN_CH_PKT_TYPE_CHAIN: { + if (!l_chain_pkt_data_size) { + log_it(L_WARNING, "Incorrect data size %zu in packet %s", l_chain_pkt_data_size, + dap_chain_ch_pkt_type_to_str(l_ch_pkt->hdr.type)); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_CHAIN_PKT_DATA_SIZE); + return false; + } 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); - 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); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_CHAIN_PKT_DATA_SIZE); return false; } dap_cluster_member_t *l_check = dap_cluster_member_find_unsafe(l_cluster, &a_ch->stream->node); @@ -852,13 +780,11 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) } 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); + log_it(L_CRITICAL, "%s", g_error_memory_alloc); break; } l_args->addr = a_ch->stream->node; l_args->ack_req = true; - if (l_chain_pkt->hdr.version < 2) - l_chain_pkt->hdr.data_size = l_chain_pkt_data_size; memcpy(l_args->data, l_chain_pkt, l_ch_pkt->hdr.data_size); if (s_debug_more) { char *l_atom_hash_str; @@ -872,8 +798,8 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) 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_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_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, DAP_CHAIN_CH_ERROR_CHAIN_PKT_DATA_SIZE); return false; } @@ -883,35 +809,35 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) " 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, + if (l_ch_chain->sync_context || l_ch_chain->legacy_sync_context) { + log_it(L_WARNING, "Can't process CHAIN_REQ request cause already busy with synchronization"); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, DAP_CHAIN_CH_ERROR_SYNC_REQUEST_ALREADY_IN_PROCESS); - return false; + break; } 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, + if (!l_chain || l_chain->callback_load_from_gdb) { + log_it(L_WARNING, "Not found valid chain with id 0x%016" DAP_UINT64_FORMAT_x " and net id 0x%016" DAP_UINT64_FORMAT_x, l_chain_pkt->hdr.chain_id.uint64, 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_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, DAP_CHAIN_CH_ERROR_CHAIN_NOT_FOUND); - return false; + break; } 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); - 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_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, DAP_CHAIN_CH_ERROR_NET_IS_OFFLINE); - return false; + break; } 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, false); 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_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, DAP_CHAIN_CH_ERROR_OUT_OF_MEMORY); break; } @@ -925,12 +851,11 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) 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)); + l_chain_pkt->hdr.net_id, l_chain_pkt->hdr.chain_id, + l_chain_pkt->hdr.cell_id, &l_sum, sizeof(l_sum), + DAP_CHAIN_CH_PKT_VERSION_CURRENT); debug_if(s_debug_more, L_DEBUG, "Out: CHAIN_SUMMARY %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->name, l_chain->net_name, NODE_ADDR_FP_ARGS_S(a_ch->stream->node)); struct sync_context *l_context = DAP_NEW_Z(struct sync_context); l_context->addr = a_ch->stream->node; l_context->iter = l_iter; @@ -941,9 +866,15 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) l_context->last_activity = dap_time_now(); atomic_store_explicit(&l_context->state, SYNC_STATE_READY, memory_order_relaxed); atomic_store(&l_context->allowed_num, l_sum.num_cur + s_sync_ack_window_size); - dap_proc_thread_callback_add(a_ch->stream_worker->worker->proc_queue_input, s_chain_iter_callback, l_context); + dap_stream_ch_uuid_t *l_uuid = DAP_DUP(&a_ch->uuid); + if (!l_uuid) { + log_it(L_CRITICAL, "%s", g_error_memory_alloc); + DAP_DELETE(l_context); + break; + } l_ch_chain->sync_context = l_context; - l_ch_chain->sync_timer = dap_timerfd_start_on_worker(a_ch->stream_worker->worker, 1000, s_sync_timer_callback, l_ch_chain); + dap_proc_thread_callback_add(a_ch->stream_worker->worker->proc_queue_input, s_chain_iter_callback, l_context); + l_ch_chain->sync_timer = dap_timerfd_start_on_worker(a_ch->stream_worker->worker, 1000, s_sync_timer_callback, l_uuid); break; } if (l_request->num_from < l_iter->cur_num || l_last_num > l_iter->cur_num) @@ -958,8 +889,9 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) .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)); + l_chain_pkt->hdr.net_id, l_chain_pkt->hdr.chain_id, + l_chain_pkt->hdr.cell_id, &l_miss_info, sizeof(l_miss_info), + DAP_CHAIN_CH_PKT_VERSION_CURRENT); 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); @@ -974,8 +906,9 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) } } 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); + l_chain_pkt->hdr.net_id, l_chain_pkt->hdr.chain_id, + l_chain_pkt->hdr.cell_id, NULL, 0, + DAP_CHAIN_CH_PKT_VERSION_CURRENT); 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)", @@ -988,8 +921,8 @@ static bool 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)); - 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_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, DAP_CHAIN_CH_ERROR_CHAIN_PKT_DATA_SIZE); return false; } @@ -1007,8 +940,8 @@ static bool 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)); - 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_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, DAP_CHAIN_CH_ERROR_CHAIN_PKT_DATA_SIZE); return false; } @@ -1022,15 +955,16 @@ static bool 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"); - 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_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, DAP_CHAIN_CH_ERROR_INCORRECT_SYNC_SEQUENCE); break; } if (l_context->num_last == l_ack_num) { 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); + l_chain_pkt->hdr.net_id, l_chain_pkt->hdr.chain_id, + l_chain_pkt->hdr.cell_id, NULL, 0, + DAP_CHAIN_CH_PKT_VERSION_CURRENT); s_ch_chain_go_idle(l_ch_chain); break; } @@ -1056,8 +990,8 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) 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_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, DAP_CHAIN_CH_ERROR_CHAIN_PKT_DATA_SIZE); return false; } @@ -1079,8 +1013,8 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) } break; default: - 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_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, DAP_CHAIN_CH_ERROR_UNKNOWN_CHAIN_PKT_TYPE); return false; @@ -1089,371 +1023,566 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) /* *** Legacy *** */ - /// --- GDB update --- - // Request for gdbs list update - case DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_REQ:{ - if(l_ch_chain->state != DAP_CHAIN_CH_STATE_IDLE){ - log_it(L_WARNING, "Can't process UPDATE_GLOBAL_DB_REQ request because its 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; - } - 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_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; - dap_proc_thread_callback_add(a_ch->stream_worker->worker->proc_queue_input, s_sync_update_gdb_proc_callback, l_sync_request); - } break; - - // Response with metadata organized in TSD - case DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_TSD: { - if (s_debug_more) - log_it(L_DEBUG, "Global DB TSD packet detected"); - } break; - - // If requested - begin to recieve record's hashes - case DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_START:{ - if (s_debug_more) - log_it(L_INFO, "In: UPDATE_GLOBAL_DB_START 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_ch_chain->state != DAP_CHAIN_CH_STATE_IDLE){ - log_it(L_WARNING, "Can't process UPDATE_GLOBAL_DB_START request because its 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; - } - l_ch_chain->request_hdr = l_chain_pkt->hdr; - l_ch_chain->state = DAP_CHAIN_CH_STATE_UPDATE_GLOBAL_DB_REMOTE; - } break; - // Response with gdb element hashes and sizes - case DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB:{ - if(s_debug_more) - log_it(L_INFO, "In: UPDATE_GLOBAL_DB pkt data_size=%zu", l_chain_pkt_data_size); - 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 request because its already busy with syncronization"); - 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; - } - for ( dap_chain_ch_update_element_t * l_element =(dap_chain_ch_update_element_t *) l_chain_pkt->data; - (size_t) (((byte_t*)l_element) - l_chain_pkt->data ) < l_chain_pkt_data_size; - l_element++){ - dap_chain_ch_hash_item_t * l_hash_item = NULL; - unsigned l_hash_item_hashv; - HASH_VALUE(&l_element->hash, sizeof(l_element->hash), l_hash_item_hashv); - HASH_FIND_BYHASHVALUE(hh, l_ch_chain->remote_gdbs, &l_element->hash, sizeof(l_element->hash), - l_hash_item_hashv, l_hash_item); - if (!l_hash_item) { - l_hash_item = DAP_NEW_Z(dap_chain_ch_hash_item_t); - if (!l_hash_item) { - log_it(L_CRITICAL, "%s", g_error_memory_alloc); - break; - } - l_hash_item->hash = l_element->hash; - l_hash_item->size = l_element->size; - HASH_ADD_BYHASHVALUE(hh, l_ch_chain->remote_gdbs, hash, sizeof(l_hash_item->hash), - l_hash_item_hashv, l_hash_item); - /*if (s_debug_more){ - char l_hash_str[72]={ [0]='\0'}; - dap_chain_hash_fast_to_str(&l_hash_item->hash,l_hash_str,sizeof (l_hash_str)); - log_it(L_DEBUG,"In: Updated remote hash gdb list with %s ", l_hash_str); - }*/ - } - } - } 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_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"); - 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); + /// --- GDB update --- + // Request for gdbs list update + case DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_REQ: { + if (l_chain_pkt_data_size != sizeof(dap_chain_ch_sync_request_old_t)) { + log_it(L_WARNING, "Incorrect data size %zu in packet %s", l_chain_pkt_data_size, + dap_chain_ch_pkt_type_to_str(l_ch_pkt->hdr.type)); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_LEGACY_PKT_DATA_SIZE); + return false; + } + dap_cluster_t *l_net_cluster = dap_cluster_find(dap_guuid_compose(l_chain_pkt->hdr.net_id.uint64, 0)); + if (!l_net_cluster || !l_net_cluster->mnemonim) { + log_it(L_WARNING, "Net id 0x%016" DAP_UINT64_FORMAT_x " not found", l_chain_pkt->hdr.net_id.uint64); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_NET_INVALID_ID); + break; + } + 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); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_NET_IS_OFFLINE); + break; + } + if (l_ch_chain->sync_context || l_ch_chain->legacy_sync_context) { + log_it(L_WARNING, "Can't process UPDATE_GLOBAL_DB request because its already busy with syncronization"); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_SYNC_REQUEST_ALREADY_IN_PROCESS); + break; + } + dap_global_db_legacy_list_t *l_db_list = dap_global_db_legacy_list_start(l_net_cluster->mnemonim); + if (!l_db_list) { + log_it(L_ERROR, "Can't create legacy DB list"); + dap_global_db_legacy_list_delete(l_db_list); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_OUT_OF_MEMORY); + break; + } + struct legacy_sync_context *l_context = s_legacy_sync_context_create(l_chain_pkt, a_ch); + if (!l_context) { + log_it(L_ERROR, "Can't create sychronization context"); + dap_global_db_legacy_list_delete(l_db_list); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_OUT_OF_MEMORY); + break; + } + l_context->is_type_of_gdb = true; + l_context->db_list = l_db_list; + l_context->remote_addr = *(dap_stream_node_addr_t *)l_chain_pkt->data; + l_context->request_hdr = l_chain_pkt->hdr; + l_ch_chain->legacy_sync_context = l_context; + l_context->state = DAP_CHAIN_CH_STATE_UPDATE_GLOBAL_DB; + debug_if(s_debug_legacy, L_DEBUG, "Sync out gdb proc, requested %" DAP_UINT64_FORMAT_U " records from address " NODE_ADDR_FP_STR " (unverified)", + l_db_list->items_number, NODE_ADDR_FP_ARGS_S(l_context->remote_addr)); + 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); + debug_if(s_debug_legacy, L_INFO, "Out: DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_START"); + dap_chain_ch_pkt_write_unsafe(DAP_STREAM_CH(l_ch_chain), DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_START, + l_chain_pkt->hdr.net_id, l_chain_pkt->hdr.chain_id, + l_chain_pkt->hdr.cell_id, &g_node_addr, sizeof(dap_chain_node_addr_t), + DAP_CHAIN_CH_PKT_VERSION_LEGACY); + dap_proc_thread_callback_add(a_ch->stream_worker->worker->proc_queue_input, s_sync_out_gdb_proc_callback, l_context); + } break; + + // If requested - begin to recieve record's hashes + case DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_START: { + struct legacy_sync_context *l_context = l_ch_chain->legacy_sync_context; + if (!l_context || l_context->state != DAP_CHAIN_CH_STATE_UPDATE_GLOBAL_DB_REMOTE) { + log_it(L_WARNING, "Can't process UPDATE_GLOBAL_DB_START packet cause synchronization sequence violation"); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_INCORRECT_SYNC_SEQUENCE); + break; + } + debug_if(s_debug_legacy, L_INFO, "In: UPDATE_GLOBAL_DB_START pkt net 0x%016"DAP_UINT64_FORMAT_x" chain 0x%016"DAP_UINT64_FORMAT_x" cell 0x%016"DAP_UINT64_FORMAT_x, + l_context->request_hdr.net_id.uint64, l_context->request_hdr.chain_id.uint64, l_context->request_hdr.cell_id.uint64); + } break; + + // Response with gdb element hashes and sizes + case DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB: { + if (l_chain_pkt_data_size % sizeof(dap_chain_ch_update_element_t)) { + log_it(L_WARNING, "Incorrect data size %zu in packet %s", l_chain_pkt_data_size, + dap_chain_ch_pkt_type_to_str(l_ch_pkt->hdr.type)); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_LEGACY_PKT_DATA_SIZE); + return false; + } + debug_if(s_debug_legacy, L_INFO, "In: UPDATE_GLOBAL_DB pkt data_size=%zu", l_chain_pkt_data_size); + struct legacy_sync_context *l_context = l_ch_chain->legacy_sync_context; + if (!l_context || l_context->state != DAP_CHAIN_CH_STATE_UPDATE_GLOBAL_DB_REMOTE) { + log_it(L_WARNING, "Can't process UPDATE_GLOBAL_DB packet cause synchronization sequence violation"); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_INCORRECT_SYNC_SEQUENCE); + break; + } + l_context->last_activity = dap_time_now(); + + for (dap_chain_ch_update_element_t *l_element = (dap_chain_ch_update_element_t *)l_chain_pkt->data; + (size_t)((byte_t *)(l_element + 1) - l_chain_pkt->data) <= l_chain_pkt_data_size; + l_element++) { + dap_chain_ch_hash_item_t * l_hash_item = NULL; + unsigned l_hash_item_hashv; + HASH_VALUE(&l_element->hash, sizeof(l_element->hash), l_hash_item_hashv); + HASH_FIND_BYHASHVALUE(hh, l_context->remote_gdbs, &l_element->hash, sizeof(l_element->hash), + l_hash_item_hashv, l_hash_item); + if (!l_hash_item) { + l_hash_item = DAP_NEW_Z(dap_chain_ch_hash_item_t); + if (!l_hash_item) { + log_it(L_CRITICAL, "%s", g_error_memory_alloc); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_OUT_OF_MEMORY); 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_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)); - 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; - // first packet of data with source node address - case DAP_CHAIN_CH_PKT_TYPE_FIRST_GLOBAL_DB: { - if(l_chain_pkt_data_size == (size_t)sizeof(dap_chain_node_addr_t)){ - l_ch_chain->request.node_addr = *(dap_chain_node_addr_t*)l_chain_pkt->data; - l_ch_chain->stats_request_gdb_processed = 0; - log_it(L_INFO, "In: FIRST_GLOBAL_DB data_size=%zu net 0x%016"DAP_UINT64_FORMAT_x" chain 0x%016"DAP_UINT64_FORMAT_x" cell 0x%016"DAP_UINT64_FORMAT_x - " from address "NODE_ADDR_FP_STR, l_chain_pkt_data_size, l_chain_pkt->hdr.net_id.uint64 , - 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); - 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; - - case DAP_CHAIN_CH_PKT_TYPE_GLOBAL_DB: { - if(s_debug_more) - log_it(L_INFO, "In: GLOBAL_DB data_size=%zu", l_chain_pkt_data_size); - // get transaction and save it to global_db - if(l_chain_pkt_data_size > 0) { - struct sync_request *l_sync_request = dap_chain_ch_create_sync_request(l_chain_pkt, a_ch); - dap_chain_pkt_item_t *l_pkt_item = &l_sync_request->pkt; - l_pkt_item->pkt_data = DAP_DUP_SIZE(l_chain_pkt->data, l_chain_pkt_data_size); - l_pkt_item->pkt_data_size = l_chain_pkt_data_size; - 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"); - 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; - - 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); - // 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 --- - // Request for atoms list update - 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"); - 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; - } - if(s_debug_more) - log_it(L_INFO, "In: UPDATE_CHAINS_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); - 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) { - l_ch_chain->state = DAP_CHAIN_CH_STATE_UPDATE_CHAINS; - if(s_debug_more) - log_it(L_INFO, "Out: UPDATE_CHAINS_START pkt: net %s chain %s cell 0x%016"DAP_UINT64_FORMAT_X, l_chain->name, - l_chain->net_name, l_chain_pkt->hdr.cell_id.uint64); - l_ch_chain->request_atom_iter = l_chain->callback_atom_iter_create(l_chain, l_chain_pkt->hdr.cell_id, NULL, false); - l_chain->callback_atom_iter_get(l_ch_chain->request_atom_iter, DAP_CHAIN_ITER_OP_FIRST, NULL); - l_ch_chain->request_hdr = l_chain_pkt->hdr; - dap_chain_ch_pkt_write_unsafe(a_ch, DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_START, - l_chain_pkt->hdr.net_id.uint64,l_chain_pkt->hdr.chain_id.uint64, - l_chain_pkt->hdr.cell_id.uint64, NULL, 0); - } - } break; - // Response with metadata organized in TSD - case DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_TSD :{ - if (s_debug_more) - log_it(L_DEBUG, "Chain TSD packet detected"); - } break; - - // If requested - begin to send atom hashes - case DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_START:{ - if (l_ch_chain->state != DAP_CHAIN_CH_STATE_IDLE) { - log_it(L_WARNING, "Can't process UPDATE_CHAINS_START request because its 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; - } - 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 UPDATE_CHAINS_START request 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); - // Who are you? I don't know you! go away! - a_ch->stream->esocket->flags |= DAP_SOCK_SIGNAL_CLOSE; - break; - } - l_ch_chain->state = DAP_CHAIN_CH_STATE_UPDATE_CHAINS_REMOTE; - l_ch_chain->request_hdr = l_chain_pkt->hdr; - debug_if(s_debug_more, L_INFO, "In: UPDATE_CHAINS_START pkt"); - } break; - - // Response with atom hashes and sizes - case DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS: { - unsigned int l_count_added=0; - unsigned int l_count_total=0; - - 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 UPDATE_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); - // Who are you? I don't know you! go away! - a_ch->stream->esocket->flags |= DAP_SOCK_SIGNAL_CLOSE; - break; - } - for ( dap_chain_ch_update_element_t * l_element =(dap_chain_ch_update_element_t *) l_chain_pkt->data; - (size_t) (((byte_t*)l_element) - l_chain_pkt->data ) < l_chain_pkt_data_size; - l_element++){ - dap_chain_ch_hash_item_t * l_hash_item = NULL; - unsigned l_hash_item_hashv; - HASH_VALUE(&l_element->hash, sizeof(dap_hash_fast_t), l_hash_item_hashv); - HASH_FIND_BYHASHVALUE(hh, l_ch_chain->remote_atoms, &l_element->hash, sizeof(dap_hash_fast_t), - l_hash_item_hashv, l_hash_item); - if( ! l_hash_item ){ - l_hash_item = DAP_NEW_Z(dap_chain_ch_hash_item_t); - if (!l_hash_item) { - log_it(L_CRITICAL, "%s", g_error_memory_alloc); - break; - } - l_hash_item->hash = l_element->hash; - l_hash_item->size = l_element->size; - HASH_ADD_BYHASHVALUE(hh, l_ch_chain->remote_atoms, hash, sizeof(dap_hash_fast_t), - l_hash_item_hashv, l_hash_item); - l_count_added++; - /* - if (s_debug_more){ - char l_hash_str[72]={ [0]='\0'}; - dap_chain_hash_fast_to_str(&l_hash_item->hash,l_hash_str,sizeof (l_hash_str)); - log_it(L_DEBUG,"In: Updated remote atom hash list with %s ", l_hash_str); - }*/ - } - l_count_total++; + l_hash_item->hash = l_element->hash; + l_hash_item->size = l_element->size; + HASH_ADD_BYHASHVALUE(hh, l_context->remote_gdbs, hash, sizeof(l_hash_item->hash), + l_hash_item_hashv, l_hash_item); + //debug_if(s_debug_legacy, L_DEBUG, "In: Updated remote hash GDB list with %s", dap_chain_hash_fast_to_str_static(&l_hash_item->hash)); } - if (s_debug_more) - log_it(L_INFO,"In: Added %u from %u remote atom hash in list",l_count_added,l_count_total); - } break; - - case DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_END: { - 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"); - 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; - } - 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 UPDATE_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; + + // End of response with GlobalDB hashes + case DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_END: { + if (l_chain_pkt_data_size != sizeof(dap_chain_ch_sync_request_old_t)) { + log_it(L_WARNING, "Incorrect data size %zu in packet %s", l_chain_pkt_data_size, + dap_chain_ch_pkt_type_to_str(l_ch_pkt->hdr.type)); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_LEGACY_PKT_DATA_SIZE); + return false; + } + struct legacy_sync_context *l_context = l_ch_chain->legacy_sync_context; + if (!l_context || l_context->state != DAP_CHAIN_CH_STATE_UPDATE_GLOBAL_DB_REMOTE) { + log_it(L_WARNING, "Can't process UPDATE_GLOBAL_DB_END packet cause synchronization sequence violation"); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_INCORRECT_SYNC_SEQUENCE); + break; + } + debug_if(s_debug_legacy, L_INFO, "In: UPDATE_GLOBAL_DB_END pkt with total count %d hashes", HASH_COUNT(l_context->remote_gdbs)); + l_context->state = DAP_CHAIN_CH_STATE_SYNC_GLOBAL_DB; + debug_if(s_debug_legacy, L_INFO, "Out: DAP_CHAIN_CH_PKT_TYPE_FIRST_GLOBAL_DB"); + dap_chain_ch_pkt_write_unsafe(DAP_STREAM_CH(l_ch_chain), DAP_CHAIN_CH_PKT_TYPE_FIRST_GLOBAL_DB, + l_context->request_hdr.net_id, l_context->request_hdr.chain_id, + l_context->request_hdr.cell_id, &g_node_addr, sizeof(dap_chain_node_addr_t), + DAP_CHAIN_CH_PKT_VERSION_LEGACY); + dap_proc_thread_callback_add(a_ch->stream_worker->worker->proc_queue_input, s_sync_out_gdb_proc_callback, l_context); + } break; + + // first packet of data with source node address + case DAP_CHAIN_CH_PKT_TYPE_FIRST_GLOBAL_DB: { + if (l_chain_pkt_data_size != sizeof(dap_chain_node_addr_t)) { + log_it(L_WARNING, "Incorrect data size %zu in packet %s", l_chain_pkt_data_size, + dap_chain_ch_pkt_type_to_str(l_ch_pkt->hdr.type)); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_LEGACY_PKT_DATA_SIZE); + return false; + } + struct legacy_sync_context *l_context = l_ch_chain->legacy_sync_context; + if (!l_context || l_context->state != DAP_CHAIN_CH_STATE_SYNC_GLOBAL_DB_REMOTE) { + log_it(L_WARNING, "Can't process FIRST_GLOBAL_DB packet cause synchronization sequence violation"); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_INCORRECT_SYNC_SEQUENCE); + break; + } + debug_if(s_debug_legacy, L_INFO, "In: FIRST_GLOBAL_DB data_size=%zu net 0x%016"DAP_UINT64_FORMAT_x" chain 0x%016"DAP_UINT64_FORMAT_x" cell 0x%016"DAP_UINT64_FORMAT_x + " from address "NODE_ADDR_FP_STR "(unverified)", l_chain_pkt_data_size, l_context->request_hdr.net_id.uint64, + l_context->request_hdr.chain_id.uint64, l_context->request_hdr.cell_id.uint64, NODE_ADDR_FP_ARGS_S(l_context->remote_addr)); + } break; + + // Dummy packet for freeze detection + case DAP_CHAIN_CH_PKT_TYPE_GLOBAL_DB_NO_FREEZE: { + struct legacy_sync_context *l_context = l_ch_chain->legacy_sync_context; + if (!l_context || l_context->state != DAP_CHAIN_CH_STATE_SYNC_GLOBAL_DB_REMOTE) { + log_it(L_WARNING, "Can't process GLOBAL_DB_NO_FREEZE packet cause synchronization sequence violation"); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_INCORRECT_SYNC_SEQUENCE); + break; + } + debug_if(s_debug_legacy, L_DEBUG, "Global DB no freeze packet detected"); + l_context->last_activity = dap_time_now(); + } break; + + case DAP_CHAIN_CH_PKT_TYPE_GLOBAL_DB: { + dap_global_db_pkt_old_t *l_pkt = (dap_global_db_pkt_old_t *)l_chain_pkt->data; + if (l_chain_pkt_data_size < sizeof(dap_global_db_pkt_old_t) || + l_chain_pkt_data_size != sizeof(*l_pkt) + l_pkt->data_size) { + log_it(L_WARNING, "Incorrect data size %zu in packet %s", l_chain_pkt_data_size, + dap_chain_ch_pkt_type_to_str(l_ch_pkt->hdr.type)); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_LEGACY_PKT_DATA_SIZE); + return false; + } + struct legacy_sync_context *l_context = l_ch_chain->legacy_sync_context; + if (l_context && l_context->state != DAP_CHAIN_CH_STATE_SYNC_GLOBAL_DB_REMOTE) { + log_it(L_WARNING, "Can't process GLOBAL_DB packet cause synchronization sequence violation"); + break; + } + if (l_context) + l_context->last_activity = dap_time_now(); + debug_if(s_debug_legacy, L_INFO, "In: GLOBAL_DB_OLD data_size=%zu", l_chain_pkt_data_size); + // get records and save it to global_db + struct record_processing_args *l_args; + DAP_NEW_Z_RET_VAL(l_args, struct record_processing_args, true, NULL); + l_args->pkt = DAP_DUP_SIZE(l_pkt, l_chain_pkt_data_size); + if (!l_args->pkt) { + log_it(L_CRITICAL, "%s", g_error_memory_alloc); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_OUT_OF_MEMORY); + break; + } + l_args->worker = a_ch->stream_worker; + l_args->uuid = a_ch->uuid; + l_args->hdr = l_chain_pkt->hdr; + l_args->new = !l_context && l_pkt->obj_count == 1; + dap_proc_thread_callback_add(a_ch->stream_worker->worker->proc_queue_input, s_gdb_in_pkt_proc_callback, l_args); + } break; + + case DAP_CHAIN_CH_PKT_TYPE_SYNCED_GLOBAL_DB: { + struct legacy_sync_context *l_context = l_ch_chain->legacy_sync_context; + if (!l_context || l_context->state != DAP_CHAIN_CH_STATE_SYNC_GLOBAL_DB_REMOTE) { + log_it(L_WARNING, "Can't process SYNCED_GLOBAL_DB packet cause synchronization sequence violation"); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_INCORRECT_SYNC_SEQUENCE); + break; + } + debug_if(s_debug_legacy, 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_context->request_hdr.net_id.uint64, l_context->request_hdr.chain_id.uint64, l_context->request_hdr.cell_id.uint64); + // we haven't node client waitng, so reply to other side + l_context->state = DAP_CHAIN_CH_STATE_UPDATE_GLOBAL_DB_REMOTE; + dap_chain_ch_sync_request_old_t l_request = { .node_addr = g_node_addr }; + debug_if(s_debug_legacy, L_INFO, "Out: UPDATE_GLOBAL_DB_REQ pkt"); + dap_chain_ch_pkt_write_unsafe(a_ch, DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_REQ, l_context->request_hdr.net_id, + l_context->request_hdr.chain_id, l_context->request_hdr.cell_id, &l_request, sizeof(l_request), + DAP_CHAIN_CH_PKT_VERSION_LEGACY); + } break; + + /// --- Chains update --- + // Request for atoms list update + case DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_REQ: { + if (l_chain_pkt_data_size) { // Expected packet with no data + log_it(L_WARNING, "Incorrect data size %zu in packet %s", l_chain_pkt_data_size, + dap_chain_ch_pkt_type_to_str(l_ch_pkt->hdr.type)); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_LEGACY_PKT_DATA_SIZE); + 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); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_NET_IS_OFFLINE); + break; + } + if (l_ch_chain->sync_context || l_ch_chain->legacy_sync_context) { + log_it(L_WARNING, "Can't process UPDATE_CHAINS request because its already busy with syncronization"); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_SYNC_REQUEST_ALREADY_IN_PROCESS); + break; + } + 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, "Requested chain not found"); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_CHAIN_NOT_FOUND); + break; + } + dap_chain_atom_iter_t *l_atom_iter = l_chain->callback_atom_iter_create(l_chain, l_chain_pkt->hdr.cell_id, NULL); + if (!l_atom_iter) { + log_it(L_ERROR, "Can't create legacy atom iterator"); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_OUT_OF_MEMORY); + break; + } + struct legacy_sync_context *l_context = s_legacy_sync_context_create(l_chain_pkt, a_ch); + if (!l_context) { + log_it(L_ERROR, "Can't create sychronization context"); + l_chain->callback_atom_iter_delete(l_atom_iter); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_OUT_OF_MEMORY); + break; + } + l_chain->callback_atom_iter_get(l_atom_iter, DAP_CHAIN_ITER_OP_FIRST, NULL); + l_context->atom_iter = l_atom_iter; + l_context->remote_addr = *(dap_stream_node_addr_t *)l_chain_pkt->data; + l_context->request_hdr = l_chain_pkt->hdr; + l_ch_chain->legacy_sync_context = l_context; + l_context->state = DAP_CHAIN_CH_STATE_UPDATE_CHAINS; + debug_if(s_debug_legacy, L_DEBUG, "Sync out chains proc, requested chain %s for net %s from address " NODE_ADDR_FP_STR " (unverified)", + l_chain->name, l_chain->net_name, NODE_ADDR_FP_ARGS_S(l_context->remote_addr)); + debug_if(s_debug_legacy, L_INFO, "In: UPDATE_CHAINS_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); + debug_if(s_debug_legacy, L_INFO, "Out: UPDATE_CHAINS_START pkt: net %s chain %s cell 0x%016"DAP_UINT64_FORMAT_X, l_chain->name, + l_chain->net_name, l_chain_pkt->hdr.cell_id.uint64); + dap_chain_ch_pkt_write_unsafe(a_ch, DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_START, + l_chain_pkt->hdr.net_id, l_chain_pkt->hdr.chain_id, + l_chain_pkt->hdr.cell_id, NULL, 0, + DAP_CHAIN_CH_PKT_VERSION_LEGACY); + dap_proc_thread_callback_add(a_ch->stream_worker->worker->proc_queue_input, s_sync_out_chains_proc_callback, l_context); + } break; + + // If requested - begin to send atom hashes + case DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_START: { + struct legacy_sync_context *l_context = l_ch_chain->legacy_sync_context; + if (!l_context || l_context->state != DAP_CHAIN_CH_STATE_UPDATE_CHAINS_REMOTE) { + log_it(L_WARNING, "Can't process UPDATE_CHAINS_START packet cause synchronization sequence violation"); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_INCORRECT_SYNC_SEQUENCE); + break; + } + debug_if(s_debug_legacy, L_INFO, "In: UPDATE_CHAINS_START pkt net 0x%016"DAP_UINT64_FORMAT_x" chain 0x%016"DAP_UINT64_FORMAT_x" cell 0x%016"DAP_UINT64_FORMAT_x, + l_context->request_hdr.net_id.uint64, l_context->request_hdr.chain_id.uint64, l_context->request_hdr.cell_id.uint64); + } break; + + // Response with atom hashes and sizes + case DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS: { + if (l_chain_pkt_data_size > sizeof(dap_chain_ch_update_element_t) * s_update_pack_size) { + log_it(L_WARNING, "Incorrect data size %zu in packet %s", l_chain_pkt_data_size, + dap_chain_ch_pkt_type_to_str(l_ch_pkt->hdr.type)); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_LEGACY_PKT_DATA_SIZE); + return false; + } + debug_if(s_debug_legacy, L_INFO, "In: UPDATE_CHAINS pkt data_size=%zu", l_chain_pkt_data_size); + struct legacy_sync_context *l_context = l_ch_chain->legacy_sync_context; + if (!l_context || l_context->state != DAP_CHAIN_CH_STATE_UPDATE_CHAINS_REMOTE) { + log_it(L_WARNING, "Can't process UPDATE_CHAINS packet cause synchronization sequence violation"); + dap_stream_ch_write_error_unsafe(a_ch, l_context->request_hdr.net_id, + l_context->request_hdr.chain_id, l_context->request_hdr.cell_id, + DAP_CHAIN_CH_ERROR_INCORRECT_SYNC_SEQUENCE); + break; + } + l_context->last_activity = dap_time_now(); + + unsigned int l_count_added = 0; + unsigned int l_count_total = 0; + for (dap_chain_ch_update_element_t *l_element = (dap_chain_ch_update_element_t *)l_chain_pkt->data; + (size_t)((byte_t *)(l_element + 1) - l_chain_pkt->data) <= l_chain_pkt_data_size; + l_element++) { + dap_chain_ch_hash_item_t *l_hash_item = NULL; + unsigned l_hash_item_hashv; + HASH_VALUE(&l_element->hash, sizeof(l_element->hash), l_hash_item_hashv); + HASH_FIND_BYHASHVALUE(hh, l_context->remote_atoms, &l_element->hash, sizeof(l_element->hash), + l_hash_item_hashv, l_hash_item); + if (!l_hash_item) { + l_hash_item = DAP_NEW_Z(dap_chain_ch_hash_item_t); + if (!l_hash_item) { + log_it(L_CRITICAL, "%s", g_error_memory_alloc); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_OUT_OF_MEMORY); break; } - debug_if(s_debug_more, L_INFO, "In: UPDATE_CHAINS_END pkt with total count %d hashes", - HASH_COUNT(l_ch_chain->remote_atoms)); - struct sync_request *l_sync_request = dap_chain_ch_create_sync_request(l_chain_pkt, a_ch); - l_ch_chain->stats_request_atoms_processed = 0; - l_ch_chain->request_hdr = l_chain_pkt->hdr; - dap_proc_thread_callback_add(a_ch->stream_worker->worker->proc_queue_input, s_sync_out_chains_proc_callback, l_sync_request); - } 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)); - 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; - // first packet of data with source node address - case DAP_CHAIN_CH_PKT_TYPE_FIRST_CHAIN: { - if(l_chain_pkt_data_size == (size_t)sizeof(dap_chain_node_addr_t)){ - l_ch_chain->request_hdr = l_chain_pkt->hdr; - l_ch_chain->request.node_addr = *(dap_chain_node_addr_t*)l_chain_pkt->data; - log_it(L_INFO, "From "NODE_ADDR_FP_STR": FIRST_CHAIN data_size=%zu 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_ch_chain->request.node_addr), - l_chain_pkt_data_size, l_ch_chain->request_hdr.net_id.uint64 , - 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); - 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); + l_hash_item->hash = l_element->hash; + l_hash_item->size = l_element->size; + HASH_ADD_BYHASHVALUE(hh, l_context->remote_atoms, hash, sizeof(l_hash_item->hash), + l_hash_item_hashv, l_hash_item); + l_count_added++; + //debug_if(s_debug_legacy, L_DEBUG, "In: Updated remote hash GDB list with %s", dap_chain_hash_fast_to_str_static(&l_hash_item->hash)); } - } break; + l_count_total++; + } + debug_if(s_debug_legacy, L_INFO, "In: Added %u from %u remote atom hash in list", l_count_added, l_count_total); + } break; - case DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAINS: { - if (dap_log_level_get() <= L_INFO) { - dap_chain_hash_fast_t l_hash_from = l_ch_chain->request.hash_from; - char l_hash_from_str[DAP_CHAIN_HASH_FAST_STR_SIZE] = { '\0' }, l_hash_to_str[DAP_CHAIN_HASH_FAST_STR_SIZE] = { '\0' }; - dap_chain_hash_fast_to_str(&l_hash_from, l_hash_from_str, DAP_CHAIN_HASH_FAST_STR_SIZE); - dap_chain_hash_fast_to_str(&c_dap_chain_addr_blank.data.hash_fast, l_hash_to_str, DAP_CHAIN_HASH_FAST_STR_SIZE); - log_it(L_INFO, "In: SYNCED_CHAINS: between %s and %s",l_hash_from_str[0] ? l_hash_from_str : "(null)", - l_hash_to_str[0] ? l_hash_to_str: "(null)"); + // End of response with chain hashes + case DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_END: { + if (l_chain_pkt_data_size != sizeof(dap_chain_ch_sync_request_old_t)) { + log_it(L_WARNING, "Incorrect data size %zu in packet %s", l_chain_pkt_data_size, + dap_chain_ch_pkt_type_to_str(l_ch_pkt->hdr.type)); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_LEGACY_PKT_DATA_SIZE); + return false; + } + struct legacy_sync_context *l_context = l_ch_chain->legacy_sync_context; + if (!l_context || l_context->state != DAP_CHAIN_CH_STATE_UPDATE_CHAINS_REMOTE) { + log_it(L_WARNING, "Can't process UPDATE_CHAINS_END packet cause synchronization sequence violation"); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_INCORRECT_SYNC_SEQUENCE); + break; + } + debug_if(s_debug_legacy, L_INFO, "In: UPDATE_CHAINS_END pkt with total count %d hashes", HASH_COUNT(l_context->remote_atoms)); + l_context->state = DAP_CHAIN_CH_STATE_SYNC_CHAINS; + debug_if(s_debug_legacy, L_INFO, "Out: DAP_CHAIN_CH_PKT_TYPE_FIRST_CHAIN"); + dap_chain_ch_pkt_write_unsafe(DAP_STREAM_CH(l_ch_chain), DAP_CHAIN_CH_PKT_TYPE_FIRST_CHAIN, + l_context->request_hdr.net_id, l_context->request_hdr.chain_id, + l_context->request_hdr.cell_id, &g_node_addr, sizeof(dap_chain_node_addr_t), + DAP_CHAIN_CH_PKT_VERSION_LEGACY); + dap_proc_thread_callback_add(a_ch->stream_worker->worker->proc_queue_input, s_sync_out_chains_proc_callback, l_context); + } break; + + // first packet of data with source node address (legacy, unverified) + case DAP_CHAIN_CH_PKT_TYPE_FIRST_CHAIN: { + if (l_chain_pkt_data_size != sizeof(dap_chain_node_addr_t)) { + log_it(L_WARNING, "Incorrect data size %zu in packet %s", l_chain_pkt_data_size, + dap_chain_ch_pkt_type_to_str(l_ch_pkt->hdr.type)); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_LEGACY_PKT_DATA_SIZE); + return false; + } + struct legacy_sync_context *l_context = l_ch_chain->legacy_sync_context; + if (!l_context || l_context->state != DAP_CHAIN_CH_STATE_SYNC_CHAINS_REMOTE) { + log_it(L_WARNING, "Can't process FIRST_CHAIN packet cause synchronization sequence violation"); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_INCORRECT_SYNC_SEQUENCE); + break; + } + debug_if(s_debug_legacy, L_INFO, "In: FIRST_CHAIN data_size=%zu net 0x%016"DAP_UINT64_FORMAT_x" chain 0x%016"DAP_UINT64_FORMAT_x" cell 0x%016"DAP_UINT64_FORMAT_x + " from address "NODE_ADDR_FP_STR "(unverified)", l_chain_pkt_data_size, l_context->request_hdr.net_id.uint64, + l_context->request_hdr.chain_id.uint64, l_context->request_hdr.cell_id.uint64, NODE_ADDR_FP_ARGS_S(l_context->remote_addr)); + } break; + + // Dummy packet for freeze detection + case DAP_CHAIN_CH_PKT_TYPE_CHAINS_NO_FREEZE: { + struct legacy_sync_context *l_context = l_ch_chain->legacy_sync_context; + if (!l_context || l_context->state != DAP_CHAIN_CH_STATE_SYNC_CHAINS_REMOTE) { + log_it(L_WARNING, "Can't process CHAINS_NO_FREEZE packet cause synchronization sequence violation"); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_INCORRECT_SYNC_SEQUENCE); + break; + } + debug_if(s_debug_legacy, L_DEBUG, "Chains no freeze packet detected"); + l_context->last_activity = dap_time_now(); + } break; + + case DAP_CHAIN_CH_PKT_TYPE_CHAIN_OLD: { + if (!l_chain_pkt_data_size) { + log_it(L_WARNING, "Incorrect data size %zu in packet %s", l_chain_pkt_data_size, + dap_chain_ch_pkt_type_to_str(l_ch_pkt->hdr.type)); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_LEGACY_PKT_DATA_SIZE); + return false; + } + struct legacy_sync_context *l_context = l_ch_chain->legacy_sync_context; + if (!l_context || l_context->state != DAP_CHAIN_CH_STATE_SYNC_CHAINS_REMOTE) { + log_it(L_WARNING, "Can't process FIRST_CHAIN packet cause synchronization sequence violation"); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_INCORRECT_SYNC_SEQUENCE); + break; + } + debug_if(s_debug_legacy, L_INFO, "In: CHAIN_OLD data_size=%zu", l_chain_pkt_data_size); + struct atom_processing_args *l_args = DAP_NEW_Z_SIZE(struct atom_processing_args, l_ch_pkt->hdr.data_size + sizeof(struct atom_processing_args)); + if (!l_args) { + log_it(L_CRITICAL, "%s", g_error_memory_alloc); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_OUT_OF_MEMORY); + break; + } + l_chain_pkt->hdr.data_size = l_chain_pkt_data_size; + memcpy(l_args->data, l_chain_pkt, l_ch_pkt->hdr.data_size); + if (s_debug_more) { + char *l_atom_hash_str; + dap_get_data_hash_str_static(l_chain_pkt->data, l_chain_pkt_data_size, l_atom_hash_str); + log_it(L_INFO, "In: CHAIN_OLD pkt: atom hash %s (size %zd)", l_atom_hash_str, l_chain_pkt_data_size); + } + dap_proc_thread_callback_add(a_ch->stream_worker->worker->proc_queue_input, s_sync_in_chains_callback, l_args); + } break; + + case DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAINS: { + struct legacy_sync_context *l_context = l_ch_chain->legacy_sync_context; + if (!l_context || l_context->state != DAP_CHAIN_CH_STATE_SYNC_CHAINS_REMOTE) { + log_it(L_WARNING, "Can't process SYNCED_CHAINS packet cause synchronization sequence violation"); + dap_stream_ch_write_error_unsafe(a_ch, l_chain_pkt->hdr.net_id, + l_chain_pkt->hdr.chain_id, l_chain_pkt->hdr.cell_id, + DAP_CHAIN_CH_ERROR_INCORRECT_SYNC_SEQUENCE); + break; + } + debug_if(s_debug_legacy, L_INFO, "In: SYNCED_CHAINS: net 0x%016"DAP_UINT64_FORMAT_x" chain 0x%016"DAP_UINT64_FORMAT_x" cell 0x%016"DAP_UINT64_FORMAT_x, + l_context->request_hdr.net_id.uint64, l_context->request_hdr.chain_id.uint64, l_context->request_hdr.cell_id.uint64); + // we haven't node client waitng, so reply to other side + l_context->state = DAP_CHAIN_CH_STATE_UPDATE_CHAINS_REMOTE; + debug_if(s_debug_legacy, L_INFO, "Out: UPDATE_CHAINS_REQ pkt"); + dap_chain_ch_sync_request_old_t l_request = { .node_addr = g_node_addr }; + dap_chain_ch_pkt_write_unsafe(a_ch, DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_REQ, l_context->request_hdr.net_id, + l_context->request_hdr.chain_id, l_context->request_hdr.cell_id, &l_request, sizeof(l_request), + DAP_CHAIN_CH_PKT_VERSION_LEGACY); + } break; - } - s_ch_chain_get_idle(l_ch_chain); - if (l_ch_chain->activity_timer) { - dap_timerfd_delete_unsafe(l_ch_chain->activity_timer); - l_ch_chain->activity_timer = NULL; - } - // 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; } + return true; } 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); - l_ch_chain->sync_timer = NULL; // Preserve timer removing from s_ch_chain_go_idle() - 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); + dap_worker_t *l_worker = dap_worker_get_current(); + dap_stream_ch_t *l_ch = dap_stream_ch_find_by_uuid_unsafe(DAP_STREAM_WORKER(l_worker), *(dap_stream_ch_uuid_t *)a_arg); + if (!l_ch) { + DAP_DELETE(a_arg); + return false; + } + dap_chain_ch_t *l_ch_chain = DAP_CHAIN_CH(l_ch); + if (!l_ch_chain) { + log_it(L_ERROR, "Channel without chain, dump it"); + DAP_DELETE(a_arg); + return false; + } + + bool l_timer_break = false; + const char *l_err_str = s_error_type_to_string(DAP_CHAIN_CH_ERROR_SYNC_TIMEOUT); + if (l_ch_chain->sync_context) { + 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_chain_ch_pkt_write_unsafe(l_ch, DAP_CHAIN_CH_PKT_TYPE_ERROR, l_context->net_id, + l_context->chain_id, l_context->cell_id, l_err_str, strlen(l_err_str) + 1, + DAP_CHAIN_CH_PKT_VERSION_CURRENT); + l_timer_break = true; + } + } else if (l_ch_chain->legacy_sync_context) { + struct legacy_sync_context *l_context = l_ch_chain->legacy_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 " (unverified) 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->remote_addr), l_context->request_hdr.net_id.uint64, + l_context->request_hdr.chain_id.uint64, l_context->request_hdr.cell_id.uint64); + dap_chain_ch_pkt_write_unsafe(l_ch, DAP_CHAIN_CH_PKT_TYPE_ERROR, l_context->request_hdr.net_id, + l_context->request_hdr.chain_id, l_context->request_hdr.cell_id, l_err_str, strlen(l_err_str) + 1, + DAP_CHAIN_CH_PKT_VERSION_LEGACY); + l_timer_break = true; + } + } else + l_timer_break = true; + if (l_timer_break) { + l_ch_chain->sync_timer = NULL; // Preserve timer removing from s_ch_chain_go_idle() + s_ch_chain_go_idle(l_ch_chain); + DAP_DELETE(a_arg); return false; } return true; @@ -1476,8 +1605,8 @@ static bool s_chain_iter_callback(void *a_arg) while (l_atom && l_atom_size) { if (l_iter->cur_num > atomic_load_explicit(&l_context->allowed_num, memory_order_acquire)) break; - dap_chain_ch_pkt_t *l_pkt = dap_chain_ch_pkt_new(l_context->net_id.uint64, l_context->chain_id.uint64, l_context->cell_id.uint64, - l_atom, l_atom_size); + dap_chain_ch_pkt_t *l_pkt = dap_chain_ch_pkt_new(l_context->net_id, l_context->chain_id, l_context->cell_id, + l_atom, l_atom_size, DAP_CHAIN_CH_PKT_VERSION_CURRENT); // For master format binary complience l_pkt->hdr.num_lo = l_iter->cur_num & 0xFFFF; l_pkt->hdr.num_hi = (l_iter->cur_num >> 16) & 0xFF; @@ -1524,6 +1653,8 @@ static bool s_chain_iter_delete_callback(void *a_arg) */ static void s_ch_chain_go_idle(dap_chain_ch_t *a_ch_chain) { + debug_if(s_debug_more, L_INFO, "Going to chain's stream channel STATE_IDLE"); + // New protocol if (a_ch_chain->sync_context) { atomic_store(&((struct sync_context *)a_ch_chain->sync_context)->state, SYNC_STATE_OVER); @@ -1537,428 +1668,42 @@ static void s_ch_chain_go_idle(dap_chain_ch_t *a_ch_chain) } //} // Legacy - if (a_ch_chain->state == DAP_CHAIN_CH_STATE_IDLE) { - return; - } - a_ch_chain->state = DAP_CHAIN_CH_STATE_IDLE; - - if(s_debug_more) - log_it(L_INFO, "Go in DAP_CHAIN_CH_STATE_IDLE"); - - // Cleanup after request - memset(&a_ch_chain->request, 0, sizeof(a_ch_chain->request)); - memset(&a_ch_chain->request_hdr, 0, sizeof(a_ch_chain->request_hdr)); - if (a_ch_chain->request_atom_iter && a_ch_chain->request_atom_iter->chain && - a_ch_chain->request_atom_iter->chain->callback_atom_iter_delete) { - a_ch_chain->request_atom_iter->chain->callback_atom_iter_delete(a_ch_chain->request_atom_iter); - a_ch_chain->request_atom_iter = NULL; + if (a_ch_chain->legacy_sync_context) { + dap_chain_ch_state_t l_current_state = atomic_exchange( + &((struct legacy_sync_context *)a_ch_chain->legacy_sync_context)->state, DAP_CHAIN_CH_STATE_IDLE); + if (l_current_state != DAP_CHAIN_CH_STATE_UPDATE_CHAINS && + l_current_state != DAP_CHAIN_CH_STATE_SYNC_CHAINS && + l_current_state != DAP_CHAIN_CH_STATE_UPDATE_GLOBAL_DB && + l_current_state != DAP_CHAIN_CH_STATE_SYNC_GLOBAL_DB && + l_current_state != DAP_CHAIN_CH_STATE_IDLE && + l_current_state != DAP_CHAIN_CH_STATE_ERROR) + // Context will not be removed from proc thread + s_legacy_sync_context_delete(a_ch_chain->legacy_sync_context); + a_ch_chain->legacy_sync_context = NULL; } - - dap_chain_ch_hash_item_t *l_hash_item = NULL, *l_tmp = NULL; - - HASH_ITER(hh, a_ch_chain->remote_atoms, l_hash_item, l_tmp) { - // Clang bug at this, l_hash_item should change at every loop cycle - HASH_DEL(a_ch_chain->remote_atoms, l_hash_item); - DAP_DELETE(l_hash_item); - } - a_ch_chain->remote_atoms = NULL; - a_ch_chain->sent_breaks = 0; } -struct chain_io_complete { - dap_stream_ch_uuid_t ch_uuid; - dap_chain_ch_state_t state; - uint8_t type; - uint64_t net_id; - uint64_t chain_id; - uint64_t cell_id; - size_t data_size; - byte_t data[]; -}; - static void s_stream_ch_io_complete(dap_events_socket_t *a_es, void *a_arg) { - dap_stream_t *l_stream = NULL; - if (!a_es->server) { - dap_client_t *l_client = DAP_ESOCKET_CLIENT(a_es); - assert(l_client); - dap_client_pvt_t *l_client_pvt = DAP_CLIENT_PVT(l_client); - l_stream = l_client_pvt->stream; - } else { - dap_http_client_t *l_http_client = DAP_HTTP_CLIENT(a_es); - if (l_http_client) - l_stream = DAP_STREAM(l_http_client); - } - if (!l_stream) + dap_return_if_fail(a_arg); + dap_stream_t *l_stream = dap_stream_get_from_es(a_es); + assert(l_stream); + dap_stream_ch_t *l_ch = dap_stream_ch_by_id_unsafe(l_stream, DAP_CHAIN_CH_ID); + assert(l_ch); + struct legacy_sync_context *l_context = DAP_CHAIN_CH(l_ch)->legacy_sync_context; + if (!l_context) return; - dap_stream_ch_t *l_ch = NULL; - for (size_t i = 0; i < l_stream->channel_count; i++) - if (l_stream->channel[i]->proc->id == DAP_CHAIN_CH_ID) - l_ch = l_stream->channel[i]; - if (!l_ch || !DAP_CHAIN_CH(l_ch)) + dap_chain_ch_state_t l_expected = DAP_CHAIN_CH_STATE_WAITING; + if (!atomic_compare_exchange_strong(&l_context->state, &l_expected, l_context->prev_state)) return; - if (a_arg) { - struct chain_io_complete *l_arg = (struct chain_io_complete *)a_arg; - if (DAP_CHAIN_CH(l_ch)->state == DAP_CHAIN_CH_STATE_WAITING) - DAP_CHAIN_CH(l_ch)->state = l_arg->state; - dap_chain_ch_pkt_write_unsafe(l_ch, l_arg->type, l_arg->net_id, l_arg->chain_id, - l_arg->cell_id, l_arg->data, l_arg->data_size); - a_es->callbacks.arg = NULL; - DAP_DELETE(a_arg); - return; - } - s_stream_ch_packet_out(l_ch, NULL); -} - -static void s_stream_ch_chain_pkt_write(dap_stream_ch_t *a_ch, uint8_t a_type, uint64_t a_net_id, - uint64_t a_chain_id, uint64_t a_cell_id, - const void * a_data, size_t a_data_size) -{ - size_t l_free_buf_size = dap_events_socket_get_free_buf_size(a_ch->stream->esocket) - - sizeof(dap_chain_ch_pkt_t) - sizeof(dap_stream_ch_pkt_t) - - sizeof(dap_stream_pkt_t) - DAP_STREAM_PKT_ENCRYPTION_OVERHEAD; - if (l_free_buf_size < a_data_size) { - struct chain_io_complete *l_arg = DAP_NEW_Z_SIZE(struct chain_io_complete, sizeof(struct chain_io_complete) + a_data_size); - l_arg->ch_uuid = a_ch->uuid; - l_arg->state = DAP_CHAIN_CH(a_ch)->state; - DAP_CHAIN_CH(a_ch)->state = DAP_CHAIN_CH_STATE_WAITING; - l_arg->type = a_type; - l_arg->net_id = a_net_id; - l_arg->chain_id = a_chain_id; - l_arg->cell_id = a_cell_id; - l_arg->data_size = a_data_size; - memcpy(l_arg->data, a_data, a_data_size); - a_ch->stream->esocket->callbacks.arg = l_arg; - } - else - dap_chain_ch_pkt_write_unsafe(a_ch, a_type, a_net_id, a_chain_id, a_cell_id, a_data, a_data_size); -} - -/** - * @brief s_stream_ch_packet_out - * @param ch - * @param arg - */ -static bool s_stream_ch_packet_out(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) { - log_it(L_CRITICAL, "Channel without chain, dump it"); - s_ch_chain_go_idle(l_ch_chain); - return false; - } - bool l_go_idle = false, l_was_sent_smth = false; - switch (l_ch_chain->state) { - // Update list of global DB records to remote - case DAP_CHAIN_CH_STATE_UPDATE_GLOBAL_DB: { -#if 0 - size_t i, q = - // s_update_pack_size; - 0; - //dap_db_log_list_obj_t **l_objs = dap_db_log_list_get_multiple(l_ch_chain->request_db_log, DAP_STREAM_PKT_SIZE_MAX, &q); - dap_chain_ch_update_element_t *l_data = DAP_NEW_Z_SIZE(dap_chain_ch_update_element_t, q * sizeof(dap_chain_ch_update_element_t)); - for (i = 0; i < q; ++i) { - l_data[i].hash = l_objs[i]->hash; - l_data[i].size = l_objs[i]->pkt->data_size; - DAP_DELETE(l_objs[i]->pkt); - DAP_DELETE(l_objs[i]); - } - if (i) { - l_was_sent_smth = true; - s_stream_ch_chain_pkt_write(a_ch, DAP_CHAIN_CH_PKT_TYPE_UPDATE_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_data, i * sizeof(dap_chain_ch_update_element_t)); - l_ch_chain->stats_request_gdb_processed += i; - DAP_DELETE(l_data); - DAP_DELETE(l_objs); - debug_if(s_debug_more, L_INFO, "Out: DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB, %zu records", i); - } else if (!l_objs) { - l_was_sent_smth = true; - l_ch_chain->request.node_addr.uint64 = dap_chain_net_get_cur_addr_int(dap_chain_net_by_id( - l_ch_chain->request_hdr.net_id)); - s_stream_ch_chain_pkt_write(a_ch, DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_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_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; - } - dap_chain_ch_update_element_t l_data[s_update_pack_size]; - uint_fast16_t i; - dap_db_log_list_obj_t *l_obj = NULL; - for (i = 0; i < s_update_pack_size; i++) { - l_obj = dap_db_log_list_get(l_ch_chain->request_db_log); - if (!l_obj || DAP_POINTER_TO_SIZE(l_obj) == 1) - break; - l_data[i].hash = l_obj->hash; - l_data[i].size = l_obj->pkt->data_size; - DAP_DELETE(l_obj->pkt); - DAP_DELETE(l_obj); - } - if (i) { - l_was_sent_smth = true; - s_stream_ch_chain_pkt_write(a_ch, DAP_CHAIN_CH_PKT_TYPE_UPDATE_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_data, i * sizeof(dap_chain_ch_update_element_t)); - l_ch_chain->stats_request_gdb_processed += i; - if (s_debug_more) - log_it(L_INFO, "Out: DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB"); - } else if (!l_obj) { - l_was_sent_smth = true; - l_ch_chain->request.node_addr.uint64 = dap_chain_net_get_cur_addr_int(dap_chain_net_by_id( - l_ch_chain->request_hdr.net_id)); - s_stream_ch_chain_pkt_write(a_ch, DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_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_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; - } -#endif - } break; - - // Synchronize GDB - case DAP_CHAIN_CH_STATE_SYNC_GLOBAL_DB: { -#if 0 - dap_global_db_pkt_t *l_pkt = NULL; - size_t l_pkt_size = 0, i, q = 0; - dap_db_log_list_obj_t **l_objs = dap_db_log_list_get_multiple(l_ch_chain->request_db_log, DAP_STREAM_PKT_SIZE_MAX, &q); - for (i = 0; i < q; ++i) { - dap_chain_ch_hash_item_t *l_hash_item = NULL; - unsigned l_hash_item_hashv = 0; - HASH_VALUE(&l_objs[i]->hash, sizeof(dap_chain_hash_fast_t), l_hash_item_hashv); - HASH_FIND_BYHASHVALUE(hh, l_ch_chain->remote_gdbs, &l_objs[i]->hash, - sizeof(dap_hash_fast_t), l_hash_item_hashv, l_hash_item); - if (!l_hash_item) { - l_hash_item = DAP_NEW_Z(dap_chain_ch_hash_item_t); - *l_hash_item = (dap_chain_ch_hash_item_t) { - .hash = l_objs[i]->hash, .size = l_objs[i]->pkt->data_size - }; - HASH_ADD_BYHASHVALUE(hh, l_ch_chain->remote_gdbs, hash, sizeof(dap_chain_hash_fast_t), - l_hash_item_hashv, l_hash_item); - l_pkt = dap_global_db_pkt_pack(l_pkt, l_objs[i]->pkt); - l_ch_chain->stats_request_gdb_processed++; - l_pkt_size = sizeof(dap_global_db_pkt_t) + l_pkt->data_size; - } - - DAP_DELETE(l_objs[i]->pkt); - DAP_DELETE(l_objs[i]); - } - - if (l_pkt_size) { - l_was_sent_smth = true; - // If request was from defined node_addr we update its state - s_stream_ch_chain_pkt_write(a_ch, DAP_CHAIN_CH_PKT_TYPE_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_pkt, l_pkt_size); - debug_if(s_debug_more, L_INFO, "Send one global_db packet, size %zu, rest %zu/%zu items", l_pkt_size, - l_ch_chain->request_db_log->items_rest, - l_ch_chain->request_db_log->items_number); - DAP_DELETE(l_pkt); - DAP_DELETE(l_objs); - } else if (!l_objs) { - l_was_sent_smth = true; - // last message - 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)); - 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_GLOBAL_DB, - NULL, 0, l_ch_chain->callback_notify_arg); - log_it(L_INFO,"Syncronized database: items syncronyzed %"DAP_UINT64_FORMAT_U" of %zu", - l_ch_chain->stats_request_gdb_processed, l_ch_chain->request_db_log->items_number); - } - // Get global DB record - dap_global_db_pkt_t *l_pkt = NULL; - dap_db_log_list_obj_t *l_obj = NULL; - size_t l_pkt_size = 0; - for (uint_fast16_t l_skip_count = 0; l_skip_count < s_skip_in_reactor_count; ) { - l_obj = dap_db_log_list_get(l_ch_chain->request_db_log); - if (!l_obj || DAP_POINTER_TO_SIZE(l_obj) == 1) { - l_skip_count = s_skip_in_reactor_count; - break; - } - dap_chain_ch_hash_item_t *l_hash_item = NULL; - unsigned l_hash_item_hashv = 0; - HASH_VALUE(&l_obj->hash, sizeof(dap_chain_hash_fast_t), l_hash_item_hashv); - HASH_FIND_BYHASHVALUE(hh, l_ch_chain->remote_gdbs, &l_obj->hash, sizeof(dap_hash_fast_t), - l_hash_item_hashv, l_hash_item); - if (l_hash_item) { // If found - skip it - /*if (s_debug_more) { - char l_request_atom_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; - dap_chain_hash_fast_to_str(&l_obj->hash, l_request_atom_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE); - log_it(L_DEBUG, "Out CHAIN: skip GDB hash %s because its already present in remote GDB hash table", - l_request_atom_hash_str); - }*/ - l_skip_count++; - } else { - l_hash_item = DAP_NEW_Z(dap_chain_ch_hash_item_t); - if (!l_hash_item) { - log_it(L_CRITICAL, "%s", g_error_memory_alloc); - return; - } - l_hash_item->hash = l_obj->hash; - l_hash_item->size = l_obj->pkt->data_size; - HASH_ADD_BYHASHVALUE(hh, l_ch_chain->remote_gdbs, hash, sizeof(dap_chain_hash_fast_t), - l_hash_item_hashv, l_hash_item); - l_pkt = dap_global_db_pkt_pack(l_pkt, l_obj->pkt); - l_ch_chain->stats_request_gdb_processed++; - l_pkt_size = sizeof(dap_global_db_pkt_t) + l_pkt->data_size; - } - DAP_DELETE(l_obj->pkt); - DAP_DELETE(l_obj); - if (l_pkt_size >= DAP_CHAIN_PKT_EXPECT_SIZE) - break; - } - if (l_pkt_size) { - l_was_sent_smth = true; - // If request was from defined node_addr we update its state - if (s_debug_more) - log_it(L_INFO, "Send one global_db packet len=%zu (rest=%zu/%zu items)", l_pkt_size, - dap_db_log_list_get_count_rest(l_ch_chain->request_db_log), - dap_db_log_list_get_count(l_ch_chain->request_db_log)); - s_stream_ch_chain_pkt_write(a_ch, DAP_CHAIN_CH_PKT_TYPE_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_pkt, l_pkt_size); - DAP_DELETE(l_pkt); - } else if (!l_obj) { - l_was_sent_smth = true; - 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_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)); - 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_GLOBAL_DB, - NULL, 0, l_ch_chain->callback_notify_arg); - } -#endif - } break; - - // Update list of atoms to remote - case DAP_CHAIN_CH_STATE_UPDATE_CHAINS:{ - dap_chain_ch_update_element_t *l_data = DAP_NEW_Z_SIZE(dap_chain_ch_update_element_t, - sizeof(dap_chain_ch_update_element_t) * s_update_pack_size); - size_t l_data_size=0; - for(uint_fast16_t n=0; n<s_update_pack_size && (l_ch_chain->request_atom_iter && l_ch_chain->request_atom_iter->cur);n++){ - l_data[n].hash = *l_ch_chain->request_atom_iter->cur_hash; - // Shift offset counter - l_data_size += sizeof(dap_chain_ch_update_element_t); - // Then get next atom - l_ch_chain->request_atom_iter->chain->callback_atom_iter_get(l_ch_chain->request_atom_iter, DAP_CHAIN_ITER_OP_NEXT, NULL); - } - if (l_data_size){ - l_was_sent_smth = true; - if(s_debug_more) - log_it(L_DEBUG,"Out: UPDATE_CHAINS with %zu hashes sent", l_data_size / sizeof(dap_chain_ch_update_element_t)); - s_stream_ch_chain_pkt_write(a_ch, DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS, - 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_data,l_data_size); - } - if(!l_data_size || !l_ch_chain->request_atom_iter){ // We over with all the hashes here - l_was_sent_smth = true; - if(s_debug_more) - log_it(L_INFO,"Out: UPDATE_CHAINS_END sent "); - 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_old_t)); - l_go_idle = true; - dap_stream_ch_set_ready_to_write_unsafe(a_ch, false); - } - DAP_DELETE(l_data); - }break; - - // Synchronize chains - case DAP_CHAIN_CH_STATE_SYNC_CHAINS: { - // Process one chain from l_ch_chain->request_atom_iter - // Pack loop to skip quicker - for(uint_fast16_t k=0; k<s_skip_in_reactor_count && - l_ch_chain->request_atom_iter && - l_ch_chain->request_atom_iter->cur; k++){ - // Check if present and skip if present - dap_chain_ch_hash_item_t *l_hash_item = NULL; - unsigned l_hash_item_hashv = 0; - HASH_VALUE(l_ch_chain->request_atom_iter->cur_hash, sizeof(dap_chain_hash_fast_t), l_hash_item_hashv); - HASH_FIND_BYHASHVALUE(hh, l_ch_chain->remote_atoms, l_ch_chain->request_atom_iter->cur_hash, - sizeof(dap_chain_hash_fast_t), l_hash_item_hashv, l_hash_item); - if( l_hash_item ){ // If found - skip it - /*if(s_debug_more){ - char l_request_atom_hash_str[81]={[0]='\0'}; - dap_chain_hash_fast_to_str(l_ch_chain->request_atom_iter->cur_hash,l_request_atom_hash_str,sizeof (l_request_atom_hash_str)); - log_it(L_DEBUG, "Out CHAIN: skip atom hash %s because its already present in remote atom hash table", - l_request_atom_hash_str); - }*/ - }else{ - l_hash_item = DAP_NEW_Z(dap_chain_ch_hash_item_t); - if (!l_hash_item) { - log_it(L_CRITICAL, "%s", g_error_memory_alloc); - return false; - } - l_hash_item->hash = *l_ch_chain->request_atom_iter->cur_hash; - if(s_debug_more){ - char l_atom_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; - dap_chain_hash_fast_to_str(&l_hash_item->hash, l_atom_hash_str, sizeof(l_atom_hash_str)); - log_it(L_INFO, "Out CHAIN pkt: atom hash %s (size %zd) ", l_atom_hash_str, l_ch_chain->request_atom_iter->cur_size); - } - s_stream_ch_chain_pkt_write(a_ch, DAP_CHAIN_CH_PKT_TYPE_CHAIN, 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_atom_iter->cur, l_ch_chain->request_atom_iter->cur_size); - l_was_sent_smth = true; - l_ch_chain->stats_request_atoms_processed++; - - l_hash_item->size = l_ch_chain->request_atom_iter->cur_size; - // Because we sent this atom to remote - we record it to not to send it twice - HASH_ADD_BYHASHVALUE(hh, l_ch_chain->remote_atoms, hash, sizeof(dap_hash_fast_t), l_hash_item_hashv, - l_hash_item); - } - // Then get next atom and populate new last - l_ch_chain->request_atom_iter->chain->callback_atom_iter_get(l_ch_chain->request_atom_iter, DAP_CHAIN_ITER_OP_NEXT, NULL); - if (l_was_sent_smth) - break; - } - if(!l_ch_chain->request_atom_iter || !l_ch_chain->request_atom_iter->cur) { // All chains synced - 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, - 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)); - log_it( L_INFO,"Synced: %"DAP_UINT64_FORMAT_U" atoms processed", l_ch_chain->stats_request_atoms_processed); - l_go_idle = true; - } - } break; - - default: - return false; - } - if (l_was_sent_smth) { - s_chain_timer_reset(l_ch_chain); - l_ch_chain->sent_breaks = 0; + if (l_context->prev_state == DAP_CHAIN_CH_STATE_UPDATE_CHAINS || + l_context->prev_state == DAP_CHAIN_CH_STATE_SYNC_CHAINS) { + l_context->enqueued_data_size = 0; + dap_proc_thread_callback_add(l_ch->stream_worker->worker->proc_queue_input, s_sync_out_chains_proc_callback, l_context); + } else if (l_context->prev_state == DAP_CHAIN_CH_STATE_UPDATE_GLOBAL_DB || + l_context->prev_state == DAP_CHAIN_CH_STATE_SYNC_GLOBAL_DB) { + l_context->enqueued_data_size = 0; + dap_proc_thread_callback_add(l_ch->stream_worker->worker->proc_queue_input, s_sync_out_gdb_proc_callback, l_context); } else - l_ch_chain->sent_breaks++; - if (l_go_idle) { - s_ch_chain_go_idle(l_ch_chain); - if (l_ch_chain->activity_timer) { - if (!a_arg) - dap_timerfd_delete_unsafe(l_ch_chain->activity_timer); - l_ch_chain->activity_timer = NULL; - } - return false; - } - return true; + log_it(L_ERROR, "Unexpected legacy sync context state %d", l_context->state); } diff --git a/modules/chain/dap_chain_ch_pkt.c b/modules/chain/dap_chain_ch_pkt.c index 9149522a97a2856db22b24a4e0c3369518c4b6ed..e774210cf23eebb1bc0ac8e4e42c7603396dbb55 100644 --- a/modules/chain/dap_chain_ch_pkt.c +++ b/modules/chain/dap_chain_ch_pkt.c @@ -23,6 +23,23 @@ #define LOG_TAG "dap_chain_ch_pkt" +static void s_chain_pkt_fill(dap_chain_ch_pkt_t *a_pkt, dap_chain_net_id_t a_net_id, + dap_chain_id_t a_chain_id, dap_chain_cell_id_t a_cell_id, + const void *a_data, size_t a_data_size, uint8_t a_version) +{ + *a_pkt = (dap_chain_ch_pkt_t) { + .hdr = { .version = a_version, + .data_size = a_version == DAP_CHAIN_CH_PKT_VERSION_LEGACY + ? 0 + : a_data_size, + .net_id = a_net_id, + .cell_id = a_cell_id, + .chain_id = a_chain_id } + }; + if (a_data_size && a_data) + memcpy(a_pkt->data, a_data, a_data_size); +} + /** * @brief dap_stream_ch_net_pkt_write * @param sid @@ -30,33 +47,36 @@ * @param data_size * @return */ -size_t dap_chain_ch_pkt_write_unsafe(dap_stream_ch_t *a_ch, uint8_t a_type, uint64_t a_net_id, - uint64_t a_chain_id, uint64_t a_cell_id, - const void * a_data, size_t a_data_size) +size_t dap_chain_ch_pkt_write_unsafe(dap_stream_ch_t *a_ch, uint8_t a_type, + dap_chain_net_id_t a_net_id, dap_chain_id_t a_chain_id, dap_chain_cell_id_t a_cell_id, + const void *a_data, size_t a_data_size, uint8_t a_version) { - dap_chain_ch_pkt_t *l_chain_pkt = dap_chain_ch_pkt_new(a_net_id, a_chain_id, a_cell_id, a_data, a_data_size); - size_t l_ret = dap_stream_ch_pkt_write_unsafe(a_ch, a_type, l_chain_pkt, dap_chain_ch_pkt_get_size(l_chain_pkt)); - DAP_DELETE(l_chain_pkt); + size_t l_chain_pkt_size = sizeof(dap_chain_ch_pkt_hdr_t) + a_data_size; + dap_chain_ch_pkt_t *l_chain_pkt = l_chain_pkt_size > 0x3FFF + ? DAP_NEW_Z_SIZE(dap_chain_ch_pkt_t, l_chain_pkt_size) + : DAP_NEW_STACK_SIZE(dap_chain_ch_pkt_t, l_chain_pkt_size); + + if (!l_chain_pkt) { + log_it(L_CRITICAL, "%s", g_error_memory_alloc); + return 0; + } + s_chain_pkt_fill(l_chain_pkt, a_net_id, a_chain_id, a_cell_id, a_data, a_data_size, a_version); + + size_t l_ret = dap_stream_ch_pkt_write_unsafe(a_ch, a_type, l_chain_pkt, l_chain_pkt_size); + if (l_chain_pkt_size > 0x3FFF) + DAP_DELETE(l_chain_pkt); return l_ret; } -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, - const void *a_data, size_t a_data_size) +dap_chain_ch_pkt_t *dap_chain_ch_pkt_new(dap_chain_net_id_t a_net_id, dap_chain_id_t a_chain_id, dap_chain_cell_id_t a_cell_id, + const void *a_data, size_t a_data_size, uint8_t a_version) { size_t l_chain_pkt_size = sizeof(dap_chain_ch_pkt_hdr_t) + a_data_size; dap_chain_ch_pkt_t *l_chain_pkt = DAP_NEW_Z_SIZE(dap_chain_ch_pkt_t, l_chain_pkt_size); - if (l_chain_pkt) { - *l_chain_pkt = (dap_chain_ch_pkt_t) { - .hdr = { .version = DAP_CHAIN_CH_PKT_VERSION, - .data_size = a_data_size, - .net_id.uint64 = a_net_id, - .cell_id.uint64 = a_cell_id, - .chain_id.uint64 = a_chain_id } - }; - if (a_data_size && a_data) - memcpy(l_chain_pkt->data, a_data, a_data_size); - } else - log_it(L_CRITICAL, g_error_memory_alloc); + if (l_chain_pkt) + s_chain_pkt_fill(l_chain_pkt, a_net_id, a_chain_id, a_cell_id, a_data, a_data_size, a_version); + else + log_it(L_CRITICAL, "%s", g_error_memory_alloc); return l_chain_pkt; } /** @@ -71,20 +91,20 @@ dap_chain_ch_pkt_t *dap_chain_ch_pkt_new(uint64_t a_net_id, uint64_t a_chain_id, * @param a_data_size * @return */ -size_t dap_chain_ch_pkt_write_mt(dap_stream_worker_t *a_worker, dap_stream_ch_uuid_t a_ch_uuid, uint8_t a_type,uint64_t a_net_id, - uint64_t a_chain_id, uint64_t a_cell_id, - const void * a_data, size_t a_data_size) +size_t dap_chain_ch_pkt_write_mt(dap_stream_worker_t *a_worker, dap_stream_ch_uuid_t a_ch_uuid, uint8_t a_type, + dap_chain_net_id_t a_net_id, dap_chain_id_t a_chain_id, dap_chain_cell_id_t a_cell_id, + const void *a_data, size_t a_data_size, uint8_t a_version) { size_t l_chain_pkt_size = sizeof(dap_chain_ch_pkt_hdr_t) + a_data_size; dap_chain_ch_pkt_t *l_chain_pkt = l_chain_pkt_size > 0x3FFF ? DAP_NEW_Z_SIZE(dap_chain_ch_pkt_t, l_chain_pkt_size) : DAP_NEW_STACK_SIZE(dap_chain_ch_pkt_t, l_chain_pkt_size); - *l_chain_pkt = (dap_chain_ch_pkt_t){ - .hdr = { .version = DAP_CHAIN_CH_PKT_VERSION, .net_id.uint64 = a_net_id, .cell_id.uint64 = a_cell_id, .chain_id.uint64 = a_chain_id } - }; - if (a_data_size && a_data) - memcpy(l_chain_pkt->data, a_data, a_data_size); + if (!l_chain_pkt) { + log_it(L_CRITICAL, "%s", g_error_memory_alloc); + return 0; + } + s_chain_pkt_fill(l_chain_pkt, a_net_id, a_chain_id, a_cell_id, a_data, a_data_size, a_version); size_t l_ret = dap_stream_ch_pkt_write_mt(a_worker, a_ch_uuid, a_type, l_chain_pkt, l_chain_pkt_size); if (l_chain_pkt_size > 0x3FFF) @@ -92,35 +112,6 @@ size_t dap_chain_ch_pkt_write_mt(dap_stream_worker_t *a_worker, dap_stream_ch_uu return l_ret; } -size_t dap_chain_ch_pkt_write_multi_mt(dap_stream_ch_cachet_t *a_links, size_t a_count, uint8_t a_type,uint64_t a_net_id, - uint64_t a_chain_id, uint64_t a_cell_id, - const void * a_data, size_t a_data_size) -{ - size_t l_chain_pkt_size = sizeof(dap_chain_ch_pkt_hdr_t) + a_data_size; - dap_chain_ch_pkt_t *l_chain_pkt = l_chain_pkt_size > 0x3FFF - ? DAP_NEW_Z_SIZE(dap_chain_ch_pkt_t, l_chain_pkt_size) - : DAP_NEW_STACK_SIZE(dap_chain_ch_pkt_t, l_chain_pkt_size); - *l_chain_pkt = (dap_chain_ch_pkt_t){ - .hdr = { .version = DAP_CHAIN_CH_PKT_VERSION, .net_id.uint64 = a_net_id, .cell_id.uint64 = a_cell_id, .chain_id.uint64 = a_chain_id } - }; - - if (a_data_size && a_data) - memcpy(l_chain_pkt->data, a_data, a_data_size); - size_t l_ret = 0, l_tmp = 0, i; - for (i = 0; i < a_count; ++i) { - l_tmp = dap_stream_ch_pkt_write_mt(a_links[i].stream_worker, a_links[i].uuid, a_type, l_chain_pkt, l_chain_pkt_size); - if (!l_tmp) { - l_ret = 0; - break; - } else { - l_ret += l_tmp; - } - } - if (l_chain_pkt_size > 0x3FFF) - DAP_DELETE(l_chain_pkt); - return l_ret; -} - /** * @brief Write ch chain packet into the queue input * @param a_es_input, @@ -134,21 +125,13 @@ size_t dap_chain_ch_pkt_write_multi_mt(dap_stream_ch_cachet_t *a_links, size_t a * @param a_data_size * @return */ -size_t dap_chain_ch_pkt_write_inter(dap_events_socket_t * a_es_input, dap_stream_ch_uuid_t a_ch_uuid, - uint8_t a_type,uint64_t a_net_id, - uint64_t a_chain_id, uint64_t a_cell_id, - const void * a_data, size_t a_data_size) +size_t dap_chain_ch_pkt_write_inter(dap_events_socket_t *a_es_input, dap_stream_ch_uuid_t a_ch_uuid, uint8_t a_type, + dap_chain_net_id_t a_net_id, dap_chain_id_t a_chain_id, dap_chain_cell_id_t a_cell_id, + const void * a_data, size_t a_data_size, uint8_t a_version) { - size_t l_chain_pkt_size = sizeof(dap_chain_ch_pkt_hdr_t) + a_data_size; - dap_chain_ch_pkt_t *l_chain_pkt = DAP_NEW_Z_SIZE(dap_chain_ch_pkt_t, l_chain_pkt_size ); - *l_chain_pkt = (dap_chain_ch_pkt_t){ - .hdr = { .version = DAP_CHAIN_CH_PKT_VERSION, .net_id.uint64 = a_net_id, .cell_id.uint64 = a_cell_id, .chain_id.uint64 = a_chain_id } - }; - - if (a_data_size && a_data) - memcpy(l_chain_pkt->data, a_data, a_data_size); + dap_chain_ch_pkt_t *l_chain_pkt = dap_chain_ch_pkt_new(a_net_id, a_chain_id, a_cell_id, a_data, a_data_size, a_version); - size_t l_ret = dap_stream_ch_pkt_write_inter(a_es_input, a_ch_uuid, a_type, l_chain_pkt, l_chain_pkt_size); + size_t l_ret = dap_stream_ch_pkt_write_inter(a_es_input, a_ch_uuid, a_type, l_chain_pkt, dap_chain_ch_pkt_get_size(l_chain_pkt)); DAP_DELETE(l_chain_pkt); return l_ret; } diff --git a/modules/chain/include/dap_chain.h b/modules/chain/include/dap_chain.h index b7f72d944c67ecca8cc83e6095ee94915a51a29c..7f8a9f636bde85def19933419fdcd7e468293d63 100644 --- a/modules/chain/include/dap_chain.h +++ b/modules/chain/include/dap_chain.h @@ -29,9 +29,6 @@ #include "dap_config.h" #include "dap_chain_common.h" #include "dap_chain_datum.h" -#include "dap_chain_datum_tx.h" -#include "dap_cert.h" -#include "dap_global_db_cluster.h" typedef struct dap_chain dap_chain_t; @@ -90,7 +87,7 @@ typedef enum dap_chain_iter_op { typedef dap_chain_t* (*dap_chain_callback_new_t)(void); typedef void (*dap_chain_callback_t)(dap_chain_t *); -typedef int (*dap_chain_callback_new_cfg_t)(dap_chain_t*, dap_config_t *); +typedef int (*dap_chain_callback_new_cfg_t)(dap_chain_t *, dap_config_t *); typedef void (*dap_chain_callback_ptr_t)(dap_chain_t *, void * ); typedef dap_chain_atom_verify_res_t (*dap_chain_callback_atom_t)(dap_chain_t *, dap_chain_atom_ptr_t, size_t, dap_hash_fast_t*); @@ -124,23 +121,18 @@ typedef void (*dap_chain_callback_notify_t)(void *a_arg, dap_chain_t *a_chain, d typedef uint64_t (*dap_chain_callback_get_count)(dap_chain_t *a_chain); typedef dap_list_t *(*dap_chain_callback_get_list)(dap_chain_t *a_chain, size_t a_count, size_t a_page, bool a_reverse); typedef dap_list_t *(*dap_chain_callback_get_poa_certs)(dap_chain_t *a_chain, size_t *a_auth_certs_count, uint16_t *count_verify); -typedef void (*dap_chain_callback_set_min_validators_count)(dap_chain_t *a_chain, uint16_t a_new_value); -typedef uint256_t (*dap_chain_callback_get_minimum_fee)(dap_chain_t *a_chain); -typedef uint256_t (*dap_chain_callback_get_collectiong_level)(dap_chain_t *a_chain); -typedef dap_enc_key_t* (*dap_chain_callback_get_signing_certificate)(dap_chain_t *a_chain); typedef void (*dap_chain_callback_load_from_gdb)(dap_chain_t *a_chain); typedef uint256_t (*dap_chain_callback_calc_reward)(dap_chain_t *a_chain, dap_hash_fast_t *a_block_hash, dap_pkey_t *a_block_sign_pkey); typedef enum dap_chain_type { - CHAIN_TYPE_FIRST, - CHAIN_TYPE_TOKEN, - CHAIN_TYPE_EMISSION, - CHAIN_TYPE_TX, - CHAIN_TYPE_CA, - CHAIN_TYPE_SIGNER, - CHAIN_TYPE_LAST, - CHAIN_TYPE_DECREE, - CHAIN_TYPE_ANCHOR + CHAIN_TYPE_INVALID = -1, + CHAIN_TYPE_TOKEN = 1, + CHAIN_TYPE_EMISSION = 2, + CHAIN_TYPE_TX = 3, + CHAIN_TYPE_CA = 4, + CHAIN_TYPE_SIGNER = 5, + CHAIN_TYPE_DECREE = 7, + CHAIN_TYPE_ANCHOR = 8 } dap_chain_type_t; typedef struct dap_chain { @@ -204,10 +196,6 @@ typedef struct dap_chain { // Consensus specific callbacks dap_chain_callback_get_poa_certs callback_get_poa_certs; - dap_chain_callback_set_min_validators_count callback_set_min_validators_count; - dap_chain_callback_get_minimum_fee callback_get_minimum_fee; - dap_chain_callback_get_collectiong_level callback_get_collectiong_level; - dap_chain_callback_get_signing_certificate callback_get_signing_certificate; dap_chain_callback_calc_reward callback_calc_reward; dap_chain_callback_load_from_gdb callback_load_from_gdb; @@ -275,5 +263,7 @@ DAP_STATIC_INLINE bool dap_chain_get_atom_last_hash(dap_chain_t *a_chain, dap_ch } 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); +const char *dap_chain_type_to_str(dap_chain_type_t a_chain_type); +const char *dap_chain_get_path(dap_chain_t *a_chain); +const char *dap_chain_get_cs_type(dap_chain_t *l_chain); diff --git a/modules/chain/include/dap_chain_ch.h b/modules/chain/include/dap_chain_ch.h index 9d51f6319edd336118b3ef1e375a0cf6171dbc1c..384e5ec3d9154c784f783acb6caa0b6b06122237 100644 --- a/modules/chain/include/dap_chain_ch.h +++ b/modules/chain/include/dap_chain_ch.h @@ -33,17 +33,19 @@ #include "uthash.h" #include "dap_global_db_cluster.h" -#define DAP_SYNC_TICKS_PER_SECOND 10 +#define DAP_CHAIN_CH_ID 'C' typedef enum dap_chain_ch_state { DAP_CHAIN_CH_STATE_IDLE = 0, DAP_CHAIN_CH_STATE_WAITING, - DAP_CHAIN_CH_STATE_UPDATE_GLOBAL_DB_REMOTE, // Downloadn GDB hashtable from remote - DAP_CHAIN_CH_STATE_UPDATE_GLOBAL_DB, // Update GDB hashtable to remote - DAP_CHAIN_CH_STATE_SYNC_GLOBAL_DB, - DAP_CHAIN_CH_STATE_UPDATE_CHAINS_REMOTE, // Update chains hashtable from remote - DAP_CHAIN_CH_STATE_UPDATE_CHAINS, // Update chains hashtable to remote - DAP_CHAIN_CH_STATE_SYNC_CHAINS, + DAP_CHAIN_CH_STATE_UPDATE_GLOBAL_DB_REMOTE, // Download GDB hashtable from remote + DAP_CHAIN_CH_STATE_UPDATE_GLOBAL_DB, // Upload GDB hashtable to remote + DAP_CHAIN_CH_STATE_SYNC_GLOBAL_DB_REMOTE, // Download GDB records from remote + DAP_CHAIN_CH_STATE_SYNC_GLOBAL_DB, // Upload GDB records to remote + DAP_CHAIN_CH_STATE_UPDATE_CHAINS_REMOTE, // Download chains hashtable from remote + DAP_CHAIN_CH_STATE_UPDATE_CHAINS, // Upload chains hashtable to remote + DAP_CHAIN_CH_STATE_SYNC_CHAINS_REMOTE, // Download chains atoms from remote + DAP_CHAIN_CH_STATE_SYNC_CHAINS, // Upload chains atoms from remote DAP_CHAIN_CH_STATE_ERROR } dap_chain_ch_state_t; @@ -56,62 +58,15 @@ typedef enum dap_chain_ch_error_type { 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_OUT_OF_MEMORY, - DAP_CHAIN_CH_ERROR_INTERNAL + DAP_CHAIN_CH_ERROR_INTERNAL, +// Legacy + DAP_CHAIN_CH_ERROR_GLOBAL_DB_INTERNAL_NOT_SAVED, + DAP_CHAIN_CH_ERROR_LEGACY_PKT_DATA_SIZE } dap_chain_ch_error_type_t; -typedef struct dap_chain_ch dap_chain_ch_t; -typedef void (*dap_chain_ch_callback_packet_t)(dap_chain_ch_t*, uint8_t a_pkt_type, - dap_chain_ch_pkt_t *a_pkt, size_t a_pkt_data_size, - void * a_arg); -typedef struct dap_chain_pkt_item { - uint64_t pkt_data_size; - byte_t *pkt_data; -} dap_chain_pkt_item_t; - -typedef struct dap_chain_ch_hash_item { - dap_hash_fast_t hash; - uint32_t size; - UT_hash_handle hh; -} dap_chain_ch_hash_item_t; - - -typedef struct dap_chain_ch { - void *_inheritor; - dap_timerfd_t *sync_timer; - void *sync_context; - - // Legacy section // - int state; - - uint64_t stats_request_atoms_processed; - uint64_t stats_request_gdb_processed; - - dap_chain_ch_hash_item_t * remote_atoms; // Remote atoms - dap_chain_ch_hash_item_t * remote_gdbs; // Remote gdbs - - // 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_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_t; - -#define DAP_CHAIN_CH(a) ((dap_chain_ch_t *) ((a)->internal) ) -#define DAP_STREAM_CH(a) ((dap_stream_ch_t *)((a)->_inheritor)) -#define DAP_CHAIN_PKT_EXPECT_SIZE 7168 -#define DAP_CHAIN_CH_ID 'C' - 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_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, dap_chain_net_id_t a_net_id, dap_chain_id_t a_chain_id, dap_chain_cell_id_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 0c721f1408379a5972fdf7138514607b9574cacc..67b0465d74251d973c672143f6d2cba1d607a093 100644 --- a/modules/chain/include/dap_chain_ch_pkt.h +++ b/modules/chain/include/dap_chain_ch_pkt.h @@ -36,16 +36,10 @@ #include "dap_stream_ch.h" -#define DAP_CHAIN_CH_PKT_VERSION 0x02 +#define DAP_CHAIN_CH_PKT_VERSION_LEGACY 0x01 +#define DAP_CHAIN_CH_PKT_VERSION_CURRENT 0x02 //Legacy -#define DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_REQ 0x05 -#define DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_START 0x25 -#define DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS 0x35 -#define DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_END 0x45 -#define DAP_CHAIN_CH_PKT_TYPE_FIRST_CHAIN 0x20 -#define DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAINS 0x03 - #define DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_REQ 0x06 #define DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_START 0x26 #define DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB 0x36 @@ -54,31 +48,30 @@ #define DAP_CHAIN_CH_PKT_TYPE_GLOBAL_DB 0x11 #define DAP_CHAIN_CH_PKT_TYPE_SYNCED_GLOBAL_DB 0x13 -#define DAP_CHAIN_CH_PKT_TYPE_DELETE 0xda -#define DAP_CHAIN_CH_PKT_TYPE_TIMEOUT 0xfe -#define DAP_CHAIN_CH_PKT_TYPE_ERROR 0xff +#define DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_REQ 0x05 +#define DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_START 0x25 +#define DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS 0x35 +#define DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_END 0x45 +#define DAP_CHAIN_CH_PKT_TYPE_FIRST_CHAIN 0x20 +#define DAP_CHAIN_CH_PKT_TYPE_CHAIN_OLD 0x01 +#define DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAINS 0x03 + +// Freeze detectors +#define DAP_CHAIN_CH_PKT_TYPE_CHAINS_NO_FREEZE 0x15 +#define DAP_CHAIN_CH_PKT_TYPE_GLOBAL_DB_NO_FREEZE 0x16 // 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 0x84 #define DAP_CHAIN_CH_PKT_TYPE_CHAIN_SUMMARY 0x81 #define DAP_CHAIN_CH_PKT_TYPE_CHAIN_ACK 0x82 #define DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAIN 0x88 - -// TSD sections -#define DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_TSD 0x15 -#define DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_TSD 0x16 - -#define DAP_CHAIN_CH_PKT_TYPE_UPDATE_TSD_PROTO 0x0001 // Protocol version -#define DAP_CHAIN_CH_PKT_TYPE_UPDATE_TSD_COUNT 0x0002 // Items count -#define DAP_CHAIN_CH_PKT_TYPE_UPDATE_TSD_HASH_LAST 0x0003 // Hash of last(s) item -#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 +#define DAP_CHAIN_CH_PKT_TYPE_ERROR 0xff // *** Legacy *** // -typedef struct dap_chain_ch_update_element{ +typedef struct dap_chain_ch_update_element { dap_hash_fast_t hash; uint32_t size; } DAP_ALIGN_PACKED dap_chain_ch_update_element_t; @@ -86,17 +79,39 @@ typedef struct dap_chain_ch_update_element{ 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]; + byte_t unused[48]; } 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" - -}; +DAP_STATIC_INLINE const char *dap_chain_ch_pkt_type_to_str(uint8_t a_pkt_type) +{ + switch (a_pkt_type) { + case DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_REQ: return "DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_REQ"; + case DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_START: return "DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_START"; + case DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB: return "DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB"; + case DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_END: return "DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_END"; + case DAP_CHAIN_CH_PKT_TYPE_FIRST_GLOBAL_DB: return "DAP_CHAIN_CH_PKT_TYPE_UPDATE_GLOBAL_DB_END"; + case DAP_CHAIN_CH_PKT_TYPE_GLOBAL_DB: return "DAP_CHAIN_CH_PKT_TYPE_GLOBAL_DB"; + case DAP_CHAIN_CH_PKT_TYPE_SYNCED_GLOBAL_DB: return "DAP_CHAIN_CH_PKT_TYPE_SYNCED_GLOBAL_DB"; + + case DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_REQ: return "DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_REQ"; + case DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_START: return "DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_START"; + case DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS: return "DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS"; + case DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_END: return "DAP_CHAIN_CH_PKT_TYPE_UPDATE_CHAINS_END"; + case DAP_CHAIN_CH_PKT_TYPE_FIRST_CHAIN: return "DAP_CHAIN_CH_PKT_TYPE_FIRST_CHAIN"; + case DAP_CHAIN_CH_PKT_TYPE_CHAIN_OLD: return "DAP_CHAIN_CH_PKT_TYPE_CHAIN_OLD"; + case DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAINS: return "DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAINS"; + + case DAP_CHAIN_CH_PKT_TYPE_CHAIN_REQ: return "DAP_CHAIN_CH_PKT_TYPE_CHAIN_REQ"; + case DAP_CHAIN_CH_PKT_TYPE_CHAIN_MISS: return "DAP_CHAIN_CH_PKT_TYPE_CHAIN_MISS"; + case DAP_CHAIN_CH_PKT_TYPE_CHAIN: return "DAP_CHAIN_CH_PKT_TYPE_CHAIN"; + case DAP_CHAIN_CH_PKT_TYPE_CHAIN_SUMMARY: return "DAP_CHAIN_CH_PKT_TYPE_CHAIN_SUMMARY"; + case DAP_CHAIN_CH_PKT_TYPE_CHAIN_ACK: return "DAP_CHAIN_CH_PKT_TYPE_CHAIN_ACK"; + case DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAIN: return "DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAIN"; + + case DAP_CHAIN_CH_PKT_TYPE_ERROR: return "DAP_CHAIN_CH_PKT_TYPE_ERROR"; + default: return "DAP_CHAIN_CH_PKT_TYPE_UNKNOWN"; + } +} // *** Active *** // @@ -134,80 +149,17 @@ typedef struct dap_chain_ch_pkt { 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, - const void *a_data, size_t a_data_size); - -size_t dap_chain_ch_pkt_write_unsafe(dap_stream_ch_t *a_ch, uint8_t a_type, uint64_t a_net_id, - uint64_t a_chain_id, uint64_t a_cell_id, - const void * a_data, size_t a_data_size); - -size_t dap_chain_ch_pkt_write_mt(dap_stream_worker_t *a_worker, dap_stream_ch_uuid_t a_ch_uuid, uint8_t a_type, uint64_t a_net_id, - uint64_t a_chain_id, uint64_t a_cell_id, - const void * a_data, size_t a_data_size); - -size_t dap_chain_ch_pkt_write_multi_mt(dap_stream_ch_cachet_t *a_links, size_t a_count, uint8_t a_type, uint64_t a_net_id, - uint64_t a_chain_id, uint64_t a_cell_id, - const void * a_data, size_t a_data_size); - -size_t dap_chain_ch_pkt_write_inter(dap_events_socket_t * a_es_input, dap_stream_ch_uuid_t a_ch_uuid, uint8_t a_type,uint64_t a_net_id, - uint64_t a_chain_id, uint64_t a_cell_id, - const void * a_data, size_t a_data_size); - -/** - * @brief dap_chain_ch_pkt_write_error_unsafe - * @param a_ch - * @param a_net_id - * @param a_chain_id - * @param a_cell_id - * @param a_err_string_format - * @return - */ -inline static DAP_PRINTF_ATTR(5, 6) size_t dap_chain_ch_pkt_write_error_unsafe(dap_stream_ch_t *a_ch, uint64_t a_net_id, - uint64_t a_chain_id, uint64_t a_cell_id, const char *a_err_string_format, ...) -{ - va_list l_va; - char *l_str; - va_start(l_va, a_err_string_format); - int l_size = vsnprintf(NULL,0,a_err_string_format,l_va); - va_end(l_va); - if (l_size > 0) { - l_size++; - l_str = DAP_NEW_STACK_SIZE(char, l_size); - va_start(l_va, a_err_string_format); - vsnprintf(l_str, l_size,a_err_string_format, l_va); - va_end(l_va); - return dap_chain_ch_pkt_write_unsafe(a_ch, DAP_CHAIN_CH_PKT_TYPE_ERROR, - a_net_id, a_chain_id, a_cell_id, l_str, l_size); - } - return 0; -} +dap_chain_ch_pkt_t *dap_chain_ch_pkt_new(dap_chain_net_id_t a_net_id, dap_chain_id_t a_chain_id, dap_chain_cell_id_t a_cell_id, + const void *a_data, size_t a_data_size, uint8_t a_version); -/** - * @brief dap_chain_ch_pkt_write_error_inter - * @param a_es_input - * @param a_ch - * @param a_net_id - * @param a_chain_id - * @param a_cell_id - * @param a_err_string_format - * @return - */ -static inline size_t dap_chain_ch_pkt_write_error_inter(dap_events_socket_t *a_es_input, dap_stream_ch_uuid_t a_ch_uuid, - uint64_t a_net_id, uint64_t a_chain_id, uint64_t a_cell_id, const char *a_err_string_format, ...) -{ - va_list l_va; - char *l_str; - va_start(l_va, a_err_string_format); - int l_size = vsnprintf(NULL, 0, a_err_string_format, l_va); - va_end(l_va); - if (l_size > 0) { - l_size++; - l_str = DAP_NEW_STACK_SIZE(char, l_size); - va_start(l_va, a_err_string_format); - vsnprintf(l_str, l_size, a_err_string_format, l_va); - va_end(l_va); - return dap_chain_ch_pkt_write_inter(a_es_input, a_ch_uuid, DAP_CHAIN_CH_PKT_TYPE_ERROR, - a_net_id, a_chain_id, a_cell_id, l_str, l_size); - } - return 0; -} +size_t dap_chain_ch_pkt_write_unsafe(dap_stream_ch_t *a_ch, uint8_t a_type, + dap_chain_net_id_t a_net_id, dap_chain_id_t a_chain_id, dap_chain_cell_id_t a_cell_id, + const void *a_data, size_t a_data_size, uint8_t a_version); + +size_t dap_chain_ch_pkt_write_mt(dap_stream_worker_t *a_worker, dap_stream_ch_uuid_t a_ch_uuid, uint8_t a_type, + dap_chain_net_id_t a_net_id, dap_chain_id_t a_chain_id, dap_chain_cell_id_t a_cell_id, + const void *a_data, size_t a_data_size, uint8_t a_version); + +size_t dap_chain_ch_pkt_write_inter(dap_events_socket_t *a_es_input, dap_stream_ch_uuid_t a_ch_uuid, uint8_t a_type, + dap_chain_net_id_t a_net_id, dap_chain_id_t a_chain_id, dap_chain_cell_id_t a_cell_id, + const void *a_data, size_t a_data_size, uint8_t a_version); diff --git a/modules/chain/tests/dap_chain_ledger_tests.c b/modules/chain/tests/dap_chain_ledger_tests.c index 455fe7a1ab1366be6c027d76434727bf9543d0cc..61250d2c2ee38a7f09bfe055866b61b7ec7e8b5c 100644 --- a/modules/chain/tests/dap_chain_ledger_tests.c +++ b/modules/chain/tests/dap_chain_ledger_tests.c @@ -24,7 +24,7 @@ dap_chain_datum_token_t *dap_ledger_test_create_datum_decl(dap_cert_t *a_cert, l_token->version = 2; l_token->type = DAP_CHAIN_DATUM_TOKEN_TYPE_DECL; l_token->subtype = DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE; - dap_snprintf(l_token->ticker, sizeof(l_token->ticker), "%s", a_token_ticker); + snprintf(l_token->ticker, sizeof(l_token->ticker), "%s", a_token_ticker); l_token->signs_valid = 1; l_token->total_supply = a_total_supply; l_token->header_native_decl.decimals = 18; @@ -798,7 +798,7 @@ void dap_ledger_test_run(void){ dap_chain_net_srv_stake_pos_delegate_init(); dap_assert_PIF(!dap_chain_net_srv_init(), "Srv initializstion"); dap_chain_net_id_t l_iddn = {0}; - dap_sscanf("0xFA0", "0x%16"DAP_UINT64_FORMAT_x, &l_iddn.uint64); + sscanf("0xFA0", "0x%16"DAP_UINT64_FORMAT_x, &l_iddn.uint64); dap_print_module_name("dap_ledger"); uint16_t l_flags = 0; l_flags |= DAP_LEDGER_CHECK_TOKEN_EMISSION; diff --git a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c index b23a4e5e1cb25d00cb37b8971b40917d4167d043..39441608440095821083be8f57969a1f4667e75f 100644 --- a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c +++ b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c @@ -826,7 +826,7 @@ void s_set_usage_data_to_gdb(const dap_chain_net_srv_usage_t *a_usage) client_statistic_value_t l_bin_value_new = {0}; size_t l_value_size = 0; // forming key - dap_sprintf(l_bin_key.key, "0x%016"DAP_UINT64_FORMAT_X"", a_usage->service->uid.uint64); + sprintf(l_bin_key.key, "0x%016"DAP_UINT64_FORMAT_X"", a_usage->service->uid.uint64); dap_chain_hash_fast_to_str_do(&a_usage->client_pkey_hash, l_bin_key.key + 18); // check writed value client_statistic_value_t *l_bin_value = (client_statistic_value_t *)dap_global_db_get_sync(SRV_STATISTIC_GDB_GROUP, l_bin_key.key, &l_value_size, NULL, NULL); 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 23d3aaac5a2808a68dec9aac455be73aba851857..448a1e0a8dec601490c9089bd47243de23228037 100644 --- a/modules/channel/chain-net/dap_stream_ch_chain_net.c +++ b/modules/channel/chain-net/dap_stream_ch_chain_net.c @@ -43,10 +43,8 @@ #include "dap_common.h" #include "dap_strfuncs.h" -#include "dap_cert.h" -#include "uthash.h" -#include "dap_http_client.h" -#include "dap_global_db.h" +#include "dap_chain_cs_esbocs.h" +#include "dap_chain_net_srv_order.h" #include "dap_stream.h" #include "dap_stream_ch_pkt.h" #include "dap_stream_ch_proc.h" @@ -207,12 +205,12 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void* a_arg) log_it(L_ERROR, "Invalid net id in packet"); } else { dap_list_t * l_orders = NULL; - dap_enc_key_t * enc_key_pvt = NULL; + dap_enc_key_t *l_enc_key_pvt = NULL; dap_chain_t *l_chain = NULL; DL_FOREACH(l_net->pub.chains, l_chain) - if(l_chain->callback_get_signing_certificate != NULL){ - enc_key_pvt = l_chain->callback_get_signing_certificate(l_chain); - if(enc_key_pvt) + if (!dap_strcmp(dap_chain_get_cs_type(l_chain), "esbocs")) { + l_enc_key_pvt = dap_chain_esbocs_get_sign_key(l_chain); + if (l_enc_key_pvt) break; } dap_sign_t *l_sign = NULL; @@ -228,10 +226,9 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void* a_arg) .uint64 = dap_chain_net_get_cur_addr_int(l_net) }; - if(enc_key_pvt) - { + if (l_enc_key_pvt) { flags = flags | F_CERT;//faund sert - l_sign = dap_sign_create(enc_key_pvt, (uint8_t*)l_ch_chain_net_pkt->data, + l_sign = dap_sign_create(l_enc_key_pvt, (uint8_t*)l_ch_chain_net_pkt->data, l_ch_chain_net_pkt->hdr.data_size, 0); if(l_sign) { diff --git a/modules/common/dap_chain_common.c b/modules/common/dap_chain_common.c index 1968c12792f1fbdc230738092bcc502dc7448c52..d3351160e6efa6f17901f12e2932c1f401617029 100644 --- a/modules/common/dap_chain_common.c +++ b/modules/common/dap_chain_common.c @@ -52,14 +52,15 @@ size_t dap_chain_hash_slow_to_str( dap_chain_hash_slow_t *a_hash, char *a_str, s { const size_t c_hash_str_size = sizeof(*a_hash) * 2 + 1 /*trailing zero*/+ 2 /* heading 0x */; - if(a_str_max < c_hash_str_size) { + if (a_str_max < c_hash_str_size) { log_it(L_ERROR, "String for hash too small, need %zu but have only %zu", c_hash_str_size, a_str_max); + return 0; } size_t i; - snprintf(a_str, 3, "0x"); + sprintf(a_str, "0x"); - for(i = 0; i < sizeof(a_hash->raw); ++i) - snprintf( a_str + i * 2 + 2, 3, "%02x", a_hash->raw[i] ); + for (i = 0; i < sizeof(a_hash->raw); ++i) + sprintf( a_str + i * 2 + 2, "%02x", a_hash->raw[i] ); a_str[c_hash_str_size] = '\0'; @@ -71,10 +72,11 @@ size_t dap_chain_hash_slow_to_str( dap_chain_hash_slow_t *a_hash, char *a_str, s * @param a_addr * @return */ -char *dap_chain_addr_to_str(const dap_chain_addr_t *a_addr) +const char *dap_chain_addr_to_str(const dap_chain_addr_t *a_addr) { dap_return_val_if_pass(!a_addr, NULL); - dap_return_val_if_pass(dap_chain_addr_is_blank(a_addr), "null"); + if (dap_chain_addr_is_blank(a_addr)) + return "null"; static _Thread_local char s_buf[DAP_ENC_BASE58_ENCODE_SIZE(sizeof(dap_chain_addr_t))] = { '\0' }; return dap_enc_base58_encode(a_addr, sizeof(dap_chain_addr_t), s_buf) ? s_buf : NULL; } diff --git a/modules/common/dap_chain_datum.c b/modules/common/dap_chain_datum.c index b1f7aec824abdaf6728ddc5366cafa4c64ce961d..54d06bfa0397b406e8e4218dc983abe0def4087f 100644 --- a/modules/common/dap_chain_datum.c +++ b/modules/common/dap_chain_datum.c @@ -34,6 +34,7 @@ #include "dap_chain_datum_tx_voting.h" #include "dap_chain_datum_hashtree_roots.h" #include "dap_enc_base58.h" +#include "dap_sign.h" #define LOG_TAG "dap_chain_datum" @@ -161,7 +162,7 @@ void dap_chain_datum_token_dump_tsd(dap_string_t *a_str_out, dap_chain_datum_tok continue; case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DELEGATE_EMISSION_FROM_STAKE_LOCK: { dap_chain_datum_token_tsd_delegate_from_stake_lock_t *l_tsd_section = _dap_tsd_get_object(l_tsd, dap_chain_datum_token_tsd_delegate_from_stake_lock_t); - char *l_balance, *l_tmp = dap_uint256_to_char(l_tsd_section->emission_rate, &l_balance); + const char *l_balance, *l_tmp = dap_uint256_to_char(l_tsd_section->emission_rate, &l_balance); dap_string_append_printf(a_str_out, "ticker_token_from: %s\nemission_rate: %s\n", l_tsd_section->ticker_token_from, l_balance); }continue; @@ -369,7 +370,7 @@ void dap_datum_token_dump_tsd_to_json(json_object * json_obj_out, dap_chain_datu continue; default: { char l_tsd_type_char[50] = {}; - dap_snprintf(l_tsd_type_char, 50, "<0x%04hX>", l_tsd->type); + snprintf(l_tsd_type_char, 50, "<0x%04hX>", l_tsd->type); json_object_object_add(json_obj_out, "tsd_type", json_object_new_string(l_tsd_type_char)); json_object_object_add(json_obj_out, "tsd_size", json_object_new_int(l_tsd->size)); } @@ -429,7 +430,7 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum, ((dap_chain_tx_in_t*)item)->header.tx_out_prev_idx); break; case TX_ITEM_TYPE_OUT_OLD: { - char *l_value_str = dap_uint256_to_char( + const char *l_value_str = dap_uint256_to_char( dap_chain_uint256_from(((dap_chain_tx_out_old_t*)item)->header.value), NULL ); dap_string_append_printf(a_str_out, "\t OUT OLD (64):\n" "\t\t Value: %s (%"DAP_UINT64_FORMAT_U")\n" @@ -439,7 +440,7 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum, dap_chain_addr_to_str(&((dap_chain_tx_out_old_t*)item)->addr)); } break; case TX_ITEM_TYPE_OUT: { // 256 - char *l_coins_str, + const char *l_coins_str, *l_value_str = dap_uint256_to_char(((dap_chain_tx_out_t*)item)->header.value, &l_coins_str), *l_addr_str = dap_chain_addr_to_str(&((dap_chain_tx_out_t*)item)->addr); dap_string_append_printf(a_str_out, "\t OUT:\n" @@ -502,7 +503,7 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum, dap_string_append_printf(a_str_out, "\tSender addr: %s\n", dap_chain_addr_to_str(&l_sender_addr)); } break; case TX_ITEM_TYPE_RECEIPT: { - char *l_coins_str, *l_value_str = dap_uint256_to_char(((dap_chain_datum_tx_receipt_t*)item)->receipt_info.value_datoshi, &l_coins_str); + const char *l_coins_str, *l_value_str = dap_uint256_to_char(((dap_chain_datum_tx_receipt_t*)item)->receipt_info.value_datoshi, &l_coins_str); dap_string_append_printf(a_str_out, "\t Receipt:\n" "\t\t size: %"DAP_UINT64_FORMAT_U"\n" "\t\t ext size: %"DAP_UINT64_FORMAT_U"\n" @@ -575,7 +576,7 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum, ((dap_chain_tx_in_cond_t*)item)->header.tx_out_prev_idx); break; case TX_ITEM_TYPE_OUT_COND: { - char *l_coins_str, *l_value_str = dap_uint256_to_char(((dap_chain_tx_out_cond_t*)item)->header.value, &l_coins_str); + const char *l_coins_str, *l_value_str = dap_uint256_to_char(((dap_chain_tx_out_cond_t*)item)->header.value, &l_coins_str); dap_time_t l_ts_exp = ((dap_chain_tx_out_cond_t*)item)->header.ts_expires; dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, l_ts_exp); dap_string_append_printf(a_str_out, "\t OUT COND:\n" @@ -589,7 +590,7 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum, ((dap_chain_tx_out_cond_t*)item)->header.srv_uid.uint64); switch (((dap_chain_tx_out_cond_t*)item)->header.subtype) { case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY: { - char *l_coins_str, *l_value_str = + const char *l_coins_str, *l_value_str = dap_uint256_to_char( ((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.unit_price_max_datoshi, &l_coins_str ); l_hash_tmp = &((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.pkey_hash; l_hash_str = dap_strcmp(a_hash_out_type, "hex") @@ -618,7 +619,7 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum, NODE_ADDR_FP_ARGS(l_signer_node_addr)); } break; case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE: { - char *l_rate_str, *l_tmp_str = + const char *l_rate_str, *l_tmp_str = dap_uint256_to_char( (((dap_chain_tx_out_cond_t*)item)->subtype.srv_xchange.rate), &l_rate_str ); dap_string_append_printf(a_str_out, "\t\t\t net id: 0x%016"DAP_UINT64_FORMAT_x"\n" "\t\t\t buy_token: %s\n" @@ -636,7 +637,7 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum, } } break; case TX_ITEM_TYPE_OUT_EXT: { - char *l_coins_str, *l_value_str = dap_uint256_to_char( ((dap_chain_tx_out_ext_t*)item)->header.value, &l_coins_str ); + const char *l_coins_str, *l_value_str = dap_uint256_to_char( ((dap_chain_tx_out_ext_t*)item)->header.value, &l_coins_str); dap_string_append_printf(a_str_out, "\t OUT EXT:\n" "\t\t Addr: %s\n" "\t\t Token: %s\n" @@ -698,6 +699,320 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum, return true; } +/** + * @brief _dap_chain_datum_tx_out_data + * + * @param a_datum + * @param a_ledger + * @param a_str_out + * @param a_hash_out_type + * @param save_processed_tx + * @param a_tx_hash_processed + * @param l_tx_num + */ +bool dap_chain_datum_dump_tx_json(dap_chain_datum_tx_t *a_datum, + const char *a_ticker, + json_object* json_obj_out, + const char *a_hash_out_type, + dap_hash_fast_t *a_tx_hash, + dap_chain_net_id_t a_net_id) +{ + bool l_is_first = false; + dap_chain_tx_in_t *l_in_item = (dap_chain_tx_in_t *)dap_chain_datum_tx_item_get(a_datum, NULL, TX_ITEM_TYPE_IN, NULL); + 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]; + 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* json_arr_items = json_object_new_array(); + dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, a_datum->header.ts_created); + l_is_first ? + json_object_object_add(json_obj_out, "first transaction", json_object_new_string("emit")): + json_object_object_add(json_obj_out, "first transaction", json_object_new_string("")); + json_object_object_add(json_obj_out, "hash", json_object_new_string(l_hash_str)); + json_object_object_add(json_obj_out, "TS Created", json_object_new_string(l_tmp_buf)); + json_object_object_add(json_obj_out, "Token ticker", a_ticker ? json_object_new_string(a_ticker) : json_object_new_string("")); + //json_object_array_add(json_arr_items, json_obj_tx); + + uint32_t l_tx_items_count = 0; + uint32_t l_tx_items_size = a_datum->header.tx_items_size; + dap_hash_fast_t *l_hash_tmp = NULL; + while (l_tx_items_count < l_tx_items_size) { + json_object* json_obj_item = json_object_new_object(); + uint8_t *item = a_datum->tx_items + l_tx_items_count; + size_t l_item_tx_size = dap_chain_datum_item_tx_get_size(item); + switch(dap_chain_datum_tx_item_get_type(item)){ + case TX_ITEM_TYPE_IN: + l_hash_tmp = &((dap_chain_tx_in_t*)item)->header.tx_prev_hash; + if (dap_hash_fast_is_blank(l_hash_tmp)) { + l_hash_str = "BLANK"; + } else { + l_hash_str = dap_strcmp(a_hash_out_type, "hex") + ? dap_enc_base58_encode_hash_to_str_static(l_hash_tmp) + : dap_chain_hash_fast_to_str_static(l_hash_tmp); + } + json_object_object_add(json_obj_item,"item type", json_object_new_string("IN")); + json_object_object_add(json_obj_item,"Tx prev hash", json_object_new_string(l_hash_str)); + json_object_object_add(json_obj_item,"Tx out prev idx", json_object_new_uint64(((dap_chain_tx_in_t*)item)->header.tx_out_prev_idx)); + break; + case TX_ITEM_TYPE_OUT_OLD: { + const char *l_value_str = dap_uint256_to_char( + dap_chain_uint256_from(((dap_chain_tx_out_old_t*)item)->header.value), NULL ); + json_object_object_add(json_obj_item,"item type", json_object_new_string("OUT OLD")); + json_object_object_add(json_obj_item,"Value", json_object_new_uint64(((dap_chain_tx_out_old_t*)item)->header.value)); + json_object_object_add(json_obj_item,"Address", json_object_new_string(dap_chain_addr_to_str(&((dap_chain_tx_out_old_t*)item)->addr))); + } break; + case TX_ITEM_TYPE_OUT: { // 256 + const char *l_coins_str, + *l_value_str = dap_uint256_to_char(((dap_chain_tx_out_t*)item)->header.value, &l_coins_str), + *l_addr_str = dap_chain_addr_to_str(&((dap_chain_tx_out_t*)item)->addr); + json_object_object_add(json_obj_item,"item type", json_object_new_string("OUT")); + json_object_object_add(json_obj_item,"Coins", json_object_new_string(l_coins_str)); + json_object_object_add(json_obj_item,"Value", json_object_new_string(l_value_str)); + json_object_object_add(json_obj_item,"Address", json_object_new_string(l_addr_str)); + } break; + case TX_ITEM_TYPE_IN_EMS: { + char l_tmp_buff[70]={0}; + l_hash_tmp = &((dap_chain_tx_in_ems_t*)item)->header.token_emission_hash; + l_hash_str = dap_strcmp(a_hash_out_type, "hex") + ? dap_enc_base58_encode_hash_to_str_static(l_hash_tmp) + : dap_chain_hash_fast_to_str_static(l_hash_tmp); + json_object_object_add(json_obj_item,"item type", json_object_new_string("IN_EMS")); + json_object_object_add(json_obj_item,"ticker", json_object_new_string(((dap_chain_tx_in_ems_t*)item)->header.ticker)); + json_object_object_add(json_obj_item,"token_emission_hash", json_object_new_string(l_hash_str)); + sprintf(l_tmp_buff,"0x%016"DAP_UINT64_FORMAT_x"",((dap_chain_tx_in_ems_t*)item)->header.token_emission_chain_id.uint64); + json_object_object_add(json_obj_item,"token_emission_chain_id", json_object_new_string(l_tmp_buff)); + } break; + /* + case TX_ITEM_TYPE_IN_EMS_EXT: { + l_hash_tmp = &((dap_chain_tx_in_ems_ext_t*)item)->header.ext_tx_hash; + l_hash_str = dap_strcmp(a_hash_out_type, "hex") + ? dap_enc_base58_encode_hash_to_str(l_hash_tmp) + : dap_chain_hash_fast_to_str_new(l_hash_tmp); + dap_string_append_printf(a_str_out, "\t IN_EMS EXT:\n" + "\t\t Version: %u\n" + "\t\t Ticker: %s\n" + "\t\t Ext chain id: 0x%016"DAP_UINT64_FORMAT_x"\n" + "\t\t Ext net id: 0x%016"DAP_UINT64_FORMAT_x"\n" + "\t\t Ext tx hash: %s\n" + "\t\t Ext tx out idx: %u\n", + ((dap_chain_tx_in_ems_ext_t*)item)->header.version, + ((dap_chain_tx_in_ems_ext_t*)item)->header.ticker, + ((dap_chain_tx_in_ems_ext_t*)item)->header.ext_chain_id.uint64, + ((dap_chain_tx_in_ems_ext_t*)item)->header.ext_net_id.uint64, + l_hash_str, + ((dap_chain_tx_in_ems_ext_t*)item)->header.ext_tx_out_idx); + DAP_DELETE(l_hash_str); + } break; */ + + case TX_ITEM_TYPE_IN_REWARD: { + l_hash_tmp = &((dap_chain_tx_in_reward_t *)item)->block_hash; + l_hash_str = dap_strcmp(a_hash_out_type, "hex") + ? dap_enc_base58_encode_hash_to_str_static(l_hash_tmp) + : dap_chain_hash_fast_to_str_static(l_hash_tmp); + json_object_object_add(json_obj_item,"item type", json_object_new_string("IN_REWARD")); + json_object_object_add(json_obj_item,"block_hash", json_object_new_string(l_hash_str)); + } break; + + case TX_ITEM_TYPE_SIG: { + dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t*)item); + json_object_object_add(json_obj_item,"item type", json_object_new_string("SIG")); + dap_sign_get_information_json(l_sign, json_obj_item, a_hash_out_type); + dap_chain_addr_t l_sender_addr; + dap_chain_addr_fill_from_sign(&l_sender_addr, l_sign, a_net_id); + json_object_object_add(json_obj_item,"Sender addr", json_object_new_string(dap_chain_addr_to_str(&l_sender_addr))); + } break; + case TX_ITEM_TYPE_RECEIPT: { + const char *l_coins_str, *l_value_str = dap_uint256_to_char(((dap_chain_datum_tx_receipt_t*)item)->receipt_info.value_datoshi, &l_coins_str); + json_object_object_add(json_obj_item,"item type", json_object_new_string("RECEIPT")); + json_object_object_add(json_obj_item,"size", json_object_new_uint64(((dap_chain_datum_tx_receipt_t*)item)->size)); + json_object_object_add(json_obj_item,"ext size", json_object_new_uint64(((dap_chain_datum_tx_receipt_t*)item)->exts_size)); + json_object_object_add(json_obj_item,"INFO", json_object_new_string("")); + json_object_object_add(json_obj_item,"units", json_object_new_uint64(((dap_chain_datum_tx_receipt_t*)item)->receipt_info.units)); + json_object_object_add(json_obj_item,"uid", json_object_new_uint64(((dap_chain_datum_tx_receipt_t*)item)->receipt_info.srv_uid.uint64)); + json_object_object_add(json_obj_item,"units type", json_object_new_string(dap_chain_srv_unit_enum_to_str(((dap_chain_datum_tx_receipt_t*)item)->receipt_info.units_type.enm))); + json_object_object_add(json_obj_item,"coins", json_object_new_string(l_coins_str)); + json_object_object_add(json_obj_item,"value", json_object_new_string(l_value_str)); + + json_object_object_add(json_obj_item,"Exts",json_object_new_string("")); + switch ( ((dap_chain_datum_tx_receipt_t*)item)->exts_size ) { + case (sizeof(dap_sign_t) * 2): { + dap_sign_t *l_client = DAP_CAST_PTR( dap_sign_t, ((dap_chain_datum_tx_receipt_t*)item)->exts_n_signs + sizeof(dap_sign_t) ); + json_object_object_add(json_obj_item,"Client", json_object_new_string("")); + dap_sign_get_information_json(l_client, json_obj_item, a_hash_out_type); + } + case (sizeof(dap_sign_t)): { + dap_sign_t *l_provider = DAP_CAST_PTR( dap_sign_t, ((dap_chain_datum_tx_receipt_t*)item)->exts_n_signs ); + json_object_object_add(json_obj_item,"Provider", json_object_new_string("")); + dap_sign_get_information_json(l_provider,json_obj_item, a_hash_out_type); + break; + } + } + } break; + case TX_ITEM_TYPE_PKEY: { + dap_pkey_t *l_pkey = (dap_pkey_t*)((dap_chain_tx_pkey_t*)item)->pkey; + dap_chain_hash_fast_t l_pkey_hash; + dap_hash_fast(l_pkey->pkey, l_pkey->header.size, &l_pkey_hash); + 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); + json_object_object_add(json_obj_item,"item type", json_object_new_string("PKey")); + json_object_object_add(json_obj_item,"PKey", json_object_new_string("")); + json_object_object_add(json_obj_item,"SIG type", json_object_new_string(dap_sign_type_to_str(((dap_chain_tx_pkey_t*)item)->header.sig_type))); + json_object_object_add(json_obj_item,"SIG size", json_object_new_uint64(((dap_chain_tx_pkey_t*)item)->header.sig_size)); + json_object_object_add(json_obj_item,"Sequence number", json_object_new_uint64(((dap_chain_tx_pkey_t*)item)->seq_no)); + json_object_object_add(json_obj_item,"Key", json_object_new_string("")); + json_object_object_add(json_obj_item,"Type", json_object_new_string(dap_pkey_type_to_str(l_pkey->header.type))); + json_object_object_add(json_obj_item,"Size", json_object_new_uint64(l_pkey->header.size)); + json_object_object_add(json_obj_item,"Hash", json_object_new_string(l_hash_str)); + + } break; + case TX_ITEM_TYPE_TSD: { + json_object_object_add(json_obj_item,"item type", json_object_new_string("TSD data")); + json_object_object_add(json_obj_item,"type", json_object_new_uint64(((dap_chain_tx_tsd_t*)item)->header.type)); + json_object_object_add(json_obj_item,"size", json_object_new_uint64(((dap_chain_tx_tsd_t*)item)->header.size)); + } break; + case TX_ITEM_TYPE_IN_COND: + json_object_object_add(json_obj_item,"item type", json_object_new_string("IN COND")); + l_hash_tmp = &((dap_chain_tx_in_cond_t*)item)->header.tx_prev_hash; + l_hash_str = dap_strcmp(a_hash_out_type, "hex") + ? dap_enc_base58_encode_hash_to_str_static(l_hash_tmp) + : dap_chain_hash_fast_to_str_static(l_hash_tmp); + json_object_object_add(json_obj_item,"Receipt_idx", json_object_new_uint64(((dap_chain_tx_in_cond_t*)item)->header.receipt_idx)); + json_object_object_add(json_obj_item,"Tx_prev_hash", json_object_new_string(l_hash_str)); + json_object_object_add(json_obj_item,"Tx_out_prev_idx", json_object_new_uint64(((dap_chain_tx_in_cond_t*)item)->header.tx_out_prev_idx)); + break; + case TX_ITEM_TYPE_OUT_COND: { + char l_tmp_buff[70]={0}; + json_object_object_add(json_obj_item,"item type", json_object_new_string("OUT COND")); + const char *l_coins_str, *l_value_str = dap_uint256_to_char(((dap_chain_tx_out_cond_t*)item)->header.value, &l_coins_str); + dap_time_t l_ts_exp = ((dap_chain_tx_out_cond_t*)item)->header.ts_expires; + dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, l_ts_exp); + json_object_object_add(json_obj_item,"Header", json_object_new_string("")); + json_object_object_add(json_obj_item,"ts_expires", l_ts_exp ? json_object_new_string(l_tmp_buf) : json_object_new_string("never")); + json_object_object_add(json_obj_item,"coins", json_object_new_string(l_coins_str)); + json_object_object_add(json_obj_item,"value", json_object_new_string(l_value_str)); + json_object_object_add(json_obj_item,"subtype", json_object_new_string(dap_chain_tx_out_cond_subtype_to_str(((dap_chain_tx_out_cond_t*)item)->header.subtype))); + sprintf(l_tmp_buff,"0x%016"DAP_UINT64_FORMAT_x"",((dap_chain_tx_out_cond_t*)item)->header.srv_uid.uint64); + json_object_object_add(json_obj_item,"uid", json_object_new_string(l_tmp_buff)); + switch (((dap_chain_tx_out_cond_t*)item)->header.subtype) { + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY: { + const char *l_coins_str, *l_value_str = + dap_uint256_to_char( ((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.unit_price_max_datoshi, &l_coins_str ); + l_hash_tmp = &((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.pkey_hash; + l_hash_str = dap_strcmp(a_hash_out_type, "hex") + ? dap_enc_base58_encode_hash_to_str_static(l_hash_tmp) + : dap_chain_hash_fast_to_str_static(l_hash_tmp); + sprintf(l_tmp_buff,"0x%08x",((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.unit.uint32); + json_object_object_add(json_obj_item,"unit", json_object_new_string(l_tmp_buff)); + json_object_object_add(json_obj_item,"pkey", json_object_new_string(l_hash_str)); + json_object_object_add(json_obj_item,"max price(coins)", json_object_new_string(l_coins_str)); + json_object_object_add(json_obj_item,"max price(value)", json_object_new_string(l_value_str)); + + } break; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE: { + dap_chain_node_addr_t *l_signer_node_addr = &((dap_chain_tx_out_cond_t*)item)->subtype.srv_stake_pos_delegate.signer_node_addr; + dap_chain_addr_t *l_signing_addr = &((dap_chain_tx_out_cond_t*)item)->subtype.srv_stake_pos_delegate.signing_addr; + l_hash_tmp = &l_signing_addr->data.hash_fast; + l_hash_str = dap_strcmp(a_hash_out_type, "hex") + ? dap_enc_base58_encode_hash_to_str_static(l_hash_tmp) + : dap_chain_hash_fast_to_str_static(l_hash_tmp); + json_object_object_add(json_obj_item,"signing_addr", json_object_new_string(dap_chain_addr_to_str(l_signing_addr))); + json_object_object_add(json_obj_item,"with pkey hash", json_object_new_string(l_hash_str)); + sprintf(l_tmp_buff,""NODE_ADDR_FP_STR"",NODE_ADDR_FP_ARGS(l_signer_node_addr)); + json_object_object_add(json_obj_item,"signer_node_addr", json_object_new_string(l_tmp_buff)); + + } break; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE: { + const char *l_rate_str, *l_tmp_str = + dap_uint256_to_char( (((dap_chain_tx_out_cond_t*)item)->subtype.srv_xchange.rate), &l_rate_str ); + sprintf(l_tmp_buff,"0x%016"DAP_UINT64_FORMAT_x"",((dap_chain_tx_out_cond_t*)item)->subtype.srv_xchange.buy_net_id.uint64); + json_object_object_add(json_obj_item,"net id", json_object_new_string(l_tmp_buff)); + json_object_object_add(json_obj_item,"buy_token", json_object_new_string(((dap_chain_tx_out_cond_t*)item)->subtype.srv_xchange.buy_token)); + json_object_object_add(json_obj_item,"rate", json_object_new_string(l_rate_str)); + } break; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK: { + dap_time_t l_ts_unlock = ((dap_chain_tx_out_cond_t*)item)->subtype.srv_stake_lock.time_unlock; + dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, l_ts_unlock); + json_object_object_add(json_obj_item,"time_unlock", json_object_new_string(l_tmp_buf)); + } break; + default: break; + } + } break; + case TX_ITEM_TYPE_OUT_EXT: { + const char *l_coins_str, *l_value_str = dap_uint256_to_char( ((dap_chain_tx_out_ext_t*)item)->header.value, &l_coins_str ); + json_object_object_add(json_obj_item,"item type", json_object_new_string("OUT EXT")); + json_object_object_add(json_obj_item,"Addr", json_object_new_string(dap_chain_addr_to_str(&((dap_chain_tx_out_ext_t*)item)->addr))); + json_object_object_add(json_obj_item,"Token", json_object_new_string(((dap_chain_tx_out_ext_t*)item)->token)); + json_object_object_add(json_obj_item,"Coins", json_object_new_string(l_coins_str)); + json_object_object_add(json_obj_item,"Value", json_object_new_string(l_value_str)); + + } break; + case TX_ITEM_TYPE_VOTING:{ + char l_tmp_buff[10]={0}; + int l_tsd_size = 0; + dap_chain_tx_tsd_t *l_item = (dap_chain_tx_tsd_t *)dap_chain_datum_tx_item_get(a_datum, 0, TX_ITEM_TYPE_TSD, &l_tsd_size); + if (!l_item || !l_tsd_size) + break; + dap_chain_datum_tx_voting_params_t *l_voting_params = dap_chain_voting_parse_tsd(a_datum); + json_object_object_add(json_obj_item,"item type", json_object_new_string("VOTING")); + json_object_object_add(json_obj_item,"Voting question", json_object_new_string(l_voting_params->voting_question)); + json_object_object_add(json_obj_item,"Answer options", json_object_new_string("")); + + dap_list_t *l_temp = l_voting_params->answers_list; + uint8_t l_index = 0; + while (l_temp) { + sprintf(l_tmp_buff, "%i", l_index); + json_object_object_add(json_obj_item, l_tmp_buff, json_object_new_string((char *)l_temp->data)); + l_index++; + l_temp = l_temp->next; + } + if (l_voting_params->voting_expire) { + dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, l_voting_params->voting_expire); + json_object_object_add(json_obj_item,"Voting expire", json_object_new_string(l_tmp_buf)); + } + if (l_voting_params->votes_max_count) { + sprintf(l_tmp_buff, "%"DAP_UINT64_FORMAT_U, l_voting_params->votes_max_count); + json_object_object_add(json_obj_item, "Votes max count", json_object_new_string(l_tmp_buff)); + } + json_object_object_add(json_obj_item,"Changing vote is", l_voting_params->vote_changing_allowed ? json_object_new_string("available") : + json_object_new_string("not available")); + l_voting_params->delegate_key_required ? + json_object_object_add(json_obj_item,"Votes max count", json_object_new_string("A delegated key is required to participate in voting.")): + json_object_object_add(json_obj_item,"Votes max count", json_object_new_string("A delegated key is not required to participate in voting.")); + + dap_list_free_full(l_voting_params->answers_list, NULL); + DAP_DELETE(l_voting_params->voting_question); + DAP_DELETE(l_voting_params); + } break; + case TX_ITEM_TYPE_VOTE:{ + char l_tmp_buff[10]={0}; + dap_chain_tx_vote_t *l_vote_item = (dap_chain_tx_vote_t *)item; + const char *l_hash_str = dap_chain_hash_fast_to_str_static(&l_vote_item->voting_hash); + json_object_object_add(json_obj_item,"item type", json_object_new_string("VOTE")); + json_object_object_add(json_obj_item,"Voting hash", json_object_new_string(l_hash_str)); + sprintf(l_tmp_buff,"%"DAP_UINT64_FORMAT_U"",l_vote_item->answer_idx); + json_object_object_add(json_obj_item,"Vote answer idx", json_object_new_string(l_tmp_buff)); + + } break; + default: + json_object_object_add(json_obj_item,"item type", json_object_new_string("This transaction have unknown item type")); + break; + } + json_object_array_add(json_arr_items, json_obj_item); + l_tx_items_count += l_item_tx_size; + // Freeze protection + if(!l_item_tx_size) + { + break; + } + + } + json_object_object_add(json_obj_out, "ITEMS", json_arr_items); + return true; +} + /** * @brief dap_chain_net_dump_datum * process datum verification process. Can be: @@ -819,7 +1134,7 @@ void dap_chain_datum_dump(dap_string_t *a_str_out, dap_chain_datum_t *a_datum, c case DAP_CHAIN_DATUM_TOKEN_EMISSION: { size_t l_emission_size = a_datum->header.data_size; dap_chain_datum_token_emission_t *l_emission = dap_chain_datum_emission_read(a_datum->data, &l_emission_size); - char *l_coins_str, *l_value_str = dap_uint256_to_char(l_emission->hdr.value, &l_coins_str); + const char *l_coins_str, *l_value_str = dap_uint256_to_char(l_emission->hdr.value, &l_coins_str); dap_string_append_printf(a_str_out, "emission: hash %s\n\t%s(%s) %s, type: %s, version: %d\n", l_hash_str, l_coins_str, @@ -889,3 +1204,212 @@ void dap_chain_datum_dump(dap_string_t *a_str_out, dap_chain_datum_t *a_datum, c } break; } } + + + +/** + * @brief dap_chain_net_dump_datum + * process datum verification process. Can be: + * if DAP_CHAIN_DATUM_TX, called dap_ledger_tx_add_check + * if DAP_CHAIN_DATUM_TOKEN_DECL, called dap_ledger_token_decl_add_check + * if DAP_CHAIN_DATUM_TOKEN_EMISSION, called dap_ledger_token_emission_add_check + * @param a_obj_out + * @param a_datum + */ +void dap_chain_datum_dump_json(json_object *a_obj_out, dap_chain_datum_t *a_datum, const char *a_hash_out_type, dap_chain_net_id_t a_net_id) +{ + if( a_datum == NULL){ + dap_json_rpc_error_add(-1,"==Datum is NULL"); + return; + } + json_object * json_obj_datum = json_object_new_object(); + dap_hash_fast_t l_datum_hash; + dap_hash_fast(a_datum->data, a_datum->header.data_size, &l_datum_hash); + 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) { + case DAP_CHAIN_DATUM_TOKEN_DECL: { + size_t l_token_size = a_datum->header.data_size; + dap_chain_datum_token_t * l_token = dap_chain_datum_token_read(a_datum->data, &l_token_size); + if(l_token_size < sizeof(dap_chain_datum_token_t)){ + dap_json_rpc_error_add(-2,"==Datum has incorrect size. Only %zu, while at least %zu is expected\n", + l_token_size, sizeof(dap_chain_datum_token_t)); + DAP_DEL_Z(l_token); + return; + } + json_object_object_add(json_obj_datum,"=== Datum Token Declaration ===",json_object_new_string("empty")); + json_object_object_add(json_obj_datum,"hash",json_object_new_string(l_hash_str)); + json_object_object_add(json_obj_datum,"ticker",json_object_new_string(l_token->ticker)); + json_object_object_add(json_obj_datum,"size",json_object_new_uint64(l_token_size)); + json_object_object_add(json_obj_datum,"version",json_object_new_int(l_token->version)); + + switch (l_token->type) { + case DAP_CHAIN_DATUM_TOKEN_TYPE_DECL: { + json_object_object_add(json_obj_datum,"type",json_object_new_string("DECL")); + switch (l_token->subtype) { + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE:{ + json_object_object_add(json_obj_datum,"subtype",json_object_new_string("PRIVATE")); + json_object_object_add(json_obj_datum,"decimals",json_object_new_uint64(l_token->header_private_decl.decimals)); + json_object_object_add(json_obj_datum,"auth signs valid",json_object_new_uint64(l_token->signs_valid)); + json_object_object_add(json_obj_datum,"auth signs total",json_object_new_uint64(l_token->signs_total)); + json_object_object_add(json_obj_datum,"total_supply",json_object_new_string(dap_uint256_to_char(l_token->total_supply, NULL))); + json_object_object_add(json_obj_datum,"Flags",json_object_new_string("")); + + dap_chain_datum_token_flags_dump_to_json(json_obj_datum,l_token->header_private_update.flags); + dap_datum_token_dump_tsd_to_json(json_obj_datum,l_token, l_token_size, a_hash_out_type); + size_t l_certs_field_size = l_token_size - sizeof(*l_token) - l_token->header_private_update.tsd_total_size; + dap_chain_datum_token_certs_dump_to_json(json_obj_datum,l_token->data_n_tsd + l_token->header_private_update.tsd_total_size, + l_certs_field_size, a_hash_out_type); + } break; + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: { + json_object_object_add(json_obj_datum,"subtype",json_object_new_string("CF20")); + json_object_object_add(json_obj_datum,"decimals",json_object_new_uint64(l_token->header_native_decl.decimals)); + json_object_object_add(json_obj_datum,"auth signs valid",json_object_new_uint64(l_token->signs_valid)); + json_object_object_add(json_obj_datum,"auth signs total",json_object_new_uint64(l_token->signs_total)); + json_object_object_add(json_obj_datum,"total_supply",json_object_new_string(dap_uint256_to_char(l_token->total_supply, NULL))); + json_object_object_add(json_obj_datum,"Flags",json_object_new_string("")); + + dap_chain_datum_token_flags_dump_to_json(json_obj_datum, l_token->header_native_decl.flags); + dap_datum_token_dump_tsd_to_json(json_obj_datum, l_token, l_token_size, a_hash_out_type); + size_t l_certs_field_size = l_token_size - sizeof(*l_token) - l_token->header_native_decl.tsd_total_size; + dap_chain_datum_token_certs_dump_to_json(json_obj_datum, l_token->data_n_tsd + l_token->header_native_decl.tsd_total_size, + l_certs_field_size, a_hash_out_type); + } break; + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PUBLIC: { + dap_chain_addr_t l_premine_addr = l_token->header_public.premine_address; + json_object_object_add(json_obj_datum,"subtype",json_object_new_string("PUBLIC")); + json_object_object_add(json_obj_datum,"premine_supply", json_object_new_string(dap_uint256_to_char(l_token->header_public.premine_supply, NULL))); + json_object_object_add(json_obj_datum,"premine_address", json_object_new_string(dap_chain_addr_to_str(&l_premine_addr))); + + json_object_object_add(json_obj_datum,"Flags",json_object_new_string("")); + dap_chain_datum_token_flags_dump_to_json(json_obj_datum, l_token->header_public.flags); + } break; + } + } break; + case DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE: { + json_object_object_add(json_obj_datum,"type",json_object_new_string("UPDATE")); + switch (l_token->subtype) { + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE: { + json_object_object_add(json_obj_datum,"subtype",json_object_new_string("PRIVATE")); + json_object_object_add(json_obj_datum,"decimals",json_object_new_uint64(l_token->header_private_decl.decimals)); + json_object_object_add(json_obj_datum,"auth signs valid",json_object_new_uint64(l_token->signs_valid)); + json_object_object_add(json_obj_datum,"auth signs total",json_object_new_uint64(l_token->signs_total)); + json_object_object_add(json_obj_datum,"total_supply",json_object_new_string(dap_uint256_to_char(l_token->total_supply, NULL))); + + json_object_object_add(json_obj_datum,"Flags",json_object_new_string("")); + dap_chain_datum_token_flags_dump_to_json(json_obj_datum, l_token->header_private_update.flags); + dap_datum_token_dump_tsd_to_json(json_obj_datum, l_token, l_token_size, a_hash_out_type); + size_t l_certs_field_size = l_token_size - sizeof(*l_token) - l_token->header_private_update.tsd_total_size; + dap_chain_datum_token_certs_dump_to_json(json_obj_datum, l_token->data_n_tsd + l_token->header_private_update.tsd_total_size, + l_certs_field_size, a_hash_out_type); + } break; + case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: { + json_object_object_add(json_obj_datum,"subtype", json_object_new_string("CF20")); + json_object_object_add(json_obj_datum,"decimals", json_object_new_uint64(l_token->header_native_update.decimals)); + json_object_object_add(json_obj_datum,"auth signs valid",json_object_new_uint64(l_token->signs_valid)); + json_object_object_add(json_obj_datum,"auth signs total",json_object_new_uint64(l_token->signs_total)); + json_object_object_add(json_obj_datum,"total_supply",json_object_new_string(dap_uint256_to_char(l_token->total_supply, NULL))); + + json_object_object_add(json_obj_datum,"Flags",json_object_new_string("")); + dap_chain_datum_token_flags_dump_to_json(json_obj_datum, l_token->header_native_update.flags); + dap_datum_token_dump_tsd_to_json(json_obj_datum, l_token, l_token_size, a_hash_out_type); + size_t l_certs_field_size = l_token_size - sizeof(*l_token) - l_token->header_native_update.tsd_total_size; + dap_chain_datum_token_certs_dump_to_json(json_obj_datum, l_token->data_n_tsd + l_token->header_native_update.tsd_total_size, + l_certs_field_size, a_hash_out_type); + } break; + } + } break; + default: + json_object_object_add(json_obj_datum,"type", json_object_new_string("UNKNOWN")); + break; + } + if (l_token->subtype == DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE ) { + json_object_object_add(json_obj_datum,"subtype", json_object_new_string("SIMPLE")); + json_object_object_add(json_obj_datum,"decimals", json_object_new_uint64(l_token->header_simple.decimals)); + json_object_object_add(json_obj_datum,"sign_total", json_object_new_uint64(l_token->signs_total)); + json_object_object_add(json_obj_datum,"sign_valid", json_object_new_uint64(l_token->signs_valid)); + json_object_object_add(json_obj_datum,"total_supply",json_object_new_string(dap_uint256_to_char(l_token->total_supply, NULL))); + + size_t l_certs_field_size = l_token_size - sizeof(*l_token); + dap_chain_datum_token_certs_dump_to_json(json_obj_datum, l_token->data_n_tsd, + l_certs_field_size, a_hash_out_type); + } + DAP_DELETE(l_token); + } break; + case DAP_CHAIN_DATUM_TOKEN_EMISSION: { + size_t l_emission_size = a_datum->header.data_size; + dap_chain_datum_token_emission_t *l_emission = dap_chain_datum_emission_read(a_datum->data, &l_emission_size); + const char *l_coins_str, *l_value_str = dap_uint256_to_char(l_emission->hdr.value, &l_coins_str); + json_object_object_add(json_obj_datum,"emission hash", json_object_new_string(l_hash_str)); + json_object_object_add(json_obj_datum,"coins", json_object_new_string(l_coins_str)); + json_object_object_add(json_obj_datum,"value", json_object_new_string(l_value_str)); + json_object_object_add(json_obj_datum,"ticker", json_object_new_string(l_emission->hdr.ticker)); + json_object_object_add(json_obj_datum,"type", json_object_new_string(c_dap_chain_datum_token_emission_type_str[l_emission->hdr.type])); + json_object_object_add(json_obj_datum,"version", json_object_new_uint64(l_emission->hdr.version)); + json_object_object_add(json_obj_datum,"to addr", json_object_new_string(dap_chain_addr_to_str(&(l_emission->hdr.address)))); + + switch (l_emission->hdr.type) { + case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH: + json_object_object_add(json_obj_datum,"signs_count", json_object_new_uint64(l_emission->data.type_auth.signs_count)); + json_object_object_add(json_obj_datum,"tsd_total_size", json_object_new_uint64(l_emission->data.type_auth.tsd_total_size)); + + if ( ( (void *) l_emission->tsd_n_signs + l_emission->data.type_auth.tsd_total_size) > + ((void *) l_emission + l_emission_size) ) + { + log_it(L_ERROR, "Illformed DATUM type %d, TSD section is out-of-buffer (%" DAP_UINT64_FORMAT_U " vs %zu)", + l_emission->hdr.type, l_emission->data.type_auth.tsd_total_size, l_emission_size); + dap_json_rpc_error_add(-3,"Skip incorrect or illformed DATUM"); + break; + } + dap_chain_datum_token_certs_dump_to_json(json_obj_datum, l_emission->tsd_n_signs + l_emission->data.type_auth.tsd_total_size, + l_emission->data.type_auth.size - l_emission->data.type_auth.tsd_total_size, a_hash_out_type); + break; + case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_ALGO: + json_object_object_add(json_obj_datum,"codename",json_object_new_string(l_emission->data.type_algo.codename)); + break; + case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_SMART_CONTRACT: { + char l_time_str[32]; + char l_flags[50] = {}; + // get time of create datum + if(dap_time_to_str_rfc822(l_time_str, sizeof(l_time_str), l_emission->data.type_presale.lock_time) < 1) + l_time_str[0] = '\0'; + snprintf(l_flags, 50, "0x%x", l_emission->data.type_presale.flags); + json_object_object_add(json_obj_datum,"flags", json_object_new_string(l_flags)); + json_object_object_add(json_obj_datum,"lock_time", json_object_new_string(l_time_str)); + json_object_object_add(json_obj_datum,"addr", json_object_new_string(dap_chain_addr_to_str(&l_emission->data.type_presale.addr))); + } + case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_ATOM_OWNER: + case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_UNDEFINED: + default: + break; + } + DAP_DELETE(l_emission); + } break; + case DAP_CHAIN_DATUM_TX: { + dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*)a_datum->data; + dap_chain_datum_dump_tx_json(l_tx, NULL, json_obj_datum, a_hash_out_type, &l_datum_hash, a_net_id); + } break; + case DAP_CHAIN_DATUM_DECREE:{ + dap_chain_datum_decree_t *l_decree = (dap_chain_datum_decree_t *)a_datum->data; + size_t l_decree_size = dap_chain_datum_decree_get_size(l_decree); + json_object_object_add(json_obj_datum,"=== Datum decree ===",json_object_new_string("empty")); + json_object_object_add(json_obj_datum,"hash",json_object_new_string(l_hash_str)); + json_object_object_add(json_obj_datum,"size",json_object_new_uint64(l_decree_size)); + dap_chain_datum_decree_dump_json(json_obj_datum, l_decree, l_decree_size, a_hash_out_type); + } break; + case DAP_CHAIN_DATUM_ANCHOR:{ + dap_chain_datum_anchor_t *l_anchor = (dap_chain_datum_anchor_t *)a_datum->data; + size_t l_anchor_size = sizeof(dap_chain_datum_anchor_t) + l_anchor->header.data_size + l_anchor->header.signs_size; + json_object_object_add(json_obj_datum,"=== Datum anchor ===",json_object_new_string("empty")); + json_object_object_add(json_obj_datum,"hash",json_object_new_string(l_hash_str)); + json_object_object_add(json_obj_datum,"size",json_object_new_uint64(l_anchor_size)); + dap_hash_fast_t l_decree_hash = { }; + dap_chain_datum_anchor_get_hash_from_data(l_anchor, &l_decree_hash); + l_hash_str = dap_chain_hash_fast_to_str_static(&l_decree_hash); + json_object_object_add(json_obj_datum,"decree hash",json_object_new_string(l_hash_str)); + dap_chain_datum_anchor_certs_dump_json(json_obj_datum,l_anchor->data_n_sign + l_anchor->header.data_size, l_anchor->header.signs_size, a_hash_out_type); + } break; + } + json_object_object_add(a_obj_out,"Datum",json_obj_datum); +} diff --git a/modules/common/dap_chain_datum_anchor.c b/modules/common/dap_chain_datum_anchor.c index 58cdc378b7257a7476c41a29d617a1df3a635b9d..a87618bb02b8308c80bf19bab1b72da2027df42a 100644 --- a/modules/common/dap_chain_datum_anchor.c +++ b/modules/common/dap_chain_datum_anchor.c @@ -90,3 +90,41 @@ void dap_chain_datum_anchor_certs_dump(dap_string_t * a_str_out, byte_t * a_sign dap_sign_type_to_str(l_sign->header.type), l_sign->header.sign_size); } } + +void dap_chain_datum_anchor_certs_dump_json(json_object * a_json_out, byte_t * a_signs, size_t a_certs_size, const char *a_hash_out_type) +{ + json_object_object_add(a_json_out, "signatures", json_object_new_string("")); + if (!a_certs_size) { + json_object_object_add(a_json_out, "Cert status", json_object_new_string("NONE")); + return; + } + json_object* json_arr_certs_out = json_object_new_array(); + size_t l_offset = 0; + for (int i = 1; l_offset < (a_certs_size); i++) { + json_object* json_obj_sign = json_object_new_object(); + dap_sign_t *l_sign = (dap_sign_t*)(a_signs + l_offset); + l_offset += dap_sign_get_size(l_sign); + if (l_sign->header.sign_size == 0) { + json_object_object_add(json_obj_sign, "sign status", json_object_new_string("CORRUPTED - 0 size signature")); + json_object_array_add(json_arr_certs_out, json_obj_sign); + continue; + } + + dap_chain_hash_fast_t l_pkey_hash = {0}; + if (dap_sign_get_pkey_hash(l_sign, &l_pkey_hash) == false) { + json_object_object_add(json_obj_sign, "sign status", json_object_new_string("CORRUPTED - can't calc hash")); + json_object_array_add(json_arr_certs_out, json_obj_sign); + continue; + } + 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); + json_object_object_add(json_obj_sign, "sign #", json_object_new_uint64(i)); + json_object_object_add(json_obj_sign, "hash", json_object_new_string(l_hash_str)); + json_object_object_add(json_obj_sign, "type", json_object_new_string(dap_sign_type_to_str(l_sign->header.type))); + json_object_object_add(json_obj_sign, "sign size", json_object_new_uint64(l_sign->header.sign_size)); + json_object_array_add(json_arr_certs_out, json_obj_sign); + } + json_object_object_add(a_json_out,"SIGNS",json_arr_certs_out); +} + diff --git a/modules/common/dap_chain_datum_decree.c b/modules/common/dap_chain_datum_decree.c index 6920023a493e992d1188653a5ccb0a2d7affe229..951b8d04741fe1cb44eae563481c6f251738c2b1 100644 --- a/modules/common/dap_chain_datum_decree.c +++ b/modules/common/dap_chain_datum_decree.c @@ -41,11 +41,7 @@ dap_sign_t *dap_chain_datum_decree_get_signs(dap_chain_datum_decree_t *a_decree, size_t* a_signs_size) { - if (!a_decree || !a_signs_size) { - log_it(L_CRITICAL, "Invalid arguments"); - return NULL; - } - + dap_return_val_if_fail(a_decree && a_signs_size, NULL); dap_sign_t *l_signs_section = (dap_sign_t*)(a_decree->data_n_signs + a_decree->header.data_size); *a_signs_size = a_decree->header.signs_size; return l_signs_section; @@ -53,29 +49,23 @@ dap_sign_t *dap_chain_datum_decree_get_signs(dap_chain_datum_decree_t *a_decree, int dap_chain_datum_decree_get_fee(dap_chain_datum_decree_t *a_decree, uint256_t *a_fee_value) { - if(!a_decree || !a_fee_value) { - log_it(L_CRITICAL, "Invalid arguments"); - return -1; - } - dap_tsd_t* l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE); - return l_tsd ? ({ _dap_tsd_get_scalar(l_tsd, a_fee_value); 0; }) : 1; + dap_return_val_if_fail(a_decree && a_fee_value, -1); + dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE); + return l_tsd && l_tsd->size == sizeof(uint256_t) ? ({ _dap_tsd_get_scalar(l_tsd, a_fee_value); 0; }) : 1; } int dap_chain_datum_decree_get_value(dap_chain_datum_decree_t *a_decree, uint256_t *a_value) { dap_return_val_if_fail(a_decree && a_value, -1); dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE); - return l_tsd ? ({ _dap_tsd_get_scalar(l_tsd, a_value); 0; }) : 1; + return l_tsd && l_tsd->size == sizeof(uint256_t) ? ({ _dap_tsd_get_scalar(l_tsd, a_value); 0; }) : 1; } int dap_chain_datum_decree_get_fee_addr(dap_chain_datum_decree_t *a_decree, dap_chain_addr_t *a_fee_wallet) { - if(!a_decree || !a_fee_wallet) { - log_it(L_CRITICAL, "Invalid arguments"); - return -1; - } - dap_tsd_t* l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE_WALLET); - return l_tsd ? ({ _dap_tsd_get_scalar(l_tsd, a_fee_wallet); 0; }) : 1; + dap_return_val_if_fail(a_decree && a_fee_wallet, -1); + dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE_WALLET); + return l_tsd && l_tsd->size == sizeof(dap_chain_addr_t) ? ({ _dap_tsd_get_scalar(l_tsd, a_fee_wallet); 0; }) : 1; } static void *s_cb_copy_pkeys(const void *a_pkey, UNUSED_ARG void *a_data) { @@ -84,10 +74,7 @@ static void *s_cb_copy_pkeys(const void *a_pkey, UNUSED_ARG void *a_data) { dap_list_t *dap_chain_datum_decree_get_owners(dap_chain_datum_decree_t *a_decree, uint16_t *a_owners_num) { - if(!a_decree || !a_owners_num){ - log_it(L_CRITICAL, "Invalid arguments"); - return NULL; - } + dap_return_val_if_fail(a_decree && a_owners_num, NULL); dap_list_t *l_tsd_list = dap_tsd_find_all(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_OWNER); *a_owners_num = (uint16_t)dap_list_length(l_tsd_list); dap_list_t *l_ret = dap_list_copy_deep(l_tsd_list, s_cb_copy_pkeys, NULL); @@ -95,77 +82,80 @@ dap_list_t *dap_chain_datum_decree_get_owners(dap_chain_datum_decree_t *a_decree return l_ret; } -int dap_chain_datum_decree_get_min_owners(dap_chain_datum_decree_t *a_decree, uint16_t *a_min_owners_num) +int dap_chain_datum_decree_get_min_owners(dap_chain_datum_decree_t *a_decree, uint256_t *a_min_owners_num) { - if(!a_decree || !a_min_owners_num){ - log_it(L_CRITICAL, "Invalid arguments"); - return -1; - } - dap_tsd_t* l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER); - return l_tsd ? ({ _dap_tsd_get_scalar(l_tsd, a_min_owners_num); 0; }) : 1; + dap_return_val_if_fail(a_decree && a_min_owners_num, -1); + dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER); + return l_tsd && l_tsd->size == sizeof(uint256_t) ? ({ _dap_tsd_get_scalar(l_tsd, a_min_owners_num); 0; }) : 1; } -int dap_chain_datum_decree_get_stake_tx_hash(dap_chain_datum_decree_t *a_decree, dap_hash_fast_t *a_tx_hash) +int dap_chain_datum_decree_get_hash(dap_chain_datum_decree_t *a_decree, dap_hash_fast_t *a_tx_hash) { - if(!a_decree || !a_tx_hash){ - log_it(L_CRITICAL, "Invalid arguments"); - return -1; - } - dap_tsd_t* l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_TX_HASH); - return l_tsd ? ({ _dap_tsd_get_scalar(l_tsd, a_tx_hash); 0; }) : 1; + dap_return_val_if_fail(a_decree && a_tx_hash, -1); + dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HASH); + return l_tsd && l_tsd->size == sizeof(dap_hash_fast_t) ? ({ _dap_tsd_get_scalar(l_tsd, a_tx_hash); 0; }) : 1; } int dap_chain_datum_decree_get_stake_value(dap_chain_datum_decree_t *a_decree, uint256_t *a_stake_value) { - if(!a_decree || !a_stake_value){ - log_it(L_CRITICAL, "Invalid arguments"); - return -1; - } - dap_tsd_t* l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_VALUE); - return l_tsd ? ({ _dap_tsd_get_scalar(l_tsd, a_stake_value); 0; }) : 1; + dap_return_val_if_fail(a_decree && a_stake_value, -1); + dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_VALUE); + return l_tsd && l_tsd->size == sizeof(uint256_t) ? ({ _dap_tsd_get_scalar(l_tsd, a_stake_value); 0; }) : 1; } int dap_chain_datum_decree_get_stake_signing_addr(dap_chain_datum_decree_t *a_decree, dap_chain_addr_t *a_signing_addr) { - if(!a_decree || !a_signing_addr){ - log_it(L_CRITICAL, "Invalid arguments"); - return -1; - } - dap_tsd_t* l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR); - return l_tsd ? ({ _dap_tsd_get_scalar(l_tsd, a_signing_addr); 0; }) : 1; + dap_return_val_if_fail(a_decree && a_signing_addr, -1); + dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR); + return l_tsd && l_tsd->size == sizeof(dap_chain_addr_t) ? ({ _dap_tsd_get_scalar(l_tsd, a_signing_addr); 0; }) : 1; } int dap_chain_datum_decree_get_stake_signer_node_addr(dap_chain_datum_decree_t *a_decree, dap_chain_node_addr_t *a_node_addr) { - if(!a_decree || !a_node_addr){ - log_it(L_CRITICAL, "Invalid arguments"); - return -1; - } - dap_tsd_t* l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNER_NODE_ADDR); - return l_tsd ? ({ _dap_tsd_get_scalar(l_tsd, a_node_addr); 0; }) : 1; + dap_return_val_if_fail(a_decree && a_node_addr, -1); + dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR); + return l_tsd && l_tsd->size == sizeof(dap_chain_node_addr_t) ? ({ _dap_tsd_get_scalar(l_tsd, a_node_addr); 0; }) : 1; } int dap_chain_datum_decree_get_stake_min_value(dap_chain_datum_decree_t *a_decree, uint256_t *a_min_value) { - if(!a_decree || !a_min_value){ - log_it(L_CRITICAL, "Invalid arguments"); - return -1; - } - dap_tsd_t* l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE); - return l_tsd ? ({ _dap_tsd_get_scalar(l_tsd, a_min_value); 0; }) : 1; + dap_return_val_if_fail(a_decree && a_min_value, -1); + dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE); + return l_tsd && l_tsd->size == sizeof(uint256_t) ? ({ _dap_tsd_get_scalar(l_tsd, a_min_value); 0; }) : 1; } int dap_chain_datum_decree_get_stake_min_signers_count(dap_chain_datum_decree_t *a_decree, uint256_t *a_min_signers_count) { - if(!a_decree || !a_min_signers_count){ - log_it(L_CRITICAL, "Invalid arguments"); - return -1; - } - dap_tsd_t* l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT); - return l_tsd ? ({ _dap_tsd_get_scalar(l_tsd, a_min_signers_count); 0; }) : 1; + dap_return_val_if_fail(a_decree && a_min_signers_count, -1); + dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT); + return l_tsd && l_tsd->size == sizeof(uint256_t) ? ({ _dap_tsd_get_scalar(l_tsd, a_min_signers_count); 0; }) : 1; } -void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree_t *a_decree, size_t a_decree_size, const char *a_hash_out_type) { +int dap_chain_datum_decree_get_action(dap_chain_datum_decree_t *a_decree, uint8_t *a_action) +{ + dap_return_val_if_fail(a_decree && a_action, -1); + dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_ACTION); + return l_tsd && l_tsd->size == sizeof(uint8_t) ? ({ _dap_tsd_get_scalar(l_tsd, a_action); 0; }) : 1; +} + +int dap_chain_datum_decree_get_signature_type(dap_chain_datum_decree_t *a_decree, uint32_t *a_signature_type) +{ + dap_return_val_if_fail(a_decree && a_signature_type, -1); + dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGNATURE_TYPE); + return l_tsd && l_tsd->size == sizeof(uint32_t) ? ({ _dap_tsd_get_scalar(l_tsd, a_signature_type); 0; }) : 1; +} + +int dap_chain_datum_decree_get_ban_addr(dap_chain_datum_decree_t *a_decree, const char **a_addr) +{ + dap_return_val_if_fail(a_decree && a_addr, -1); + dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST); + if (!l_tsd) + l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STRING); + return l_tsd ? ({ *a_addr = dap_tsd_get_string_const(l_tsd); !dap_strcmp(*a_addr, DAP_TSD_CORRUPTED_STRING); }) : 1; +} + +void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree_t *a_decree, size_t a_decree_size, const char *a_hash_out_type) +{ char *l_type_str = ""; switch(a_decree->header.type) { @@ -193,7 +183,7 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree } uint256_t l_value = uint256_0; _dap_tsd_get_scalar(l_tsd, &l_value); - char *l_value_str = dap_uint256_to_char(l_value, NULL); + const char *l_value_str = dap_uint256_to_char(l_value, NULL); dap_string_append_printf(a_str_out, "\tValue: %s\n", l_value_str); break; case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN: @@ -205,7 +195,7 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree } uint256_t l_fee_value = uint256_0; _dap_tsd_get_scalar(l_tsd, &l_fee_value); - char *l_fee_value_str = dap_uint256_to_char(l_fee_value, NULL); + const char *l_fee_value_str = dap_uint256_to_char(l_fee_value, NULL); dap_string_append_printf(a_str_out, "\tFee: %s\n", l_fee_value_str); break; case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_OWNER: @@ -220,13 +210,13 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree dap_string_append_printf(a_str_out, "\tOwner fingerprint: %s\n", l_owner_pkey_str); break; case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER: - if (l_tsd->size > sizeof(uint256_t)){ + if (l_tsd->size != sizeof(uint32_t)){ dap_string_append_printf(a_str_out, "\tOwner min: <WRONG SIZE>\n"); break; } uint256_t l_owner_min = uint256_0; _dap_tsd_get_scalar(l_tsd, &l_owner_min); - char *l_owner_min_str = dap_uint256_to_char(l_owner_min, NULL); + const char *l_owner_min_str = dap_uint256_to_char(l_owner_min, NULL); dap_string_append_printf(a_str_out, "\tOwner min: %s\n", l_owner_min_str); break; case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE_WALLET: @@ -238,9 +228,9 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree _dap_tsd_get_scalar(l_tsd, &l_addr_fee_wallet);*/ _dap_tsd_get_object(l_tsd, dap_chain_addr_t); dap_string_append_printf(a_str_out, "\tWallet for fee: %s\n", dap_chain_addr_to_str(l_addr_fee_wallet)); break; - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_TX_HASH: + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HASH: if (l_tsd->size > sizeof(dap_hash_fast_t)) { - dap_string_append_printf(a_str_out, "\tStake tx: <WRONG SIZE>\n"); + dap_string_append_printf(a_str_out, "\tHash: <WRONG SIZE>\n"); break; } dap_hash_fast_t *l_stake_tx = /*{ }; @@ -248,7 +238,7 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree 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); + dap_string_append_printf(a_str_out, "\tHash: %s\n", l_stake_tx_hash); break; case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_VALUE: if (l_tsd->size > sizeof(uint256_t)){ @@ -257,7 +247,7 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree } uint256_t l_stake_value = uint256_0; _dap_tsd_get_scalar(l_tsd, &l_stake_value); - char *l_stake_value_str = dap_uint256_to_char(l_stake_value, NULL); + const char *l_stake_value_str = dap_uint256_to_char(l_stake_value, NULL); dap_string_append_printf(a_str_out, "\tStake value: %s\n", l_stake_value_str); break; case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR: @@ -274,7 +264,7 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree : 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); break; - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNER_NODE_ADDR: + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR: if(l_tsd->size > sizeof(dap_chain_node_addr_t)){ dap_string_append_printf(a_str_out, "\tNode addr: <WRONG SIZE>\n"); break; @@ -290,7 +280,7 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree } uint256_t l_min_value = uint256_0; _dap_tsd_get_scalar(l_tsd, &l_min_value); - char *l_min_value_str = dap_uint256_to_char(l_min_value, NULL); + const char *l_min_value_str = dap_uint256_to_char(l_min_value, NULL); dap_string_append_printf(a_str_out, "\tMin value: %s\n", l_min_value_str); break; case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT: @@ -300,13 +290,32 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree } uint256_t l_min_signers_count = uint256_0; _dap_tsd_get_scalar(l_tsd, &l_min_signers_count); - char *l_min_signers_count_str = dap_uint256_to_char(l_min_signers_count, NULL); + const char *l_min_signers_count_str = dap_uint256_to_char(l_min_signers_count, NULL); dap_string_append_printf(a_str_out, "\tMin signers count: %s\n", l_min_signers_count_str); break; case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST: - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR: { - dap_string_append_printf(a_str_out, "\tNode address: %s\n", dap_tsd_get_string(l_tsd)); - } break; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STRING: + dap_string_append_printf(a_str_out, "\tHost address: %s\n", dap_tsd_get_string(l_tsd)); + break; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_ACTION: + if (l_tsd->size != sizeof(uint8_t)){ + dap_string_append_printf(a_str_out, "\tAction: <WRONG SIZE>\n"); + break; + } + uint8_t l_action = 0; + _dap_tsd_get_scalar(l_tsd, &l_action); + dap_string_append_printf(a_str_out, "\tAction: %s\n", l_action ? "add (enable)" : "delete (disable)"); + break; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGNATURE_TYPE: + if (l_tsd->size != sizeof(uint32_t)){ + dap_string_append_printf(a_str_out, "\tSignature type: <WRONG SIZE>\n"); + break; + } + uint32_t l_type = 0; + _dap_tsd_get_scalar(l_tsd, &l_type); + dap_sign_type_t l_sign_type = { .type = l_type }; + dap_string_append_printf(a_str_out, "\tSignature type: %s\n", dap_sign_type_to_str(l_sign_type)); + break; default: dap_string_append_printf(a_str_out, "\t<UNKNOWN_TYPE_TSD_SECTION>\n"); break; @@ -349,30 +358,263 @@ void dap_chain_datum_decree_certs_dump(dap_string_t * a_str_out, byte_t * a_sign } } -dap_chain_datum_decree_t* dap_chain_datum_decree_sign_in_cycle(dap_cert_t ** a_certs, dap_chain_datum_decree_t *a_datum_decree, +void dap_chain_datum_decree_dump_json(json_object *a_json_out, dap_chain_datum_decree_t *a_decree, size_t a_decree_size, const char *a_hash_out_type) +{ + char *l_type_str = ""; + char l_tmp_buff[70]={0}; + switch(a_decree->header.type) + { + case DAP_CHAIN_DATUM_DECREE_TYPE_COMMON: + l_type_str = "DECREE_TYPE_COMMON"; + break; + case DAP_CHAIN_DATUM_DECREE_TYPE_SERVICE: + l_type_str = "DECREE_TYPE_SERVICE"; + break; + default: + l_type_str = "DECREE_TYPE_UNKNOWN"; + } + json_object_object_add(a_json_out, "type", json_object_new_string(l_type_str)); + const char *l_subtype_str = dap_chain_datum_decree_subtype_to_str(a_decree->header.sub_type); + json_object_object_add(a_json_out, "subtype", json_object_new_string(l_subtype_str)); + json_object_object_add(a_json_out, "TSD", json_object_new_string("")); + for (size_t l_offset = 0; l_offset < a_decree->header.data_size;) { + dap_tsd_t *l_tsd = (dap_tsd_t *)((byte_t*)a_decree->data_n_signs + l_offset); + l_offset += dap_tsd_size(l_tsd); + switch(l_tsd->type) { + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE: + if (l_tsd->size > sizeof(uint256_t)){ + json_object_object_add(a_json_out, "Value", json_object_new_string("WRONG SIZE")); + break; + } + uint256_t l_value = uint256_0; + _dap_tsd_get_scalar(l_tsd, &l_value); + const char *l_value_str = dap_uint256_to_char(l_value, NULL); + json_object_object_add(a_json_out, "Value", json_object_new_string(l_value_str)); + break; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN: + break; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE: + if (l_tsd->size > sizeof(uint256_t)){ + json_object_object_add(a_json_out, "Fee", json_object_new_string("WRONG SIZE")); + break; + } + uint256_t l_fee_value = uint256_0; + _dap_tsd_get_scalar(l_tsd, &l_fee_value); + const char *l_fee_value_str = dap_uint256_to_char(l_fee_value, NULL); + json_object_object_add(a_json_out, "Fee", json_object_new_string(l_fee_value_str)); + break; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_OWNER: + if (l_tsd->size < sizeof(dap_pkey_t)) { + json_object_object_add(a_json_out, "Owner fingerprint", json_object_new_string("WRONG SIZE")); + break; + } + dap_pkey_t *l_owner_pkey = /*DAP_NEW_STACK_SIZE(dap_pkey_t, l_tsd->size); + memcpy(l_owner_pkey, l_tsd->data, l_tsd->size);*/ _dap_tsd_get_object(l_tsd, dap_pkey_t); + char *l_owner_pkey_str; + dap_get_data_hash_str_static(l_owner_pkey->pkey, l_owner_pkey->header.size, l_owner_pkey_str); + json_object_object_add(a_json_out, "Owner fingerprint", json_object_new_string(l_owner_pkey_str)); + break; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER: + if (l_tsd->size > sizeof(uint256_t)){ + json_object_object_add(a_json_out, "Owner min", json_object_new_string("WRONG SIZE")); + break; + } + uint256_t l_owner_min = uint256_0; + _dap_tsd_get_scalar(l_tsd, &l_owner_min); + const char *l_owner_min_str = dap_uint256_to_char(l_owner_min, NULL); + json_object_object_add(a_json_out, "Owner min", json_object_new_string(l_owner_min_str)); + break; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE_WALLET: + if (l_tsd->size > sizeof(dap_chain_addr_t)) { + json_object_object_add(a_json_out, "Wallet for fee", json_object_new_string("WRONG SIZE")); + break; + } + dap_chain_addr_t *l_addr_fee_wallet = /*{ }; + _dap_tsd_get_scalar(l_tsd, &l_addr_fee_wallet);*/ _dap_tsd_get_object(l_tsd, dap_chain_addr_t); + json_object_object_add(a_json_out, "Wallet for fee", json_object_new_string(dap_chain_addr_to_str(l_addr_fee_wallet))); + break; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HASH: + if (l_tsd->size > sizeof(dap_hash_fast_t)) { + json_object_object_add(a_json_out, "Stake tx", json_object_new_string("WRONG SIZE")); + break; + } + 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); + 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); + json_object_object_add(a_json_out, "Stake tx", json_object_new_string(l_stake_tx_hash)); + break; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_VALUE: + if (l_tsd->size > sizeof(uint256_t)){ + json_object_object_add(a_json_out, "Stake value", json_object_new_string("WRONG SIZE")); + break; + } + uint256_t l_stake_value = uint256_0; + _dap_tsd_get_scalar(l_tsd, &l_stake_value); + const char *l_stake_value_str = dap_uint256_to_char(l_stake_value, NULL); + json_object_object_add(a_json_out, "Stake value", json_object_new_string(l_stake_value_str)); + break; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR: + if (l_tsd->size > sizeof(dap_chain_addr_t)) { + json_object_object_add(a_json_out, "Signing addr", json_object_new_string("WRONG SIZE")); + break; + } + dap_chain_addr_t *l_stake_addr_signing = /*{ }; + _dap_tsd_get_scalar(l_tsd, &l_stake_addr_signing);*/ _dap_tsd_get_object(l_tsd, dap_chain_addr_t); + json_object_object_add(a_json_out, "Signing addr", json_object_new_string(dap_chain_addr_to_str(l_stake_addr_signing))); + dap_chain_hash_fast_t l_pkey_signing = l_stake_addr_signing->data.hash_fast; + 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); + json_object_object_add(a_json_out, "Signing pkey fingerprint", json_object_new_string(l_pkey_signing_str)); + break; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR: + if(l_tsd->size > sizeof(dap_chain_node_addr_t)){ + json_object_object_add(a_json_out, "Node addr", json_object_new_string("WRONG SIZE")); + break; + } + dap_chain_node_addr_t *l_node_addr = _dap_tsd_get_object(l_tsd, dap_chain_node_addr_t); + sprintf(l_tmp_buff, NODE_ADDR_FP_STR, NODE_ADDR_FP_ARGS(l_node_addr)); + json_object_object_add(a_json_out, "Node addr", json_object_new_string(l_tmp_buff)); + break; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE: + if (l_tsd->size > sizeof(uint256_t)) { + json_object_object_add(a_json_out, "Min value", json_object_new_string("WRONG SIZE")); + break; + } + uint256_t l_min_value = uint256_0; + _dap_tsd_get_scalar(l_tsd, &l_min_value); + const char *l_min_value_str = dap_uint256_to_char(l_min_value, NULL); + json_object_object_add(a_json_out, "Min value", json_object_new_string(l_min_value_str)); + break; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT: + if (l_tsd->size > sizeof(uint256_t)) { + json_object_object_add(a_json_out, "Min signers count", json_object_new_string("WRONG SIZE")); + break; + } + uint256_t l_min_signers_count = uint256_0; + _dap_tsd_get_scalar(l_tsd, &l_min_signers_count); + const char *l_min_signers_count_str = dap_uint256_to_char(l_min_signers_count, NULL); + json_object_object_add(a_json_out, "Min signers count", json_object_new_string(l_min_signers_count_str)); + break; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST: + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STRING: + json_object_object_add(a_json_out, "Host address", json_object_new_string(dap_tsd_get_string(l_tsd))); + break; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_ACTION: + if (l_tsd->size != sizeof(uint8_t)) { + json_object_object_add(a_json_out, "Action", json_object_new_string("WRONG SIZE")); + break; + } + uint8_t l_action = 0; + _dap_tsd_get_scalar(l_tsd, &l_action); + json_object_object_add(a_json_out, "tAction", l_action ? + json_object_new_string("add (enable)") : json_object_new_string("delete (disable)")); + break; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGNATURE_TYPE: + if (l_tsd->size != sizeof(uint32_t)) { + json_object_object_add(a_json_out, "Signature type", json_object_new_string("WRONG SIZE")); + break; + } + uint32_t l_type = 0; + _dap_tsd_get_scalar(l_tsd, &l_type); + dap_sign_type_t l_sign_type = { .type = l_type }; + json_object_object_add(a_json_out, "Signature type", json_object_new_string(dap_sign_type_to_str(l_sign_type))); + break; + default: + json_object_object_add(a_json_out, "UNKNOWN_TYPE_TSD_SECTION", json_object_new_string("")); + break; + } + } + dap_chain_datum_decree_certs_dump_json(a_json_out, a_decree->data_n_signs + a_decree->header.data_size, + a_decree->header.signs_size, a_hash_out_type); +} + +void dap_chain_datum_decree_certs_dump_json(json_object * a_json_out, byte_t * a_signs, size_t a_certs_size, const char *a_hash_out_type) +{ + json_object_object_add(a_json_out, "signatures", json_object_new_string("")); + if (!a_certs_size) { + json_object_object_add(a_json_out, "Cert status", json_object_new_string("NONE")); + return; + } + json_object* json_arr_certs_out = json_object_new_array(); + size_t l_offset = 0; + for (int i = 1; l_offset < (a_certs_size); i++) { + json_object* json_obj_sign = json_object_new_object(); + dap_sign_t *l_sign = (dap_sign_t *) (a_signs + l_offset); + l_offset += dap_sign_get_size(l_sign); + if (l_sign->header.sign_size == 0) { + json_object_object_add(json_obj_sign, "sign status", json_object_new_string("CORRUPTED - 0 size signature")); + json_object_array_add(json_arr_certs_out, json_obj_sign); + continue; + } + + dap_chain_hash_fast_t l_pkey_hash = {0}; + if (dap_sign_get_pkey_hash(l_sign, &l_pkey_hash) == false) { + json_object_object_add(json_obj_sign, "sign status", json_object_new_string("CORRUPTED - can't calc hash")); + json_object_array_add(json_arr_certs_out, json_obj_sign); + continue; + } + + 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); + json_object_object_add(json_obj_sign, "sign #", json_object_new_uint64(i)); + json_object_object_add(json_obj_sign, "hash", json_object_new_string(l_hash_str)); + json_object_object_add(json_obj_sign, "type", json_object_new_string(dap_sign_type_to_str(l_sign->header.type))); + json_object_object_add(json_obj_sign, "sign size", json_object_new_uint64(l_sign->header.sign_size)); + json_object_array_add(json_arr_certs_out, json_obj_sign); + } + json_object_object_add(a_json_out,"SIGNS", json_arr_certs_out); +} + +dap_chain_datum_decree_t *dap_chain_datum_decree_new(dap_chain_net_id_t a_net_id, dap_chain_id_t a_chain_id, + dap_chain_cell_id_t a_cell_id, size_t a_total_tsd_size) +{ + dap_chain_datum_decree_t *l_decree = NULL; + DAP_NEW_Z_SIZE_RET_VAL(l_decree, dap_chain_datum_decree_t, sizeof(dap_chain_datum_decree_t) + a_total_tsd_size, NULL, NULL); + + l_decree->decree_version = DAP_CHAIN_DATUM_DECREE_VERSION; + l_decree->header.ts_created = dap_time_now(); + l_decree->header.type = DAP_CHAIN_DATUM_DECREE_TYPE_COMMON; + l_decree->header.common_decree_params.net_id = a_net_id; + l_decree->header.common_decree_params.chain_id = a_chain_id; + l_decree->header.common_decree_params.cell_id = a_cell_id; + l_decree->header.data_size = a_total_tsd_size; + return l_decree; +} + +dap_chain_datum_decree_t *dap_chain_datum_decree_sign_in_cycle(dap_cert_t **a_certs, dap_chain_datum_decree_t *a_datum_decree, size_t a_certs_count, size_t *a_total_sign_count) { size_t l_cur_sign_offset = a_datum_decree->header.data_size + a_datum_decree->header.signs_size; size_t l_total_signs_size = a_datum_decree->header.signs_size, l_total_sign_count = 0; - for(size_t i = 0; i < a_certs_count; i++) - { - dap_sign_t * l_sign = dap_cert_sign(a_certs[i], a_datum_decree, + for(size_t i = 0; i < a_certs_count; i++) { + dap_sign_t * l_sign = dap_cert_sign(a_certs[i], a_datum_decree, sizeof(dap_chain_datum_decree_t) + a_datum_decree->header.data_size, 0); - - if (l_sign) { - size_t l_sign_size = dap_sign_get_size(l_sign); - a_datum_decree = DAP_REALLOC(a_datum_decree, sizeof(dap_chain_datum_decree_t) + l_cur_sign_offset + l_sign_size); - memcpy((byte_t*)a_datum_decree->data_n_signs + l_cur_sign_offset, l_sign, l_sign_size); - l_total_signs_size += l_sign_size; - l_cur_sign_offset += l_sign_size; - a_datum_decree->header.signs_size = l_total_signs_size; + if (!l_sign) { + log_it(L_ERROR, "Decree signing failed"); + DAP_DELETE(a_datum_decree); + return NULL; + } + size_t l_sign_size = dap_sign_get_size(l_sign); + a_datum_decree = DAP_REALLOC(a_datum_decree, sizeof(dap_chain_datum_decree_t) + l_cur_sign_offset + l_sign_size); + if (!a_datum_decree) { + log_it(L_CRITICAL, "%s", g_error_memory_alloc); DAP_DELETE(l_sign); - log_it(L_DEBUG,"<-- Signed with '%s'", a_certs[i]->name); - l_total_sign_count++; + return NULL; } + memcpy(a_datum_decree->data_n_signs + l_cur_sign_offset, l_sign, l_sign_size); + DAP_DELETE(l_sign); + l_total_signs_size += l_sign_size; + l_cur_sign_offset += l_sign_size; + a_datum_decree->header.signs_size = l_total_signs_size; + log_it(L_DEBUG,"<-- Signed with '%s'", a_certs[i]->name); + l_total_sign_count++; } - - *a_total_sign_count = l_total_sign_count; + if (a_total_sign_count) + *a_total_sign_count = l_total_sign_count; return a_datum_decree; } diff --git a/modules/common/dap_chain_datum_tx_items.c b/modules/common/dap_chain_datum_tx_items.c index 83b2c2cb79586aaa8664531515fa99cd92742aa9..6f5b32842a2ad59997ee77c6532bf514e14674ae 100644 --- a/modules/common/dap_chain_datum_tx_items.c +++ b/modules/common/dap_chain_datum_tx_items.c @@ -34,6 +34,7 @@ #include "dap_chain_datum_tx_items.h" #include "dap_chain_datum_tx_voting.h" +#define LOG_TAG "dap_chain_datum_tx_items" static size_t dap_chain_tx_in_get_size(const dap_chain_tx_in_t *a_item) { @@ -696,3 +697,152 @@ uint8_t *dap_chain_datum_tx_out_get_by_out_idx(dap_chain_datum_tx_t *a_tx, int a return l_ret; } + +void dap_chain_datum_tx_group_items_free( dap_chain_datum_tx_item_groups_t *a_items_groups) +{ + if (a_items_groups->items_in) dap_list_free(a_items_groups->items_in); + if (a_items_groups->items_in_cond) dap_list_free(a_items_groups->items_in_cond); + if (a_items_groups->items_in_reward) dap_list_free(a_items_groups->items_in_reward); + if (a_items_groups->items_sig) dap_list_free(a_items_groups->items_sig); + if (a_items_groups->items_out) dap_list_free(a_items_groups->items_out); + if (a_items_groups->items_out_ext) dap_list_free(a_items_groups->items_out_ext); + if (a_items_groups->items_out_cond) dap_list_free(a_items_groups->items_out_cond); + if (a_items_groups->items_out_cond_srv_fee) dap_list_free(a_items_groups->items_out_cond_srv_fee); + if (a_items_groups->items_out_cond_srv_pay) dap_list_free(a_items_groups->items_out_cond_srv_pay); + if (a_items_groups->items_out_cond_srv_xchange) dap_list_free(a_items_groups->items_out_cond_srv_xchange); + if (a_items_groups->items_out_cond_srv_stake_pos_delegate) dap_list_free(a_items_groups->items_out_cond_srv_stake_pos_delegate); + if (a_items_groups->items_out_cond_srv_stake_lock) dap_list_free(a_items_groups->items_out_cond_srv_stake_lock); + if (a_items_groups->items_in_ems) dap_list_free(a_items_groups->items_in_ems); + if (a_items_groups->items_vote) dap_list_free(a_items_groups->items_vote); + if (a_items_groups->items_voting) dap_list_free(a_items_groups->items_voting); + if (a_items_groups->items_tsd) dap_list_free(a_items_groups->items_tsd); + if (a_items_groups->items_pkey) dap_list_free(a_items_groups->items_pkey); + if (a_items_groups->items_receipt) dap_list_free(a_items_groups->items_receipt); + if (a_items_groups->items_unknown) dap_list_free(a_items_groups->items_unknown); + if (a_items_groups->items_out_old) dap_list_free(a_items_groups->items_out_old); + if (a_items_groups->items_out_cond_unknonwn) dap_list_free(a_items_groups->items_out_cond_unknonwn); + if (a_items_groups->items_out_cond_undefined) dap_list_free(a_items_groups->items_out_cond_undefined); + if (a_items_groups->items_out_all) dap_list_free(a_items_groups->items_out_all); + if (a_items_groups->items_in_all) dap_list_free(a_items_groups->items_in_all); +} + +#define DAP_LIST_SAPPEND(X, Y) X = dap_list_append(X,Y) +bool dap_chain_datum_tx_group_items(dap_chain_datum_tx_t *a_tx, dap_chain_datum_tx_item_groups_t *a_res_group) +{ + + if(!a_tx || !a_res_group) + return NULL; + + uint32_t l_tx_items_pos = 0, l_tx_items_size = a_tx->header.tx_items_size; + + int l_item_idx = 0; + + while (l_tx_items_pos < l_tx_items_size) { + + uint8_t *l_item = a_tx->tx_items + l_tx_items_pos; + int l_item_size = dap_chain_datum_item_tx_get_size(l_item); + + if(!l_item_size) + return false; + + dap_chain_tx_item_type_t l_type = dap_chain_datum_tx_item_get_type(l_item); + + switch (l_type) + { + case TX_ITEM_TYPE_IN: + DAP_LIST_SAPPEND(a_res_group->items_in, l_item); + DAP_LIST_SAPPEND(a_res_group->items_in_all, l_item); + break; + + case TX_ITEM_TYPE_IN_COND: + DAP_LIST_SAPPEND(a_res_group->items_in_cond, l_item); + DAP_LIST_SAPPEND(a_res_group->items_in_all, l_item); + break; + + case TX_ITEM_TYPE_IN_REWARD: + DAP_LIST_SAPPEND(a_res_group->items_in_reward, l_item); + DAP_LIST_SAPPEND(a_res_group->items_in_all, l_item); + break; + + case TX_ITEM_TYPE_IN_EMS: + DAP_LIST_SAPPEND(a_res_group->items_in_ems, l_item); + DAP_LIST_SAPPEND(a_res_group->items_in_all, l_item); + break; + + case TX_ITEM_TYPE_OUT_OLD: + DAP_LIST_SAPPEND(a_res_group->items_out_old, l_item); + DAP_LIST_SAPPEND(a_res_group->items_out_all, l_item); + break; + + case TX_ITEM_TYPE_OUT_EXT: + DAP_LIST_SAPPEND(a_res_group->items_out_ext, l_item); + DAP_LIST_SAPPEND(a_res_group->items_out_all, l_item); + break; + + case TX_ITEM_TYPE_OUT: + DAP_LIST_SAPPEND(a_res_group->items_out, l_item); + DAP_LIST_SAPPEND(a_res_group->items_out_all, l_item); + break; + + case TX_ITEM_TYPE_OUT_COND: { + switch ( ((dap_chain_tx_out_cond_t *)l_item)->header.subtype ) + { + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_UNDEFINED: + DAP_LIST_SAPPEND(a_res_group->items_out_cond_undefined, l_item); + break; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY: + DAP_LIST_SAPPEND(a_res_group->items_out_cond_srv_pay, l_item); + break; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE: + DAP_LIST_SAPPEND(a_res_group->items_out_cond_srv_xchange, l_item); + break; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE: + DAP_LIST_SAPPEND(a_res_group->items_out_cond_srv_stake_pos_delegate, l_item); + break; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE: + DAP_LIST_SAPPEND(a_res_group->items_out_cond_srv_fee, l_item); + break; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK: + DAP_LIST_SAPPEND(a_res_group->items_out_cond_srv_stake_lock, l_item); + break; + default: + DAP_LIST_SAPPEND(a_res_group->items_out_cond_unknonwn, l_item); + break; + } + + DAP_LIST_SAPPEND(a_res_group->items_out_cond, l_item); + DAP_LIST_SAPPEND(a_res_group->items_out_all, l_item); + } + break; + + case TX_ITEM_TYPE_PKEY: + DAP_LIST_SAPPEND(a_res_group->items_pkey, l_item); + break; + case TX_ITEM_TYPE_SIG: + DAP_LIST_SAPPEND(a_res_group->items_sig, l_item); + break; + case TX_ITEM_TYPE_RECEIPT: + DAP_LIST_SAPPEND(a_res_group->items_receipt, l_item); + break; + case TX_ITEM_TYPE_TSD: + DAP_LIST_SAPPEND(a_res_group->items_tsd, l_item); + break; + + case TX_ITEM_TYPE_VOTING: + DAP_LIST_SAPPEND(a_res_group->items_voting, l_item); + break; + + case TX_ITEM_TYPE_VOTE: + DAP_LIST_SAPPEND(a_res_group->items_vote, l_item); + break; + default: + DAP_LIST_SAPPEND(a_res_group->items_unknown, l_item); + } + + l_tx_items_pos += l_item_size; + l_item_idx++; + } + + return true; + +} diff --git a/modules/common/include/dap_chain_common.h b/modules/common/include/dap_chain_common.h index fe9cebf3cc00646789cb6f1b5ecf23ba3e1d967c..a6e9143468133b9c46045e0af2ee24082f0f2550 100644 --- a/modules/common/include/dap_chain_common.h +++ b/modules/common/include/dap_chain_common.h @@ -30,10 +30,8 @@ #include "dap_math_ops.h" #include "dap_math_convert.h" #include "dap_enc_key.h" -#include "dap_pkey.h" #include "dap_sign.h" #include "dap_hash.h" -#include "json.h" #include "dap_strfuncs.h" #define DAP_CHAIN_ADDR_VERSION_CURRENT 1 @@ -200,7 +198,7 @@ extern "C" { size_t dap_chain_hash_slow_to_str(dap_chain_hash_slow_t * a_hash, char * a_str, size_t a_str_max); -char* dap_chain_addr_to_str(const dap_chain_addr_t *a_addr); +const char *dap_chain_addr_to_str(const dap_chain_addr_t *a_addr); dap_chain_addr_t* dap_chain_addr_from_str(const char *str); bool dap_chain_addr_is_blank(const dap_chain_addr_t *a_addr); diff --git a/modules/common/include/dap_chain_datum.h b/modules/common/include/dap_chain_datum.h index c3be81a88aeea7a52b0a01a1d98a3ccd6aabb8da..d9df56a67ef7a469df6992b15ecc4eff0aec3bc7 100644 --- a/modules/common/include/dap_chain_datum.h +++ b/modules/common/include/dap_chain_datum.h @@ -25,11 +25,9 @@ #pragma once #include <stdint.h> #include "dap_common.h" -#include "dap_math_ops.h" #include "dap_chain_common.h" #include "dap_chain_datum_tx.h" #include "dap_chain_datum_token.h" -#include "json.h" #define DAP_CHAIN_DATUM_VERSION 0x00 @@ -162,4 +160,11 @@ bool dap_chain_datum_dump_tx(dap_chain_datum_tx_t *a_datum, const char *a_hash_out_type, dap_hash_fast_t *a_tx_hash, dap_chain_net_id_t a_net_id); +bool dap_chain_datum_dump_tx_json(dap_chain_datum_tx_t *a_datum, + const char *a_ticker, + json_object* json_obj_out, + const char *a_hash_out_type, + dap_hash_fast_t *a_tx_hash, + dap_chain_net_id_t a_net_id); json_object * dap_chain_datum_to_json(dap_chain_datum_t* a_datum); +void dap_chain_datum_dump_json(json_object *a_obj_out, dap_chain_datum_t *a_datum, const char *a_hash_out_type, dap_chain_net_id_t a_net_id); diff --git a/modules/common/include/dap_chain_datum_anchor.h b/modules/common/include/dap_chain_datum_anchor.h index 044b8165f68ac20636796a08fb6da920556c9d23..16c1ab915990752fbdae51a3851f621c2981dda8 100644 --- a/modules/common/include/dap_chain_datum_anchor.h +++ b/modules/common/include/dap_chain_datum_anchor.h @@ -51,3 +51,5 @@ DAP_STATIC_INLINE size_t dap_chain_datum_anchor_get_size(dap_chain_datum_anchor_ int dap_chain_datum_anchor_get_hash_from_data(dap_chain_datum_anchor_t* a_anchor, dap_hash_fast_t * l_out_hash); void dap_chain_datum_anchor_certs_dump(dap_string_t * a_str_out, byte_t * a_signs, size_t a_certs_size, const char *a_hash_out_type); + +void dap_chain_datum_anchor_certs_dump_json(json_object * a_json_out, byte_t * a_signs, size_t a_certs_size, const char *a_hash_out_type); diff --git a/modules/common/include/dap_chain_datum_decree.h b/modules/common/include/dap_chain_datum_decree.h index 42964d99c508c3717876134c261584b57ca79b77..f8f40ea74fbd7f417d455d0f3b3f7729d280890a 100644 --- a/modules/common/include/dap_chain_datum_decree.h +++ b/modules/common/include/dap_chain_datum_decree.h @@ -26,7 +26,6 @@ #include "dap_math_ops.h" #include "dap_time.h" #include "dap_list.h" -#include "dap_tsd.h" #include "dap_cert.h" #include <stdint.h> @@ -73,6 +72,9 @@ DAP_STATIC_INLINE size_t dap_chain_datum_decree_get_size(dap_chain_datum_decree_ #define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_BAN 0x0009 #define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_UNBAN 0x000A #define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_REWARD 0x000B +#define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_MAX_WEIGHT 0x000C +#define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_EMERGENCY_VALIDATORS 0x000D +#define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_CHECK_SIGNS_STRUCTURE 0x000E // DECREE TSD types #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE 0x0100 @@ -81,14 +83,16 @@ DAP_STATIC_INLINE size_t dap_chain_datum_decree_get_size(dap_chain_datum_decree_ #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_OWNER 0x0103 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER 0x0104 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE_WALLET 0x0106 -#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_TX_HASH 0x0107 +#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HASH 0x0107 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_VALUE 0x0108 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR 0x0109 -#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNER_NODE_ADDR 0x0110 +#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR 0x0110 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE 0x0111 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT 0x0112 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST 0x0113 -#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR 0x0115 +#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STRING 0x0115 +#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_ACTION 0x010A +#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGNATURE_TYPE 0x010B DAP_STATIC_INLINE const char *dap_chain_datum_decree_subtype_to_str(uint16_t a_decree_subtype) { @@ -113,6 +117,12 @@ DAP_STATIC_INLINE const char *dap_chain_datum_decree_subtype_to_str(uint16_t a_d return "DECREE_COMMON_SUBTYPE_UNBAN"; case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_REWARD: return "DECREE_COMMON_SUBTYPE_REWARD"; + case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_MAX_WEIGHT: + return "DECREE_COMMON_SUBTYPE_VALIDATOR_MAX_WEIGHT"; + case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_EMERGENCY_VALIDATORS: + return "DECREE_COMMON_SUBTYPE_EMERGENCY_VALIDATORS"; + case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_CHECK_SIGNS_STRUCTURE: + return "DECREE_COMMON_SUBTYPE_CHECK_SIGNS_STRUCTURE"; default: return "DECREE_SUBTYPE_UNKNOWN"; } @@ -120,39 +130,45 @@ DAP_STATIC_INLINE const char *dap_chain_datum_decree_subtype_to_str(uint16_t a_d DAP_STATIC_INLINE const char *dap_chain_datum_decree_tsd_type_to_str(uint16_t a_decree_tsd_type) { switch (a_decree_tsd_type) { - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE: - return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE"; - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN: - return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN"; - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE: - return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE"; - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_OWNER: - return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_OWNER"; - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER: - return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER"; - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE_WALLET: - return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE_WALLET"; - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_TX_HASH: - return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_TX_HASH"; - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_VALUE: - return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_VALUE"; - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR: - return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR"; - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNER_NODE_ADDR: - return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNER_NODE_ADDR"; - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE: - return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE"; - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT: - return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT"; - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST: - return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST"; - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR: - return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR"; - default: - return "DECREE_TSD_TYPE_UNKNOWN"; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE: + return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE"; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN: + return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN"; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE: + return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE"; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_OWNER: + return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_OWNER"; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER: + return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER"; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE_WALLET: + return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE_WALLET"; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HASH: + return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HASH"; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_VALUE: + return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_VALUE"; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR: + return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR"; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR: + return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR"; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE: + return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE"; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT: + return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT"; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST: + return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST"; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STRING: + return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STRING"; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_ACTION: + return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_ACTION"; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGNATURE_TYPE: + return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGNATURE_TYPE"; + default: + return "DECREE_TSD_TYPE_UNKNOWN"; } } +dap_chain_datum_decree_t *dap_chain_datum_decree_new(dap_chain_net_id_t a_net_id, dap_chain_id_t a_chain_id, + dap_chain_cell_id_t a_cell_id, size_t a_total_tsd_size); /** * @brief dap_chain_datum_decree_get_signs * @param decree pointer to decree @@ -192,7 +208,7 @@ dap_list_t *dap_chain_datum_decree_get_owners(dap_chain_datum_decree_t *a_decree * @param a_owners_num pointer to minimum number of owners buffer * @return result code. 0 - success */ -int dap_chain_datum_decree_get_min_owners(dap_chain_datum_decree_t *a_decree, uint16_t *a_min_owners_num); +int dap_chain_datum_decree_get_min_owners(dap_chain_datum_decree_t *a_decree, uint256_t *a_min_owners_num); /** * @brief dap_chain_datum_decree_get_tx_hash get stake tx hash @@ -200,7 +216,7 @@ int dap_chain_datum_decree_get_min_owners(dap_chain_datum_decree_t *a_decree, ui * @param a_tx_hash pointer to tx hash buffer * @return result code. 0 - success */ -int dap_chain_datum_decree_get_stake_tx_hash(dap_chain_datum_decree_t *a_decree, dap_hash_fast_t *a_tx_hash); +int dap_chain_datum_decree_get_hash(dap_chain_datum_decree_t *a_decree, dap_hash_fast_t *a_tx_hash); /** * @brief dap_chain_datum_decree_get_stake_value get stake value @@ -250,6 +266,9 @@ int dap_chain_datum_decree_get_stake_min_value(dap_chain_datum_decree_t *a_decre * @return result code. 0 - success */ int dap_chain_datum_decree_get_stake_min_signers_count(dap_chain_datum_decree_t *a_decree, uint256_t *a_min_signers_count); +int dap_chain_datum_decree_get_action(dap_chain_datum_decree_t *a_decree, uint8_t *a_action); +int dap_chain_datum_decree_get_signature_type(dap_chain_datum_decree_t *a_decree, uint32_t *a_signature_type); +int dap_chain_datum_decree_get_ban_addr(dap_chain_datum_decree_t *a_decree, const char **a_addr); /** * @breif dap_chain_datum_decree_dump Dump information about decree @@ -260,6 +279,15 @@ int dap_chain_datum_decree_get_stake_min_signers_count(dap_chain_datum_decree_t */ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree_t *a_decree, size_t a_decree_size, const char *a_hash_out_type); +/** + * @breif dap_chain_datum_decree_dump Dump information about decree + * @param a_obj_out pointer to output json object + * @param a_decree pointer to decree + * @param a_decree_size size data + * @param a_hash_out_type + */ +void dap_chain_datum_decree_dump_json(json_object *a_obj_out, dap_chain_datum_decree_t *a_decree, size_t a_decree_size, const char *a_hash_out_type); + /** * @brief dap_chain_datum_decree_certs_dump compose decree signatures output string * @param a_str_out pointer to output text buffer @@ -268,6 +296,8 @@ void dap_chain_datum_decree_dump(dap_string_t *a_str_out, dap_chain_datum_decree */ void dap_chain_datum_decree_certs_dump(dap_string_t * a_str_out, byte_t * a_signs, size_t a_certs_size, const char *a_hash_out_type); +void dap_chain_datum_decree_certs_dump_json(json_object * a_json_out, byte_t * a_signs, size_t a_certs_size, const char *a_hash_out_type); + /** * @brief dap_chain_datum_decree_sign_in_cycle * sign data (datum_decree) by certificates (1 or more) diff --git a/modules/common/include/dap_chain_datum_token.h b/modules/common/include/dap_chain_datum_token.h index 4fb52984e1bc6c68a1e32c84da0434cdd57fa4d9..e993e219a04ba91d4d17bc605cb60def9943938c 100644 --- a/modules/common/include/dap_chain_datum_token.h +++ b/modules/common/include/dap_chain_datum_token.h @@ -500,6 +500,22 @@ typedef struct dap_chain_datum_token_emission { #define DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_UNIQUE_ID 0x000F #define DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_BASE_TX_HASH 0x0010 +#define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_STAKING "STAKING" +#define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_STAKE_CROSSCHAIN "CONTRACT" +#define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_STAKE_CROSSCHAINV2 "CONTRACT_NFT" +#define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_HARVEST "HARVEST" +#define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_ADDLIQ "ADDLIQ" +#define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_EMSFIX "EMSFIX" +#define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_BONUS "BONUS" +#define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_UNSTAKE_FINALIZATION "UNSTAKE" + +#define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_BRIDGE "BRIDGE" +#define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_BRIDGE_TRANSFER "TO_WALLET" +#define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_BRIDGE_COMMISSION_OLD "COMISSION" +#define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_BRIDGE_COMMISSION "COMMISSION" +#define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_BRIDGE_CROSSCHAIN "CROSSCHAIN" + + extern const char *c_dap_chain_datum_token_emission_type_str[]; /// TDS op funcs diff --git a/modules/common/include/dap_chain_datum_tx.h b/modules/common/include/dap_chain_datum_tx.h index 87776da8f6d5d02eda7f1b7206ea8799a39848c6..3473e3ffe8585db8c1bd5bb1c600ba26e14c473d 100644 --- a/modules/common/include/dap_chain_datum_tx.h +++ b/modules/common/include/dap_chain_datum_tx.h @@ -27,7 +27,7 @@ #include "dap_enc_key.h" #include "dap_chain_common.h" #include "dap_time.h" -#include "json.h" +#include "dap_pkey.h" /** * @struct dap_chain_datum_tx @@ -153,6 +153,5 @@ dap_sign_t *dap_chain_datum_tx_get_sign(dap_chain_datum_tx_t *a_tx, int a_sign_n */ int dap_chain_datum_tx_verify_sign(dap_chain_datum_tx_t *a_tx); -//json_object *dap_chain_datum_tx_to_json(dap_chain_datum_tx_t *a_tx); int dap_chain_datum_tx_get_fee_value (dap_chain_datum_tx_t *a_tx, uint256_t *a_value); diff --git a/modules/common/include/dap_chain_datum_tx_items.h b/modules/common/include/dap_chain_datum_tx_items.h index 8c312f097c12534c14ae0ef9c88fbaed7848fa6a..b81995e3ff6865e041c58484cac38062c6330249 100644 --- a/modules/common/include/dap_chain_datum_tx_items.h +++ b/modules/common/include/dap_chain_datum_tx_items.h @@ -85,6 +85,42 @@ DAP_STATIC_INLINE const char * dap_chain_datum_tx_item_type_to_str(dap_chain_tx_ } } +typedef struct dap_chain_datum_tx_item_groups { + + dap_list_t *items_in_all; + dap_list_t *items_in; + dap_list_t *items_in_cond; + dap_list_t *items_in_reward; + dap_list_t *items_sig; + + + dap_list_t *items_out; + dap_list_t *items_out_all; + dap_list_t *items_out_old; + dap_list_t *items_out_ext; + dap_list_t *items_out_cond; + dap_list_t *items_out_cond_srv_fee; + dap_list_t *items_out_cond_srv_pay; + dap_list_t *items_out_cond_srv_xchange; + dap_list_t *items_out_cond_srv_stake_pos_delegate; + dap_list_t *items_out_cond_srv_stake_lock; + dap_list_t *items_out_cond_unknonwn; + dap_list_t *items_out_cond_undefined; + + dap_list_t *items_in_ems; + dap_list_t *items_vote; + dap_list_t *items_voting; + dap_list_t *items_tsd; + dap_list_t *items_pkey; + dap_list_t *items_receipt; + + dap_list_t *items_unknown; + +} dap_chain_datum_tx_item_groups_t; + +bool dap_chain_datum_tx_group_items(dap_chain_datum_tx_t *a_tx, dap_chain_datum_tx_item_groups_t *a_res_group); +void dap_chain_datum_tx_group_items_free( dap_chain_datum_tx_item_groups_t *a_group); + /** * Get item type by item name * diff --git a/modules/common/include/dap_chain_datum_tx_out_cond.h b/modules/common/include/dap_chain_datum_tx_out_cond.h index 85414a2fabea9b3328bdd20e69617c86b0d6ca45..f8dd739dd37c84b8e468d0ddb64b269bbda41cb2 100644 --- a/modules/common/include/dap_chain_datum_tx_out_cond.h +++ b/modules/common/include/dap_chain_datum_tx_out_cond.h @@ -28,7 +28,6 @@ #include "dap_common.h" #include "dap_time.h" #include "dap_chain_common.h" -#include "dap_chain_datum_tx.h" enum dap_chain_tx_out_cond_subtype { DAP_CHAIN_TX_OUT_COND_SUBTYPE_UNDEFINED = 0x0, diff --git a/modules/consensus/block-poa/dap_chain_cs_block_poa.c b/modules/consensus/block-poa/dap_chain_cs_block_poa.c index 6498631906238d2b6540062ecd5d9e2e8519b1ae..d36958cfc24183c9e148b7a530608ba212a452ea 100644 --- a/modules/consensus/block-poa/dap_chain_cs_block_poa.c +++ b/modules/consensus/block-poa/dap_chain_cs_block_poa.c @@ -112,11 +112,12 @@ static int s_cli_block_poa(int argc, char ** argv, void **a_str_reply) return -1; } - if (dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index,argc,argv,a_str_reply,&l_chain,&l_chain_net)){ + if (dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index,argc,argv,a_str_reply,&l_chain,&l_chain_net, + CHAIN_TYPE_INVALID)){ return -3; } - const char *l_chain_type = dap_chain_net_get_type(l_chain); + const char *l_chain_type = dap_chain_get_cs_type(l_chain); if (strcmp(l_chain_type, "block_poa")){ dap_cli_server_cmd_set_reply_text(a_str_reply, "Type of chain %s is not block_poa. This chain with type %s is not supported by this command", @@ -211,9 +212,9 @@ static int s_callback_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg) } char l_cert_name[512]; for (size_t i = 0; i < l_poa_pvt->auth_certs_count ; i++ ){ - snprintf(l_cert_name,sizeof(l_cert_name),"%s.%zu",l_poa_pvt->auth_certs_prefix, i); + snprintf(l_cert_name, sizeof(l_cert_name), "%s.%zu",l_poa_pvt->auth_certs_prefix, i); if ((l_poa_pvt->auth_certs[i] = dap_cert_find_by_name( l_cert_name)) == NULL) { - snprintf(l_cert_name,sizeof(l_cert_name),"%s.%zu.pub",l_poa_pvt->auth_certs_prefix, i); + snprintf(l_cert_name, sizeof(l_cert_name), "%s.%zu.pub",l_poa_pvt->auth_certs_prefix, i); if ((l_poa_pvt->auth_certs[i] = dap_cert_find_by_name( l_cert_name)) == NULL) { log_it(L_ERROR, "Can't find cert \"%s\"", l_cert_name); return -1; diff --git a/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c b/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c index 40f10dc4c5b9a9f498eaf2eb2cad2ce5c7524c99..2aaac68b091d488e62da30ecdb513f22b6efe50a 100644 --- a/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c +++ b/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c @@ -190,11 +190,12 @@ static int s_cli_dag_poa(int argc, char ** argv, void **a_str_reply) return -1; } - if (dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index,argc,argv,a_str_reply,&l_chain,&l_chain_net)) { + if (dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index,argc,argv,a_str_reply,&l_chain,&l_chain_net, + CHAIN_TYPE_INVALID)) { return -3; } - const char *l_chain_type = dap_chain_net_get_type(l_chain); + const char *l_chain_type = dap_chain_get_cs_type(l_chain); if (strcmp(l_chain_type, "dag_poa")){ dap_cli_server_cmd_set_reply_text(a_str_reply, @@ -378,9 +379,9 @@ static int s_callback_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg) } char l_cert_name[512]; for (size_t i = 0; i < l_poa_pvt->auth_certs_count ; i++ ){ - snprintf(l_cert_name,sizeof(l_cert_name),"%s.%zu",l_poa_pvt->auth_certs_prefix, i); + snprintf(l_cert_name, sizeof(l_cert_name), "%s.%zu",l_poa_pvt->auth_certs_prefix, i); if ((l_poa_pvt->auth_certs[i] = dap_cert_find_by_name( l_cert_name)) == NULL) { - snprintf(l_cert_name,sizeof(l_cert_name),"%s.%zu.pub",l_poa_pvt->auth_certs_prefix, i); + snprintf(l_cert_name, sizeof(l_cert_name), "%s.%zu.pub",l_poa_pvt->auth_certs_prefix, i); if ((l_poa_pvt->auth_certs[i] = dap_cert_find_by_name( l_cert_name)) == NULL) { log_it(L_ERROR, "Can't find cert \"%s\"", l_cert_name); return -1; @@ -740,7 +741,7 @@ static int s_callback_created(dap_chain_t * a_chain, dap_config_t *a_chain_net_c dap_global_db_cluster_t *l_dag_cluster = dap_global_db_cluster_add(dap_global_db_instance_get_default(), NULL, dap_guuid_compose(l_net->pub.id.uint64, DAP_CHAIN_CLUSTER_ID_DAG), l_dag->gdb_group_events_round_new, 900, true, - DAP_GDB_MEMBER_ROLE_NOBODY, DAP_CLUSTER_ROLE_AUTONOMIC); + DAP_GDB_MEMBER_ROLE_NOBODY, DAP_CLUSTER_TYPE_AUTONOMIC); dap_global_db_cluster_add_notify_callback(l_dag_cluster, s_round_changes_notify, l_dag); dap_chain_net_add_auth_nodes_to_cluster(l_net, l_dag_cluster); dap_link_manager_add_net_associate(l_net->pub.id.uint64, l_dag_cluster->links_cluster); diff --git a/modules/consensus/esbocs/dap_chain_cs_esbocs.c b/modules/consensus/esbocs/dap_chain_cs_esbocs.c index 325a9058eeb04c57cee1f8e85ea7447142edfc3b..c2c0effb2f8cbb327f67bc7f54779f5219e4a402 100644 --- a/modules/consensus/esbocs/dap_chain_cs_esbocs.c +++ b/modules/consensus/esbocs/dap_chain_cs_esbocs.c @@ -22,11 +22,13 @@ You should have received a copy of the GNU General Public License along with any CellFrame SDK based project. If not, see <http://www.gnu.org/licenses/>. */ #include "dap_common.h" +#include "dap_context.h" #include "utlist.h" #include "dap_timerfd.h" #include "rand/dap_rand.h" #include "dap_stream_ch_proc.h" #include "dap_chain_net.h" +#include "dap_chain_net_srv_order.h" #include "dap_chain_common.h" #include "dap_chain_mempool.h" #include "dap_chain_cell.h" @@ -35,7 +37,6 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic #include "dap_chain_cs_esbocs.h" #include "dap_chain_net_srv_stake_pos_delegate.h" #include "dap_chain_ledger.h" -#include "dap_chain_node_cli.h" #include "dap_chain_node_cli_cmd.h" #define LOG_TAG "dap_chain_cs_esbocs" @@ -50,11 +51,12 @@ 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_proc_state(void *a_arg); 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 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); +static bool s_session_round_new(void *a_session); static bool s_session_candidate_to_chain( dap_chain_esbocs_session_t *a_session, dap_chain_hash_fast_t *a_candidate_hash, dap_chain_block_t *a_candidate, size_t a_candidate_size); @@ -64,7 +66,6 @@ static void s_session_candidate_verify(dap_chain_esbocs_session_t *a_session, da static void s_session_candidate_precommit(dap_chain_esbocs_session_t *a_session, dap_chain_esbocs_message_t *a_message); static void s_session_round_finish(dap_chain_esbocs_session_t *a_session, dap_chain_esbocs_store_t *l_store); -static bool s_session_timer(void *a_arg); static void s_message_send(dap_chain_esbocs_session_t *a_session, uint8_t a_message_type, dap_hash_fast_t *a_block_hash, const void *a_data, size_t a_data_size, dap_list_t *a_validators); static void s_message_chain_add(dap_chain_esbocs_session_t * a_session, @@ -78,12 +79,8 @@ static void s_callback_delete(dap_chain_cs_blocks_t *a_blocks); static int s_callback_created(dap_chain_t *a_chain, dap_config_t *a_chain_net_cfg); static size_t s_callback_block_sign(dap_chain_cs_blocks_t *a_blocks, dap_chain_block_t **a_block_ptr, size_t a_block_size); static int s_callback_block_verify(dap_chain_cs_blocks_t *a_blocks, dap_chain_block_t *a_block, size_t a_block_size); -static uint256_t s_callback_get_minimum_fee(dap_chain_t *a_chain); -static uint256_t s_callback_get_collectiong_level(dap_chain_t *a_chain); -static dap_enc_key_t *s_callback_get_sign_key(dap_chain_t *a_chain); -static void s_callback_set_min_validators_count(dap_chain_t *a_chain, uint16_t a_new_value); static void s_db_change_notifier(dap_store_obj_t *a_obj, void * a_arg); - +static dap_list_t *s_check_emergency_rights(dap_chain_esbocs_t *a_esbocs, dap_chain_addr_t *a_signing_addr); static int s_cli_esbocs(int a_argc, char **a_argv, void **a_str_reply); DAP_STATIC_INLINE const char *s_voting_msg_type_to_str(uint8_t a_type) @@ -127,18 +124,26 @@ DAP_STATIC_INLINE size_t s_get_esbocs_message_size(dap_chain_esbocs_message_t *a static dap_chain_esbocs_session_t *s_session_items; +struct precached_key { + uint64_t frequency; + dap_hash_fast_t pkey_hash; + size_t pkey_size; + struct precached_key *prev, *next; + byte_t sign_pkey[]; +}; + typedef struct dap_chain_esbocs_pvt { // Base params dap_enc_key_t *blocks_sign_key; dap_hash_fast_t candidate_hash; // Validators section bool poa_mode; - uint16_t min_validators_count; uint16_t start_validators_min; // Debug flag bool debug; // Emergancy mode with signing by current online validators only bool emergency_mode; + dap_list_t *emergency_validator_addrs; // Round params uint16_t new_round_delay; uint16_t round_start_sync_timeout; @@ -151,6 +156,11 @@ typedef struct dap_chain_esbocs_pvt { uint256_t minimum_fee; uint256_t collecting_level; dap_pkey_t *block_sign_pkey; + // Decree controoled params + uint16_t min_validators_count; + bool check_signs_structure; + // Internal cache + struct precached_key *precached_keys; } dap_chain_esbocs_pvt_t; #define PVT(a) ((dap_chain_esbocs_pvt_t *)a->_pvt) @@ -174,10 +184,18 @@ int dap_chain_cs_esbocs_init() s_stream_ch_packet_in, NULL); dap_cli_server_cmd_add ("esbocs", s_cli_esbocs, "ESBOCS commands", - "esbocs min_validators_count set -net <net_name> -chain <chain_name> -cert <poa_cert_name> -val_count <value>" + "esbocs min_validators_count set -net <net_name> -chain <chain_name> -cert <poa_cert_name> -val_count <value>\n" "\tSets minimum validators count for ESBOCS consensus\n" - "esbocs min_validators_count print -net <net_name> -chain <chain_name>" - "\tShow minimum validators count for ESBOCS consensus\n\n"); + "esbocs min_validators_count show -net <net_name> -chain <chain_name>\n" + "\tShow minimum validators count for ESBOCS consensus\n" + "esbocs check_signs_structure {enable|disable} -net <net_name> -chain <chain_name> -cert <poa_cert_name>\n" + "\tEnables or disables checks for blocks signs structure validity\n" + "esbocs check_signs_structure show -net <net_name> -chain <chain_name>\n" + "\tShow status of checks for blocks signs structure validity\n" + "esbocs emergency_validator {add|remove} -net <net_name> -chain <chain_name> -cert <poa_cert_name> -pkey_hash <validator_pkey_hash>\n" + "\tAdd or remove validator by its signature public key hash to list of validators allowed to work in emergency mode\n" + "esbocs emergency_validator show -net <net_name> -chain <chain_name>\n" + "\tShow list of validators public key hashes allowed to work in emergency mode\n"); return 0; } @@ -201,11 +219,6 @@ static int s_callback_new(dap_chain_t *a_chain, dap_config_t *a_chain_cfg) l_blocks->callback_block_sign = s_callback_block_sign; l_esbocs->chain = a_chain; - a_chain->callback_set_min_validators_count = s_callback_set_min_validators_count; - a_chain->callback_get_minimum_fee = s_callback_get_minimum_fee; - a_chain->callback_get_collectiong_level = s_callback_get_collectiong_level; - a_chain->callback_get_signing_certificate = s_callback_get_sign_key; - l_esbocs->_pvt = DAP_NEW_Z(dap_chain_esbocs_pvt_t); dap_chain_esbocs_pvt_t *l_esbocs_pvt = PVT(l_esbocs); if (!l_esbocs_pvt) { @@ -214,7 +227,6 @@ static int s_callback_new(dap_chain_t *a_chain, dap_config_t *a_chain_cfg) goto lb_err; } l_esbocs_pvt->debug = dap_config_get_item_bool_default(a_chain_cfg, "esbocs", "consensus_debug", false); - l_esbocs_pvt->emergency_mode = dap_config_get_item_bool_default(a_chain_cfg, "esbocs", "emergency_mode", false); l_esbocs_pvt->poa_mode = dap_config_get_item_bool_default(a_chain_cfg, "esbocs", "poa_mode", false); l_esbocs_pvt->round_start_sync_timeout = dap_config_get_item_uint16_default(a_chain_cfg, "esbocs", "round_start_sync_timeout", 15); l_esbocs_pvt->new_round_delay = dap_config_get_item_uint16_default(a_chain_cfg, "esbocs", "new_round_delay", 10); @@ -231,15 +243,16 @@ static int s_callback_new(dap_chain_t *a_chain, dap_config_t *a_chain_cfg) const char *l_auth_certs_prefix = dap_config_get_item_str(a_chain_cfg, "esbocs", "auth_certs_prefix"); uint16_t l_node_addrs_count; char **l_addrs = dap_config_get_array_str(a_chain_cfg, "esbocs", "validators_addrs", &l_node_addrs_count); - uint16_t l_auth_certs_count = l_node_addrs_count; - if (l_auth_certs_count < l_esbocs_pvt->min_validators_count) { + if (l_node_addrs_count < l_esbocs_pvt->min_validators_count) { l_ret = -2; goto lb_err; } - char l_cert_name[512]; - dap_cert_t *l_cert_cur; + dap_chain_net_srv_stake_net_add(a_chain->net_id); + uint16_t l_auth_certs_count = dap_config_get_item_uint16_default(a_chain_cfg, "esbocs", "auth_certs_count", l_node_addrs_count); dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id); for (size_t i = 0; i < l_auth_certs_count; i++) { + char l_cert_name[512]; + dap_cert_t *l_cert_cur; snprintf(l_cert_name, sizeof(l_cert_name), "%s.%zu", l_auth_certs_prefix, i); if ((l_cert_cur = dap_cert_find_by_name(l_cert_name)) == NULL) { snprintf(l_cert_name, sizeof(l_cert_name), "%s.%zu.pub", l_auth_certs_prefix, i); @@ -252,13 +265,18 @@ static int s_callback_new(dap_chain_t *a_chain, dap_config_t *a_chain_cfg) dap_chain_addr_t l_signing_addr; log_it(L_NOTICE, "Initialized auth cert \"%s\"", l_cert_name); dap_chain_addr_fill_from_key(&l_signing_addr, l_cert_cur->enc_key, a_chain->net_id); + + l_esbocs_pvt->emergency_validator_addrs = dap_list_append(l_esbocs_pvt->emergency_validator_addrs, + DAP_DUP(&l_signing_addr)); + if (i >= l_node_addrs_count) + continue; + dap_chain_node_addr_t l_signer_node_addr; if (dap_chain_node_addr_from_str(&l_signer_node_addr, l_addrs[i])) { log_it(L_ERROR, "Wrong address format, should be like 0123::4567::89AB::CDEF"); l_ret = -4; goto lb_err; } - dap_chain_esbocs_validator_t *l_validator = DAP_NEW_Z(dap_chain_esbocs_validator_t); if (!l_validator) { log_it(L_CRITICAL, "%s", g_error_memory_alloc); @@ -274,7 +292,7 @@ static int s_callback_new(dap_chain_t *a_chain, dap_config_t *a_chain_cfg) if (!l_esbocs_pvt->poa_mode) { // auth certs in PoA mode will be first PoS validators keys dap_hash_fast_t l_stake_tx_hash = {}; - uint256_t l_weight = dap_chain_net_srv_stake_get_allowed_min_value(); + uint256_t l_weight = dap_chain_net_srv_stake_get_allowed_min_value(a_chain->net_id); dap_chain_net_srv_stake_key_delegate(l_net, &l_signing_addr, &l_stake_tx_hash, l_weight, &l_signer_node_addr); } @@ -351,39 +369,40 @@ static void s_check_db_collect_callback(dap_global_db_instance_t UNUSED_ARG *a_d dap_global_db_objs_delete(l_objs, l_objs_count); } -void dap_chain_esbocs_add_block_collect(dap_chain_block_t *a_block_ptr, size_t a_block_size, - dap_chain_esbocs_block_collect_t *a_block_collect_params,int a_type) +void dap_chain_esbocs_add_block_collect(dap_chain_block_cache_t *a_block_cache, + dap_chain_esbocs_block_collect_t *a_block_collect_params, + dap_chain_block_autocollect_type_t a_type) { - dap_hash_fast_t l_last_block_hash; - dap_chain_get_atom_last_hash(a_block_collect_params->chain, a_block_collect_params->cell_id, &l_last_block_hash); + dap_return_if_fail(a_block_cache && a_block_collect_params); dap_chain_t *l_chain = a_block_collect_params->chain; - dap_sign_t *l_sign = dap_chain_block_sign_get(a_block_ptr, a_block_size, 0); - if (dap_pkey_match_sign(a_block_collect_params->block_sign_pkey, l_sign)&&(!a_type||a_type==1)) { - dap_chain_esbocs_block_collect_t *l_block_collect_params = DAP_NEW_Z(dap_chain_esbocs_block_collect_t); - l_block_collect_params->collecting_level = a_block_collect_params->collecting_level; - l_block_collect_params->minimum_fee = a_block_collect_params->minimum_fee; - l_block_collect_params->chain = a_block_collect_params->chain; - l_block_collect_params->blocks_sign_key = a_block_collect_params->blocks_sign_key; - l_block_collect_params->block_sign_pkey = a_block_collect_params->block_sign_pkey; - l_block_collect_params->collecting_addr = a_block_collect_params->collecting_addr; - - dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(l_chain); - dap_chain_block_cache_t *l_block_cache = dap_chain_block_cache_get_by_hash(l_blocks, &l_last_block_hash); - assert(l_block_cache); - dap_chain_net_t *l_net = dap_chain_net_by_id(l_chain->net_id); - assert(l_net); - uint256_t l_value_fee = uint256_0; - dap_list_t *l_list_used_out = dap_chain_block_get_list_tx_cond_outs_with_val( - l_net->pub.ledger, l_block_cache, &l_value_fee); - if (!IS_ZERO_256(l_value_fee)) { - char *l_fee_group = dap_chain_cs_blocks_get_fee_group(l_chain->net_name); - dap_global_db_set(l_fee_group, l_block_cache->block_hash_str, &l_value_fee, sizeof(l_value_fee), - false, s_check_db_collect_callback, l_block_collect_params); - DAP_DELETE(l_fee_group); - } - dap_list_free_full(l_list_used_out, NULL); - } - if (dap_chain_block_sign_match_pkey(a_block_ptr, a_block_size, a_block_collect_params->block_sign_pkey)&&(!a_type||a_type==2)) { + if (a_type == DAP_CHAIN_BLOCK_COLLECT_BOTH || a_type == DAP_CHAIN_BLOCK_COLLECT_FEES) { + dap_sign_t *l_sign = dap_chain_block_sign_get(a_block_cache->block, a_block_cache->block_size, 0); + if (dap_pkey_match_sign(a_block_collect_params->block_sign_pkey, l_sign)) { + dap_chain_esbocs_block_collect_t *l_block_collect_params = DAP_NEW_Z(dap_chain_esbocs_block_collect_t); + l_block_collect_params->collecting_level = a_block_collect_params->collecting_level; + l_block_collect_params->minimum_fee = a_block_collect_params->minimum_fee; + l_block_collect_params->chain = a_block_collect_params->chain; + l_block_collect_params->blocks_sign_key = a_block_collect_params->blocks_sign_key; + l_block_collect_params->block_sign_pkey = a_block_collect_params->block_sign_pkey; + l_block_collect_params->collecting_addr = a_block_collect_params->collecting_addr; + dap_chain_net_t *l_net = dap_chain_net_by_id(l_chain->net_id); + assert(l_net); + uint256_t l_value_fee = uint256_0; + dap_list_t *l_list_used_out = dap_chain_block_get_list_tx_cond_outs_with_val( + l_net->pub.ledger, a_block_cache, &l_value_fee); + if (!IS_ZERO_256(l_value_fee)) { + char *l_fee_group = dap_chain_cs_blocks_get_fee_group(l_chain->net_name); + dap_global_db_set(l_fee_group, a_block_cache->block_hash_str, &l_value_fee, sizeof(l_value_fee), + false, s_check_db_collect_callback, l_block_collect_params); + DAP_DELETE(l_fee_group); + } + dap_list_free_full(l_list_used_out, NULL); + } + } + if (a_type != DAP_CHAIN_BLOCK_COLLECT_BOTH && a_type != DAP_CHAIN_BLOCK_COLLECT_REWARDS) + return; + if (dap_chain_block_sign_match_pkey(a_block_cache->block, a_block_cache->block_size, + a_block_collect_params->block_sign_pkey)) { dap_chain_esbocs_block_collect_t *l_block_collect_params = DAP_NEW_Z(dap_chain_esbocs_block_collect_t); l_block_collect_params->collecting_level = a_block_collect_params->collecting_level; l_block_collect_params->minimum_fee = a_block_collect_params->minimum_fee; @@ -391,19 +410,15 @@ void dap_chain_esbocs_add_block_collect(dap_chain_block_t *a_block_ptr, size_t a l_block_collect_params->blocks_sign_key = a_block_collect_params->blocks_sign_key; l_block_collect_params->block_sign_pkey = a_block_collect_params->block_sign_pkey; l_block_collect_params->collecting_addr = a_block_collect_params->collecting_addr; - - dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(l_chain); - dap_chain_block_cache_t *l_block_cache = dap_chain_block_cache_get_by_hash(l_blocks, &l_last_block_hash); - assert(l_block_cache); dap_chain_net_t *l_net = dap_chain_net_by_id(l_chain->net_id); assert(l_net); - if (!dap_ledger_is_used_reward(l_net->pub.ledger, &l_block_cache->block_hash, + if (!dap_ledger_is_used_reward(l_net->pub.ledger, &a_block_cache->block_hash, &l_block_collect_params->collecting_addr->data.hash_fast)) { - uint256_t l_value_reward = l_chain->callback_calc_reward(l_chain, &l_block_cache->block_hash, + uint256_t l_value_reward = l_chain->callback_calc_reward(l_chain, &a_block_cache->block_hash, l_block_collect_params->block_sign_pkey); if (!IS_ZERO_256(l_value_reward)) { char *l_reward_group = dap_chain_cs_blocks_get_reward_group(l_chain->net_name); - dap_global_db_set(l_reward_group, l_block_cache->block_hash_str, &l_value_reward, sizeof(l_value_reward), + dap_global_db_set(l_reward_group, a_block_cache->block_hash_str, &l_value_reward, sizeof(l_value_reward), false, s_check_db_collect_callback, l_block_collect_params); DAP_DELETE(l_reward_group); } @@ -433,7 +448,8 @@ static void s_new_atom_notifier(void *a_arg, dap_chain_t *a_chain, dap_chain_cel .collecting_addr = PVT(l_session->esbocs)->collecting_addr, .cell_id = a_id }; - dap_chain_esbocs_add_block_collect(a_atom, a_atom_size, &l_block_collect_params,0); + dap_chain_block_cache_t *l_block_cache = dap_chain_block_cache_get_by_hash(DAP_CHAIN_CS_BLOCKS(a_chain), &l_last_block_hash); + dap_chain_esbocs_add_block_collect(l_block_cache, &l_block_collect_params, DAP_CHAIN_BLOCK_COLLECT_BOTH); } bool dap_chain_esbocs_get_autocollect_status(dap_chain_net_id_t a_net_id) @@ -460,7 +476,7 @@ static int s_callback_created(dap_chain_t *a_chain, dap_config_t *a_chain_net_cf l_esbocs_pvt->collecting_addr = dap_chain_addr_from_str(dap_config_get_item_str(a_chain_net_cfg, "esbocs", "fee_addr")); l_esbocs_pvt->collecting_level = dap_chain_coins_to_balance(dap_config_get_item_str_default(a_chain_net_cfg, "esbocs", "set_collect_fee", "10.0")); - dap_list_t *l_validators = dap_chain_net_srv_stake_get_validators(a_chain->net_id, false); + dap_list_t *l_validators = dap_chain_net_srv_stake_get_validators(a_chain->net_id, false, NULL); for (dap_list_t *it = l_validators; it; it = it->next) { dap_stream_node_addr_t *l_addr = &((dap_chain_net_srv_stake_item_t *)it->data)->node_addr; dap_chain_net_add_validator_to_clusters(a_chain, l_addr); @@ -518,21 +534,24 @@ static int s_callback_created(dap_chain_t *a_chain, dap_config_t *a_chain_net_cf l_session->my_addr.uint64 = dap_chain_net_get_cur_addr_int(l_net); l_session->my_signing_addr = l_my_signing_addr; -// TODO make correct link management w/o global DB cluster -#ifdef DAP_CHAIN_CS_ESBOCS_DIRECTIVE_SUPPORT + char *l_sync_group = s_get_penalty_group(l_net->pub.id); l_session->db_cluster = dap_global_db_cluster_add(dap_global_db_instance_get_default(), NULL, dap_guuid_compose(l_net->pub.id.uint64, DAP_CHAIN_CLUSTER_ID_ESBOCS), l_sync_group, 72 * 3600, true, - DAP_GDB_MEMBER_ROLE_NOBODY, DAP_CLUSTER_ROLE_AUTONOMIC); + DAP_GDB_MEMBER_ROLE_NOBODY, DAP_CLUSTER_TYPE_AUTONOMIC); DAP_DELETE(l_sync_group); dap_global_db_cluster_add_notify_callback(l_session->db_cluster, s_db_change_notifier, l_session); -#endif dap_link_manager_add_net_associate(l_net->pub.id.uint64, l_session->db_cluster->links_cluster); +#ifdef DAP_CHAIN_CS_ESBOCS_DIRECTIVE_SUPPORT + dap_global_db_role_t l_directives_cluster_role_default = DAP_GDB_MEMBER_ROLE_ROOT; +#else + dap_global_db_role_t l_directives_cluster_role_default = DAP_GDB_MEMBER_ROLE_GUEST; +#endif for (dap_list_t *it = l_validators; it; it = it->next) { dap_stream_node_addr_t *l_addr = &((dap_chain_net_srv_stake_item_t *)it->data)->node_addr; - dap_global_db_cluster_member_add(l_session->db_cluster, l_addr, DAP_GDB_MEMBER_ROLE_ROOT); + dap_global_db_cluster_member_add(l_session->db_cluster, l_addr, l_directives_cluster_role_default); } dap_list_free_full(l_validators, NULL); @@ -567,16 +586,17 @@ static int s_callback_created(dap_chain_t *a_chain, dap_config_t *a_chain_net_cf log_it(L_ERROR, "No valid order found was signed by this validator deledgated key. Switch off validator mode."); return -4; } - pthread_mutexattr_t l_mutex_attr; - pthread_mutexattr_init(&l_mutex_attr); - pthread_mutexattr_settype(&l_mutex_attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&l_session->mutex, &l_mutex_attr); - pthread_mutexattr_destroy(&l_mutex_attr); + l_esbocs_pvt->emergency_mode = dap_config_get_item_bool_default(a_chain_net_cfg, "esbocs", "emergency_mode", false); + if (l_esbocs_pvt->emergency_mode && !s_check_emergency_rights(l_esbocs, &l_my_signing_addr)) { + log_it(L_ERROR, "This validator is not allowed to work in emergency mode. Use special decree to supply it"); + return -5; + } + pthread_mutex_init(&l_session->mutex, NULL); dap_chain_add_callback_notify(a_chain, s_new_atom_notifier, l_session); s_session_round_new(l_session); - l_session->cs_timer = dap_timerfd_start(1000, s_session_timer, l_session); - debug_if(l_esbocs_pvt->debug, L_MSG, "Consensus main timer is started"); + l_session->cs_timer = !dap_proc_thread_timer_add(NULL, s_session_proc_state, l_session, 1000); + debug_if(l_esbocs_pvt->debug && l_session->cs_timer, L_MSG, "Consensus main timer is started"); DAP_CHAIN_PVT(a_chain)->cs_started = true; return 0; @@ -618,10 +638,9 @@ void dap_chain_esbocs_stop_timer(dap_chain_net_id_t a_net_id) dap_chain_esbocs_session_t *l_session; DL_FOREACH(s_session_items, l_session) { if (l_session->chain->net_id.uint64 == a_net_id.uint64 && - l_session->cs_timer){ + l_session->cs_timer) { log_it(L_INFO, "Stop consensus timer for net: %s, chain: %s", dap_chain_net_by_id(a_net_id)->pub.name, l_session->chain->name); - dap_timerfd_delete_mt(l_session->cs_timer->worker, l_session->cs_timer->esocket_uuid); - l_session->cs_timer = NULL; + l_session->cs_timer = false; } } } @@ -630,9 +649,9 @@ void dap_chain_esbocs_start_timer(dap_chain_net_id_t a_net_id) { dap_chain_esbocs_session_t *l_session; DL_FOREACH(s_session_items, l_session) { - if (l_session->chain->net_id.uint64 == a_net_id.uint64){ + if (l_session->chain->net_id.uint64 == a_net_id.uint64) { log_it(L_INFO, "Start consensus timer for net: %s, chain: %s", dap_chain_net_by_id(a_net_id)->pub.name, l_session->chain->name); - l_session->cs_timer = dap_timerfd_start(1000, s_session_timer, l_session); + l_session->cs_timer = true; } } } @@ -667,31 +686,86 @@ bool dap_chain_esbocs_remove_validator_from_clusters(dap_chain_net_id_t a_net_id return NULL; } -static uint256_t s_callback_get_minimum_fee(dap_chain_t *a_chain) +uint256_t dap_chain_esbocs_get_collecting_level(dap_chain_t *a_chain) { + dap_return_val_if_fail(a_chain && !strcmp(dap_chain_get_cs_type(a_chain), "esbocs"), uint256_0); dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain); dap_chain_esbocs_t *l_esbocs = DAP_CHAIN_ESBOCS(l_blocks); dap_chain_esbocs_pvt_t *l_esbocs_pvt = PVT(l_esbocs); - return l_esbocs_pvt->minimum_fee; + return l_esbocs_pvt->collecting_level; } -static uint256_t s_callback_get_collectiong_level(dap_chain_t *a_chain) +dap_enc_key_t *dap_chain_esbocs_get_sign_key(dap_chain_t *a_chain) { + dap_return_val_if_fail(a_chain && !strcmp(dap_chain_get_cs_type(a_chain), "esbocs"), NULL); dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain); dap_chain_esbocs_t *l_esbocs = DAP_CHAIN_ESBOCS(l_blocks); dap_chain_esbocs_pvt_t *l_esbocs_pvt = PVT(l_esbocs); - return l_esbocs_pvt->collecting_level; + return l_esbocs_pvt->blocks_sign_key; } -static dap_enc_key_t *s_callback_get_sign_key(dap_chain_t *a_chain) +int dap_chain_esbocs_set_min_validators_count(dap_chain_t *a_chain, uint16_t a_new_value) { + dap_return_val_if_fail(a_chain && !strcmp(dap_chain_get_cs_type(a_chain), "esbocs"), -1); dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain); dap_chain_esbocs_t *l_esbocs = DAP_CHAIN_ESBOCS(l_blocks); dap_chain_esbocs_pvt_t *l_esbocs_pvt = PVT(l_esbocs); + if (a_new_value) + l_esbocs_pvt->min_validators_count = a_new_value; + else { + dap_hash_fast_t l_stake_tx_hash = {}; + dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id); + uint256_t l_weight = dap_chain_net_srv_stake_get_allowed_min_value(a_chain->net_id); + for (dap_list_t *it = l_esbocs_pvt->poa_validators; it; it = it->next) { + dap_chain_esbocs_validator_t *l_validator = it->data; + dap_chain_net_srv_stake_key_delegate(l_net, &l_validator->signing_addr, &l_stake_tx_hash, + l_weight, &l_validator->node_addr); + } + l_esbocs_pvt->min_validators_count = l_esbocs_pvt->start_validators_min; + } + return 0; +} - return l_esbocs_pvt->blocks_sign_key; +int dap_chain_esbocs_set_signs_struct_check(dap_chain_t *a_chain, bool a_enable) +{ + dap_return_val_if_fail(a_chain && !strcmp(dap_chain_get_cs_type(a_chain), "esbocs"), -1); + dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain); + dap_chain_esbocs_t *l_esbocs = DAP_CHAIN_ESBOCS(l_blocks); + dap_chain_esbocs_pvt_t *l_esbocs_pvt = PVT(l_esbocs); + l_esbocs_pvt->check_signs_structure = a_enable; + return 0; +} + +int dap_chain_esbocs_set_emergency_validator(dap_chain_t *a_chain, bool a_add, uint32_t a_sign_type, dap_hash_fast_t *a_validator_hash) +{ + dap_return_val_if_fail(a_chain && !strcmp(dap_chain_get_cs_type(a_chain), "esbocs"), -1); + dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain); + dap_chain_esbocs_t *l_esbocs = DAP_CHAIN_ESBOCS(l_blocks); + dap_chain_esbocs_pvt_t *l_esbocs_pvt = PVT(l_esbocs); + dap_chain_addr_t l_signing_addr; + dap_sign_type_t l_type = { .type = a_sign_type }; + dap_chain_addr_fill(&l_signing_addr, l_type , a_validator_hash, a_chain->net_id); + if (a_add) { + if (s_check_emergency_rights(l_esbocs, &l_signing_addr)) + return -2; + dap_chain_addr_t *l_addr_new = DAP_DUP(&l_signing_addr); + if (!l_addr_new) { + log_it(L_CRITICAL, "%s", g_error_memory_alloc); + return -4; + } + l_esbocs_pvt->emergency_validator_addrs = dap_list_append( + l_esbocs_pvt->emergency_validator_addrs, l_addr_new); + } else { + dap_list_t *l_to_remove = s_check_emergency_rights(l_esbocs, &l_signing_addr); + if (!l_to_remove) + return -3; + DAP_DELETE(l_to_remove->data); + l_esbocs_pvt->emergency_validator_addrs = dap_list_delete_link( + l_esbocs_pvt->emergency_validator_addrs, l_to_remove); + } + return 0; } static void s_callback_delete(dap_chain_cs_blocks_t *a_blocks) @@ -706,7 +780,6 @@ static void s_callback_delete(dap_chain_cs_blocks_t *a_blocks) } pthread_mutex_lock(&l_session->mutex); DL_DELETE(s_session_items, l_session); - dap_timerfd_delete_mt(l_session->cs_timer->worker, l_session->cs_timer->esocket_uuid); s_session_round_clear(l_session); dap_chain_esbocs_sync_item_t *l_sync_item, *l_sync_tmp; HASH_ITER(hh, l_session->sync_items, l_sync_item, l_sync_tmp) { @@ -743,33 +816,30 @@ static void *s_callback_list_form(const void *a_srv_validator, UNUSED_ARG void * return l_validator; } -static void s_callback_set_min_validators_count(dap_chain_t *a_chain, uint16_t a_new_value) -{ - dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain); - dap_chain_esbocs_t *l_esbocs = DAP_CHAIN_ESBOCS(l_blocks); - dap_chain_esbocs_pvt_t *l_esbocs_pvt = PVT(l_esbocs); - if (a_new_value) - l_esbocs_pvt->min_validators_count = a_new_value; - else { - dap_hash_fast_t l_stake_tx_hash = {}; - dap_chain_net_t *l_net = dap_chain_net_by_id(a_chain->net_id); - uint256_t l_weight = dap_chain_net_srv_stake_get_allowed_min_value(); - for (dap_list_t *it = l_esbocs_pvt->poa_validators; it; it = it->next) { - dap_chain_esbocs_validator_t *l_validator = it->data; - dap_chain_net_srv_stake_key_delegate(l_net, &l_validator->signing_addr, &l_stake_tx_hash, - l_weight, &l_validator->node_addr); - } - l_esbocs_pvt->min_validators_count = l_esbocs_pvt->start_validators_min; - } -} - -static dap_list_t *s_get_validators_list(dap_chain_esbocs_session_t *a_session, uint64_t a_skip_count) +static dap_list_t *s_get_validators_list(dap_chain_esbocs_t *a_esbocs, dap_hash_fast_t *a_last_hash, uint64_t a_skip_count, + uint16_t *a_excluded_list, uint16_t a_excluded_list_size) { - dap_chain_esbocs_pvt_t *l_esbocs_pvt = PVT(a_session->esbocs); + dap_chain_esbocs_pvt_t *l_esbocs_pvt = PVT(a_esbocs); dap_list_t *l_ret = NULL; - + dap_list_t *l_validators = NULL; if (!l_esbocs_pvt->poa_mode) { - dap_list_t *l_validators = dap_chain_net_srv_stake_get_validators(a_session->chain->net_id, true); + if (a_excluded_list_size) { + l_validators = dap_chain_net_srv_stake_get_validators(a_esbocs->chain->net_id, false, NULL); + uint16_t l_excluded_num = *a_excluded_list; + uint16_t l_excluded_list_idx = 0, l_validator_idx = 0; + dap_list_t *it, *tmp; + DL_FOREACH_SAFE(l_validators, it, tmp) { + if (l_validator_idx++ == l_excluded_num) { + DAP_DELETE(it->data); + l_validators = dap_list_delete_link(l_validators, it); + if (l_excluded_list_idx == a_excluded_list_size - 1) + break; + l_excluded_num = a_excluded_list[++l_excluded_list_idx]; + } + } + } else + l_validators = dap_chain_net_srv_stake_get_validators(a_esbocs->chain->net_id, true, + &a_esbocs->session->cur_round.excluded_list); uint16_t l_total_validators_count = dap_list_length(l_validators); if (l_total_validators_count < l_esbocs_pvt->min_validators_count) { log_it(L_MSG, "Can't start new round. Totally active validators count %hu is below minimum count %hu", @@ -792,7 +862,7 @@ static dap_list_t *s_get_validators_list(dap_chain_esbocs_session_t *a_session, size_t l_consensus_optimum = (size_t)l_esbocs_pvt->min_validators_count * 2 - 1; size_t l_need_vld_cnt = dap_min(l_total_validators_count, l_consensus_optimum); - dap_pseudo_random_seed(*(uint256_t *)&a_session->cur_round.last_block_hash); + dap_pseudo_random_seed(*(uint256_t *)a_last_hash); for (uint64_t i = 0; i < a_skip_count * l_need_vld_cnt; i++) dap_pseudo_random_get(uint256_0, NULL); for (size_t l_current_vld_cnt = 0; l_current_vld_cnt < l_need_vld_cnt; l_current_vld_cnt++) { @@ -800,16 +870,17 @@ static dap_list_t *s_get_validators_list(dap_chain_esbocs_session_t *a_session, uint256_t l_chosen_weight = dap_pseudo_random_get(l_total_weight, &l_raw_result); if (false) { //PVT(a_session->esbocs)->debug) { unsigned l_strlen = 1024, l_off = 0; - char *l_chosen_weight_str, *l_total_weight_str, *l_raw_result_str, l_str[l_strlen]; + const char *l_chosen_weight_str, *l_total_weight_str, *l_raw_result_str; + char l_str[l_strlen]; dap_uint256_to_char(l_chosen_weight, &l_chosen_weight_str); - l_off = dap_snprintf(l_str, l_strlen, + l_off = snprintf(l_str, l_strlen, "Round seed %s, sync attempt %"DAP_UINT64_FORMAT_U", chosen weight %s ", - dap_hash_fast_to_str_static(&a_session->cur_round.last_block_hash), + dap_hash_fast_to_str_static(a_last_hash), a_skip_count + 1, l_chosen_weight_str); dap_uint256_to_char(l_total_weight, &l_total_weight_str); - l_off += dap_snprintf(l_str + l_off, l_strlen - l_off, "from %s, ", l_total_weight_str); + l_off += snprintf(l_str + l_off, l_strlen - l_off, "from %s, ", l_total_weight_str); dap_uint256_to_char(l_raw_result, &l_raw_result_str); - l_off += dap_snprintf(l_str + l_off, l_strlen - l_off, "by number %s", l_raw_result_str); + l_off += snprintf(l_str + l_off, l_strlen - l_off, "by number %s", l_raw_result_str); log_it(L_MSG, "%s", l_str); } dap_list_t *l_chosen = NULL; @@ -846,7 +917,7 @@ static int s_callback_addr_compare(dap_list_t *a_list_elem, dap_list_t *a_addr_e log_it(L_CRITICAL, "Invalid argument"); return -1; } - return memcmp(&l_validator->signing_addr, l_addr, sizeof(dap_chain_addr_t)); + return memcmp(&l_validator->signing_addr.data.hash_fast, &l_addr->data.hash_fast, sizeof(dap_hash_fast_t)); } static dap_list_t *s_validator_check(dap_chain_addr_t *a_addr, dap_list_t *a_validators) @@ -862,7 +933,9 @@ static int s_callback_addr_compare_synced(dap_list_t *a_list_elem, dap_list_t *a log_it(L_CRITICAL, "Invalid argument"); return -1; } - return memcmp(&l_validator->signing_addr, l_addr, sizeof(dap_chain_addr_t)) || !l_validator->is_synced; + return memcmp(&l_validator->signing_addr.data.hash_fast, + &l_addr->data.hash_fast, sizeof(dap_hash_fast_t)) || + !l_validator->is_synced; } static dap_list_t *s_validator_check_synced(dap_chain_addr_t *a_addr, dap_list_t *a_validators) @@ -944,6 +1017,7 @@ static void s_session_round_clear(dap_chain_esbocs_session_t *a_session) dap_chain_esbocs_store_t *l_store_item, *l_store_tmp; HASH_ITER(hh, a_session->cur_round.store_items, l_store_item, l_store_tmp) { HASH_DEL(a_session->cur_round.store_items, l_store_item); + DAP_DEL_Z(l_store_item->candidate); dap_list_free_full(l_store_item->candidate_signs, NULL); DAP_DELETE(l_store_item); } @@ -960,8 +1034,9 @@ 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) +static bool s_session_round_new(void *a_arg) { + dap_chain_esbocs_session_t *a_session = (dap_chain_esbocs_session_t*)a_arg; if (!a_session->round_fast_forward) s_session_update_penalty(a_session); s_session_round_clear(a_session); @@ -986,15 +1061,18 @@ static void s_session_round_new(dap_chain_esbocs_session_t *a_session) a_session->cur_round.sync_attempt = 1; } if (!PVT(a_session->esbocs)->emergency_mode) { - a_session->cur_round.validators_list = s_get_validators_list(a_session, a_session->cur_round.sync_attempt - 1); + a_session->cur_round.validators_list = s_get_validators_list(a_session->esbocs, + &a_session->cur_round.last_block_hash, + a_session->cur_round.sync_attempt - 1, + NULL, 0); if (!a_session->cur_round.validators_list) { log_it(L_WARNING, "Minimum active validators not found"); a_session->ts_round_sync_start = dap_time_now(); a_session->sync_failed = true; - return; + return false; } } - dap_list_t *l_validators = dap_chain_net_srv_stake_get_validators(a_session->chain->net_id, false); + dap_list_t *l_validators = dap_chain_net_srv_stake_get_validators(a_session->chain->net_id, false, NULL); a_session->cur_round.all_validators = dap_list_copy_deep(l_validators, s_callback_list_form, NULL); dap_list_free_full(l_validators, NULL); bool l_round_already_started = a_session->round_fast_forward; @@ -1035,6 +1113,7 @@ static void s_session_round_new(dap_chain_esbocs_session_t *a_session) a_session->round_fast_forward = false; a_session->sync_failed = false; a_session->listen_ensure = 0; + return false; } static void s_session_attempt_new(dap_chain_esbocs_session_t *a_session) @@ -1314,7 +1393,8 @@ static void s_session_state_change(dap_chain_esbocs_session_t *a_session, enum s s_session_state_change(a_session, a_session->old_state, a_time); else { log_it(L_ERROR, "No previous state registered, can't roll back"); - s_session_round_new(a_session); + dap_proc_thread_t *l_thread = DAP_PROC_THREAD(dap_context_current()); + dap_proc_thread_callback_add(l_thread, s_session_round_new, a_session); } } default: @@ -1322,117 +1402,115 @@ static void s_session_state_change(dap_chain_esbocs_session_t *a_session, enum s } } -static void s_session_proc_state(dap_chain_esbocs_session_t *a_session) +static void s_session_proc_state(void *a_arg) { - if (pthread_mutex_trylock(&a_session->mutex) != 0) + dap_chain_esbocs_session_t *l_session = a_arg; + if (!l_session->cs_timer) + return; // Timer is inactive + if (pthread_mutex_trylock(&l_session->mutex) != 0) return; // Session is busy - bool l_cs_debug = PVT(a_session->esbocs)->debug; + bool l_cs_debug = PVT(l_session->esbocs)->debug; dap_time_t l_time = dap_time_now(); - switch (a_session->state) { + switch (l_session->state) { case DAP_CHAIN_ESBOCS_SESSION_STATE_WAIT_START: { - a_session->listen_ensure = 1; - bool l_round_skip = PVT(a_session->esbocs)->emergency_mode ? - false : !s_validator_check(&a_session->my_signing_addr, a_session->cur_round.validators_list); - if (a_session->ts_round_sync_start && l_time - a_session->ts_round_sync_start >= - (dap_time_t)PVT(a_session->esbocs)->round_start_sync_timeout + - (a_session->sync_failed ? s_get_round_skip_timeout(a_session) : 0)) { - if (a_session->cur_round.attempt_num > PVT(a_session->esbocs)->round_attempts_max ) { - debug_if(PVT(a_session->esbocs)->debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U"." + l_session->listen_ensure = 1; + bool l_round_skip = PVT(l_session->esbocs)->emergency_mode ? + false : !s_validator_check(&l_session->my_signing_addr, l_session->cur_round.validators_list); + if (l_session->ts_round_sync_start && l_time - l_session->ts_round_sync_start >= + (dap_time_t)PVT(l_session->esbocs)->round_start_sync_timeout + + (l_session->sync_failed ? s_get_round_skip_timeout(l_session) : 0)) { + if (l_session->cur_round.attempt_num > PVT(l_session->esbocs)->round_attempts_max ) { + debug_if(PVT(l_session->esbocs)->debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U"." " Round finished by reason: attempts is out", - a_session->chain->net_name, a_session->chain->name, - a_session->cur_round.id); - s_session_round_new(a_session); + l_session->chain->net_name, l_session->chain->name, + l_session->cur_round.id); + dap_proc_thread_t *l_thread = DAP_PROC_THREAD(dap_context_current()); + dap_proc_thread_callback_add(l_thread, s_session_round_new, l_session); break; } - uint16_t l_min_validators_synced = PVT(a_session->esbocs)->emergency_mode ? - a_session->cur_round.total_validators_synced : a_session->cur_round.validators_synced_count; - if (l_min_validators_synced >= PVT(a_session->esbocs)->min_validators_count && !l_round_skip) { - a_session->cur_round.id = s_session_calc_current_round_id(a_session); + uint16_t l_min_validators_synced = PVT(l_session->esbocs)->emergency_mode ? + l_session->cur_round.total_validators_synced : l_session->cur_round.validators_synced_count; + if (l_min_validators_synced >= PVT(l_session->esbocs)->min_validators_count && !l_round_skip) { + l_session->cur_round.id = s_session_calc_current_round_id(l_session); debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu." " Minimum count of validators are synchronized, wait to submit candidate", - a_session->chain->net_name, a_session->chain->name, - a_session->cur_round.id, a_session->cur_round.attempt_num); - s_session_state_change(a_session, DAP_CHAIN_ESBOCS_SESSION_STATE_WAIT_PROC, l_time); + l_session->chain->net_name, l_session->chain->name, + l_session->cur_round.id, l_session->cur_round.attempt_num); + s_session_state_change(l_session, DAP_CHAIN_ESBOCS_SESSION_STATE_WAIT_PROC, l_time); } else { // timeout start sync debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu." " Round finished by reason: %s", - a_session->chain->net_name, a_session->chain->name, - a_session->cur_round.id, a_session->cur_round.attempt_num, + l_session->chain->net_name, l_session->chain->name, + l_session->cur_round.id, l_session->cur_round.attempt_num, l_round_skip ? "skipped" : "can't synchronize minimum number of validators"); - a_session->sync_failed = true; - s_session_round_new(a_session); + l_session->sync_failed = true; + dap_proc_thread_t *l_thread = DAP_PROC_THREAD(dap_context_current()); + dap_proc_thread_callback_add(l_thread, s_session_round_new, l_session); } } } break; case DAP_CHAIN_ESBOCS_SESSION_STATE_WAIT_PROC: - if (l_time - a_session->ts_stage_entry >= PVT(a_session->esbocs)->round_attempt_timeout * a_session->listen_ensure) { - a_session->listen_ensure += 2; + if (l_time - l_session->ts_stage_entry >= PVT(l_session->esbocs)->round_attempt_timeout * l_session->listen_ensure) { + l_session->listen_ensure += 2; debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu." " Attempt finished by reason: haven't cantidate submitted", - a_session->chain->net_name, a_session->chain->name, - a_session->cur_round.id, a_session->cur_round.attempt_num); - s_session_attempt_new(a_session); + l_session->chain->net_name, l_session->chain->name, + l_session->cur_round.id, l_session->cur_round.attempt_num); + s_session_attempt_new(l_session); } break; case DAP_CHAIN_ESBOCS_SESSION_STATE_WAIT_SIGNS: - if (l_time - a_session->ts_stage_entry >= PVT(a_session->esbocs)->round_attempt_timeout) { + if (l_time - l_session->ts_stage_entry >= PVT(l_session->esbocs)->round_attempt_timeout) { dap_chain_esbocs_store_t *l_store; - HASH_FIND(hh, a_session->cur_round.store_items, &a_session->cur_round.attempt_candidate_hash, sizeof(dap_hash_fast_t), l_store); + HASH_FIND(hh, l_session->cur_round.store_items, &l_session->cur_round.attempt_candidate_hash, sizeof(dap_hash_fast_t), l_store); if (!l_store) { log_it(L_ERROR, "No round candidate found!"); - s_session_attempt_new(a_session); + s_session_attempt_new(l_session); break; } - if (dap_list_length(l_store->candidate_signs) >= PVT(a_session->esbocs)->min_validators_count) { + if (dap_list_length(l_store->candidate_signs) >= PVT(l_session->esbocs)->min_validators_count) { if(l_cs_debug) { - const 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(&l_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, - a_session->cur_round.attempt_num, l_candidate_hash_str); + l_session->chain->net_name, l_session->chain->name, l_session->cur_round.id, + l_session->cur_round.attempt_num, l_candidate_hash_str); } - s_session_state_change(a_session, DAP_CHAIN_ESBOCS_SESSION_STATE_WAIT_FINISH, l_time); + s_session_state_change(l_session, DAP_CHAIN_ESBOCS_SESSION_STATE_WAIT_FINISH, l_time); break; } debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu." " Attempt finished by reason: cant't collect minimum number of validator's signs", - a_session->chain->net_name, a_session->chain->name, - a_session->cur_round.id, a_session->cur_round.attempt_num); - s_session_attempt_new(a_session); + l_session->chain->net_name, l_session->chain->name, + l_session->cur_round.id, l_session->cur_round.attempt_num); + s_session_attempt_new(l_session); } break; case DAP_CHAIN_ESBOCS_SESSION_STATE_WAIT_FINISH: - if (l_time - a_session->ts_stage_entry >= PVT(a_session->esbocs)->round_attempt_timeout * 2) { + if (l_time - l_session->ts_stage_entry >= PVT(l_session->esbocs)->round_attempt_timeout * 2) { debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu." " Attempt finished by reason: cant't collect minimum number of validator's precommits with same final hash", - a_session->chain->net_name, a_session->chain->name, - a_session->cur_round.id, a_session->cur_round.attempt_num); - s_session_attempt_new(a_session); + l_session->chain->net_name, l_session->chain->name, + l_session->cur_round.id, l_session->cur_round.attempt_num); + s_session_attempt_new(l_session); } break; case DAP_CHAIN_ESBOCS_SESSION_STATE_WAIT_VOTING: - if (l_time - a_session->ts_stage_entry >= PVT(a_session->esbocs)->round_attempt_timeout * 2) { - const char *l_hash_str = dap_chain_hash_fast_to_str_static(&a_session->cur_round.directive_hash); + if (l_time - l_session->ts_stage_entry >= PVT(l_session->esbocs)->round_attempt_timeout * 2) { + const char *l_hash_str = dap_chain_hash_fast_to_str_static(&l_session->cur_round.directive_hash); debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu." " Voting finished by reason: cant't collect minimum number of validator's votes for directive %s", - a_session->chain->net_name, a_session->chain->name, - a_session->cur_round.id, a_session->cur_round.attempt_num, + l_session->chain->net_name, l_session->chain->name, + l_session->cur_round.id, l_session->cur_round.attempt_num, l_hash_str); - s_session_state_change(a_session, DAP_CHAIN_ESBOCS_SESSION_STATE_PREVIOUS, l_time); + s_session_state_change(l_session, DAP_CHAIN_ESBOCS_SESSION_STATE_PREVIOUS, l_time); } break; default: break; } - pthread_mutex_unlock(&a_session->mutex); -} - -static bool s_session_timer(void *a_arg) -{ - dap_chain_esbocs_session_t *l_session = a_arg; - s_session_proc_state(l_session); - return true; + pthread_mutex_unlock(&l_session->mutex); } static void s_message_chain_add(dap_chain_esbocs_session_t *a_session, @@ -1463,20 +1541,34 @@ static void s_session_candidate_submit(dap_chain_esbocs_session_t *a_session) { dap_chain_t *l_chain = a_session->chain; dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(l_chain); - dap_chain_block_t *l_candidate; size_t l_candidate_size = 0; dap_hash_fast_t l_candidate_hash = {0}; dap_chain_node_mempool_process_all(a_session->chain, false); - l_candidate = l_blocks->callback_new_block_move(l_blocks, &l_candidate_size); - if (l_candidate_size) { - dap_hash_fast(l_candidate, l_candidate_size, &l_candidate_hash); - if (PVT(a_session->esbocs)->debug) { - 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); + dap_chain_block_t *l_candidate = l_blocks->callback_new_block_move(l_blocks, &l_candidate_size); + if (l_candidate && l_candidate_size) { + if (PVT(a_session->esbocs)->emergency_mode) + l_candidate_size = dap_chain_block_meta_add(&l_candidate, l_candidate_size, DAP_CHAIN_BLOCK_META_EMERGENCY, NULL, 0); + if (PVT(a_session->esbocs)->check_signs_structure && l_candidate_size) { + l_candidate_size = dap_chain_block_meta_add(&l_candidate, l_candidate_size, DAP_CHAIN_BLOCK_META_SYNC_ATTEMPT, + &a_session->cur_round.sync_attempt, sizeof(uint64_t)); + if (l_candidate_size) + l_candidate_size = dap_chain_block_meta_add(&l_candidate, l_candidate_size, DAP_CHAIN_BLOCK_META_ROUND_ATTEMPT, + &a_session->cur_round.attempt_num, sizeof(uint8_t)); + if (l_candidate_size) + l_candidate_size = dap_chain_block_meta_add(&l_candidate, l_candidate_size, DAP_CHAIN_BLOCK_META_EXCLUDED_KEYS, + a_session->cur_round.excluded_list, *a_session->cur_round.excluded_list * sizeof(uint16_t)); + } + if (l_candidate_size) { + dap_hash_fast(l_candidate, l_candidate_size, &l_candidate_hash); + if (PVT(a_session->esbocs)->debug) { + 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); + } } - } else { // there is no my candidate, send null hash + } + if (!l_candidate || !l_candidate_size) { // there is no my candidate, send null hash if (PVT(a_session->esbocs)->debug) log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu." " I don't have a candidate. I submit a null candidate.", @@ -1688,7 +1780,7 @@ void s_session_sync_queue_add(dap_chain_esbocs_session_t *a_session, dap_chain_e void *l_message_copy = DAP_DUP_SIZE(a_message, a_message_size); if (!l_message_copy) { - log_it(L_CRITICAL, g_error_memory_alloc); + log_it(L_CRITICAL, "%s", g_error_memory_alloc); return; } dap_chain_esbocs_sync_item_t *l_sync_item; @@ -1910,6 +2002,70 @@ static int s_session_directive_apply(dap_chain_esbocs_directive_t *a_directive, return 0; } +DAP_STATIC_INLINE bool s_block_is_emergency(dap_chain_block_t *a_block, size_t a_block_size) +{ + return dap_chain_block_meta_get(a_block, a_block_size, DAP_CHAIN_BLOCK_META_EMERGENCY); +} + +static dap_list_t *s_check_emergency_rights(dap_chain_esbocs_t *a_esbocs, dap_chain_addr_t *a_signing_addr) +{ + for (dap_list_t *it = PVT(a_esbocs)->emergency_validator_addrs; it; it = it->next) { + dap_chain_addr_t *l_authorized_pkey = it->data; + if (dap_hash_fast_compare(&l_authorized_pkey->data.hash_fast, &a_signing_addr->data.hash_fast)) + return it; + } + return NULL; +} + +static bool s_check_signing_rights(dap_chain_esbocs_t *a_esbocs, dap_chain_block_t *a_block, size_t a_block_size, + dap_chain_addr_t *a_signing_addr, bool a_first_sign) +{ + uint8_t *l_sync_attempt_ptr = dap_chain_block_meta_get(a_block, a_block_size, DAP_CHAIN_BLOCK_META_SYNC_ATTEMPT); + if (!l_sync_attempt_ptr) { + log_it(L_ERROR, "Can't get block metadata for SYNC_ATTEMPT"); + return false; + } + uint64_t l_sync_attempt = *(uint64_t *)l_sync_attempt_ptr; + uint8_t l_round_attempt = 0; + if (a_first_sign) { + uint8_t *l_round_attempt_ptr = dap_chain_block_meta_get(a_block, a_block_size, DAP_CHAIN_BLOCK_META_ROUND_ATTEMPT); + if (!l_round_attempt_ptr) { + log_it(L_ERROR, "Can't get block metadata for ROUND_ATTEMPT"); + return false; + } + l_round_attempt = *l_round_attempt_ptr; + } + dap_hash_fast_t *l_prev_hash_ptr = (dap_hash_fast_t *)dap_chain_block_meta_get(a_block, a_block_size, DAP_CHAIN_BLOCK_META_PREV); + if (!l_prev_hash_ptr) { + log_it(L_ERROR, "Can't get block metadata for PREV_HASH"); + return false; + } + uint16_t *l_excluded_list = (uint16_t *)dap_chain_block_meta_get(a_block, a_block_size, DAP_CHAIN_BLOCK_META_EXCLUDED_KEYS); + if (!l_excluded_list) { + log_it(L_ERROR, "Can't get block metadata for EXCLUDED_KEYS"); + return false; + } + dap_list_t *l_allowed_validators_list = s_get_validators_list(a_esbocs, l_prev_hash_ptr, l_sync_attempt - 1, + l_excluded_list + 1, *l_excluded_list); + if (!l_allowed_validators_list) { + log_it(L_ERROR, "Can't get block allowed validators list"); + return false; + } + if (a_first_sign) { + size_t l_list_len = dap_list_length(l_allowed_validators_list); + if (l_list_len < l_round_attempt) { + log_it(L_ERROR, "Round attempt %hhu is greater than length of allowed validators list %zu", + l_round_attempt, l_list_len); + return false; + } + dap_chain_esbocs_validator_t *l_chosen_validator = dap_list_nth(l_allowed_validators_list, l_round_attempt)->data; + if (dap_hash_fast_compare(&l_chosen_validator->signing_addr.data.hash_fast, &a_signing_addr->data.hash_fast)) + return true; + return false; + } + return s_validator_check(a_signing_addr, l_allowed_validators_list); +} + struct esbocs_msg_args { dap_stream_node_addr_t addr_from; dap_chain_esbocs_session_t *session; @@ -1975,7 +2131,7 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg) NODE_ADDR_FP_ARGS_S(a_ch->stream->node), NODE_ADDR_FP_ARGS_S(l_session->my_addr)); 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); + log_it(L_CRITICAL, "%s", g_error_memory_alloc); return false; } l_args->addr_from = a_ch->stream->node; @@ -2115,7 +2271,7 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain } if (l_not_in_list) { debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu." - " Message rejected: validator addr:%s not in the current validators list or not synced yet", + " Message rejected: validator key:%s not in the current validators list or not synced yet", l_session->chain->net_name, l_session->chain->name, l_session->cur_round.id, l_message->hdr.attempt_num, l_validator_addr_str); goto session_unlock; @@ -2132,8 +2288,9 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain " Receive START_SYNC: from validator:%s, sync attempt %"DAP_UINT64_FORMAT_U, l_session->chain->net_name, l_session->chain->name, l_message->hdr.round_id, l_validator_addr_str, l_sync_attempt); + dap_global_db_driver_hash_t l_msg_hash = ((struct sync_params *)l_message_data)->db_hash, l_session_hash = l_session->db_hash; if (!PVT(l_session->esbocs)->emergency_mode && - dap_global_db_driver_hash_compare(((struct sync_params *)l_message_data)->db_hash, l_session->db_hash)) { + dap_global_db_driver_hash_compare(&l_msg_hash, &l_session_hash)) { debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", sync_attempt %"DAP_UINT64_FORMAT_U " SYNC message is rejected cause DB hash mismatch", l_session->chain->net_name, l_session->chain->name, l_session->cur_round.id, @@ -2173,7 +2330,8 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain l_session->round_fast_forward = true; l_session->cur_round.id = l_message->hdr.round_id - 1; l_session->cur_round.sync_attempt = l_sync_attempt - 1; - s_session_round_new(l_session); + dap_proc_thread_t *l_thread = DAP_PROC_THREAD(dap_context_current()); + dap_proc_thread_callback_add(l_thread, s_session_round_new, l_session); } } } else // Send it immediatly, if was not sent yet @@ -2200,13 +2358,25 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain case DAP_CHAIN_ESBOCS_MSG_TYPE_SUBMIT: { uint8_t *l_candidate = l_message_data; size_t l_candidate_size = l_message_data_size; + // check submission rights + if (s_block_is_emergency((dap_chain_block_t *)l_candidate, l_candidate_size)) { + if (!s_check_emergency_rights(l_session->esbocs, &l_signing_addr)) { + debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu." + " Decline emergency SUBMIT candidate from not authorized validator %s", + l_session->chain->net_name, l_session->chain->name, + l_session->cur_round.id, l_message->hdr.attempt_num, + l_validator_addr_str); + break; + } + l_session->cur_round.attempt_submit_validator = l_signing_addr; + } + // check for NULL candidate if (!l_candidate_size || dap_hash_fast_is_blank(&l_message->hdr.candidate_hash)) { debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu." " Receive SUBMIT candidate NULL", l_session->chain->net_name, l_session->chain->name, l_session->cur_round.id, l_message->hdr.attempt_num); - if (dap_chain_addr_compare(&l_session->cur_round.attempt_submit_validator, &l_signing_addr)) - s_session_attempt_new(l_session); + s_session_attempt_new(l_session); break; } // check candidate hash @@ -2214,12 +2384,11 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain dap_hash_fast(l_candidate, l_candidate_size, &l_check_hash); if (!dap_hash_fast_compare(&l_check_hash, l_candidate_hash)) { debug_if(l_cs_debug, L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu." - " Receive SUBMIT candidate hash broken", + " Decline SUBMIT candidate with broken hash", l_session->chain->net_name, l_session->chain->name, l_session->cur_round.id, l_message->hdr.attempt_num); break; } - if (l_cs_debug) { 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." @@ -2331,13 +2500,21 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain if (!l_store) { l_candidate_hash_str = dap_chain_hash_fast_to_str_static(l_candidate_hash); log_it(L_WARNING, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu." - " Receive COMMIT_SIGN message for unknown candidate %s", + " Decline COMMIT_SIGN message for unknown candidate %s", l_session->chain->net_name, l_session->chain->name, l_session->cur_round.id, l_message->hdr.attempt_num, l_candidate_hash_str); break; } - + dap_list_t *l_list = s_validator_check(&l_signing_addr, l_session->cur_round.validators_list); + if (!l_list) { + log_it(L_WARNING, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu." + " Decline COMMIT_SIGN message for validator %s not present in current validator's list", + l_session->chain->net_name, l_session->chain->name, + l_session->cur_round.id, l_message->hdr.attempt_num, + l_validator_addr_str); + break; + } if (l_cs_debug) { 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." @@ -2345,26 +2522,25 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain l_session->chain->net_name, l_session->chain->name, l_session->cur_round.id, l_message->hdr.attempt_num, l_candidate_hash_str); } - + // check candidate's sign size_t l_offset = dap_chain_block_get_sign_offset(l_store->candidate, l_store->candidate_size); int l_sign_verified = dap_sign_verify(l_candidate_sign, l_store->candidate, l_offset + sizeof(l_store->candidate->hdr)); - // check candidate's sign - if (!l_sign_verified) { - l_store->candidate_signs = dap_list_append(l_store->candidate_signs, - DAP_DUP_SIZE(l_candidate_sign, l_candidate_sign_size)); - if (dap_list_length(l_store->candidate_signs) == l_round->validators_synced_count) { - if (PVT(l_session->esbocs)->debug) - log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu." - " Candidate %s collected signs of all synced validators", - l_session->chain->net_name, l_session->chain->name, l_round->id, - l_message->hdr.attempt_num, l_candidate_hash_str); - s_session_state_change(l_session, DAP_CHAIN_ESBOCS_SESSION_STATE_WAIT_FINISH, dap_time_now()); - } - } else { + if (l_sign_verified != 0) { if (!l_candidate_hash_str) l_candidate_hash_str = dap_chain_hash_fast_to_str_static(l_candidate_hash); log_it(L_WARNING, "Candidate: %s sign is incorrect: code %d", l_candidate_hash_str, l_sign_verified); + break; + } + l_store->candidate_signs = dap_list_append(l_store->candidate_signs, + DAP_DUP_SIZE(l_candidate_sign, l_candidate_sign_size)); + if (dap_list_length(l_store->candidate_signs) == l_round->validators_synced_count) { + if (PVT(l_session->esbocs)->debug) + log_it(L_MSG, "net:%s, chain:%s, round:%"DAP_UINT64_FORMAT_U", attempt:%hhu." + " Candidate %s collected signs of all synced validators", + l_session->chain->net_name, l_session->chain->name, l_round->id, + l_message->hdr.attempt_num, l_candidate_hash_str); + s_session_state_change(l_session, DAP_CHAIN_ESBOCS_SESSION_STATE_WAIT_FINISH, dap_time_now()); } } break; @@ -2510,7 +2686,7 @@ static void s_message_send(dap_chain_esbocs_session_t *a_session, uint8_t a_mess struct esbocs_msg_args *l_args = DAP_NEW_SIZE(struct esbocs_msg_args, sizeof(struct esbocs_msg_args) + l_message_size + l_sign_size); if (!l_args) { - log_it(L_CRITICAL, g_error_memory_alloc); + log_it(L_CRITICAL, "%s", g_error_memory_alloc); return; } l_args->addr_from = a_session->my_addr; @@ -2540,6 +2716,49 @@ static size_t s_callback_block_sign(dap_chain_cs_blocks_t *a_blocks, dap_chain_b return dap_chain_block_sign_add(a_block_ptr, a_block_size, l_esbocs_pvt->blocks_sign_key); } +static uint64_t s_get_precached_key_hash(struct precached_key **a_precached_keys_list, dap_sign_t *a_source_sign, dap_hash_fast_t *a_result) +{ + bool l_found = false; + struct precached_key *l_key = NULL; + DL_FOREACH(*a_precached_keys_list, l_key) { + if (l_key->pkey_size == a_source_sign->header.sign_pkey_size && + !memcmp(l_key->sign_pkey, dap_sign_get_pkey(a_source_sign, NULL), l_key->pkey_size)) { + l_found = true; + l_key->frequency++; + break; + } + } + if (l_found) { + struct precached_key *l_key_swap = NULL; + DL_FOREACH(*a_precached_keys_list, l_key_swap) { + if (l_key_swap == l_key) + break; + if (l_key_swap->frequency < l_key->frequency) { + struct precached_key *l_swapper = l_key->next; + l_key->next = l_key_swap->next; + l_key_swap->next = l_swapper; + l_swapper = l_key->prev; + l_key->prev = l_key_swap->prev; + l_key_swap->prev = l_swapper; + break; + } + } + if (a_result) + *a_result = l_key->pkey_hash; + return l_key->frequency; + } + struct precached_key *l_key_new = DAP_NEW_SIZE(struct precached_key, + sizeof(struct precached_key) + a_source_sign->header.sign_pkey_size); + l_key_new->pkey_size = a_source_sign->header.sign_pkey_size; + l_key_new->frequency = 0; + memcpy(l_key_new->sign_pkey, dap_sign_get_pkey(a_source_sign, NULL), l_key_new->pkey_size); + dap_sign_get_pkey_hash(a_source_sign, &l_key_new->pkey_hash); + DL_APPEND(*a_precached_keys_list, l_key_new); + if (a_result) + *a_result = l_key_new->pkey_hash; + return 0; +} + static int s_callback_block_verify(dap_chain_cs_blocks_t *a_blocks, dap_chain_block_t *a_block, size_t a_block_size) { dap_chain_esbocs_t *l_esbocs = DAP_CHAIN_ESBOCS(a_blocks); @@ -2550,10 +2769,11 @@ static int s_callback_block_verify(dap_chain_cs_blocks_t *a_blocks, dap_chain_bl return -7; } - /*if (a_block->hdr.meta_n_datum_n_signs_size != a_block_size - sizeof(a_block->hdr)) { + if (a_block->hdr.meta_n_datum_n_signs_size && + a_block->hdr.meta_n_datum_n_signs_size != a_block_size - sizeof(a_block->hdr)) { log_it(L_WARNING, "Incorrect size with block %p on chain %s", a_block, a_blocks->chain->name); return -8; - }*/ // TODO Retun it after hard-fork with correct block sizes + } if (l_esbocs->session && l_esbocs->session->processing_candidate == a_block) // It's a block candidate, don't check signs @@ -2583,19 +2803,19 @@ static int s_callback_block_verify(dap_chain_cs_blocks_t *a_blocks, dap_chain_bl int l_ret = 0; uint16_t l_signs_verified_count = 0; size_t l_block_excl_sign_size = dap_chain_block_get_sign_offset(a_block, a_block_size) + sizeof(a_block->hdr); + bool l_block_is_emergency = s_block_is_emergency(a_block, a_block_size); // Get the header on signing operation time size_t l_block_original = a_block->hdr.meta_n_datum_n_signs_size; a_block->hdr.meta_n_datum_n_signs_size = l_block_excl_sign_size - sizeof(a_block->hdr); - for (size_t i=0; i< l_signs_count; i++) { - dap_sign_t *l_sign = (dap_sign_t *)l_signs[i]; + for (size_t i = 0; i < l_signs_count; i++) { + dap_sign_t *l_sign = l_signs[i]; if (!dap_sign_verify_size(l_sign, a_block_size - l_block_excl_sign_size + sizeof(a_block->hdr))) { log_it(L_ERROR, "Corrupted block: sign size is bigger than block size"); l_ret = -3; break; } - - dap_chain_addr_t l_signing_addr; - dap_chain_addr_fill_from_sign(&l_signing_addr, l_sign, a_blocks->chain->net_id); + dap_chain_addr_t l_signing_addr = { .net_id = a_blocks->chain->net_id }; + s_get_precached_key_hash(&l_esbocs_pvt->precached_keys, l_sign, &l_signing_addr.data.hash_fast); if (!l_esbocs_pvt->poa_mode) { // Compare signature with delegated keys if (!dap_chain_net_srv_stake_key_delegated(&l_signing_addr)) { @@ -2611,6 +2831,35 @@ static int s_callback_block_verify(dap_chain_cs_blocks_t *a_blocks, dap_chain_bl continue; } } + if (i == 0) { + if (l_block_is_emergency && !s_check_emergency_rights(l_esbocs, &l_signing_addr)) { + log_it(L_ATT, "Restricted emergency block submitter %s", + dap_chain_hash_fast_to_str_static(&l_signing_addr.data.hash_fast)); + l_ret = -5; + break; + } else if (l_esbocs_pvt->check_signs_structure && + !s_check_signing_rights(l_esbocs, a_block, a_block_size, &l_signing_addr, true)) { + log_it(L_ATT, "Restricted block submitter %s", + dap_chain_hash_fast_to_str_static(&l_signing_addr.data.hash_fast)); + l_ret = -5; + break; + } + } else { + if (l_block_is_emergency && !s_check_emergency_rights(l_esbocs, &l_signing_addr) && + l_esbocs_pvt->check_signs_structure && + !s_check_signing_rights(l_esbocs, a_block, a_block_size, &l_signing_addr, false)) { + log_it(L_ATT, "Restricted emergency block signer %s", + dap_chain_hash_fast_to_str_static(&l_signing_addr.data.hash_fast)); + l_ret = -5; + break; + } else if (l_esbocs_pvt->check_signs_structure && + !s_check_signing_rights(l_esbocs, a_block, a_block_size, &l_signing_addr, false)) { + log_it(L_ATT, "Restricted block signer %s", + dap_chain_hash_fast_to_str_static(&l_signing_addr.data.hash_fast)); + l_ret = -5; + break; + } + } if (!dap_sign_verify(l_sign, a_block, l_block_excl_sign_size)) l_signs_verified_count++; } @@ -2649,73 +2898,56 @@ static dap_chain_datum_decree_t *s_esbocs_decree_set_min_validators_count(dap_ch uint256_t a_value, dap_cert_t *a_cert) { size_t l_total_tsd_size = sizeof(dap_tsd_t) + sizeof(uint256_t); - dap_chain_datum_decree_t *l_decree = NULL; - dap_list_t *l_tsd_list = NULL; - dap_tsd_t *l_tsd = NULL; -// memory alloc - DAP_NEW_Z_SIZE_RET_VAL(l_tsd, dap_tsd_t, l_total_tsd_size, NULL, NULL); - DAP_NEW_Z_SIZE_RET_VAL(l_decree, dap_chain_datum_decree_t, sizeof(dap_chain_datum_decree_t) + l_total_tsd_size, NULL, l_tsd); - - l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT; - l_tsd->size = sizeof(uint256_t); - *(uint256_t*)(l_tsd->data) = a_value; - l_tsd_list = dap_list_append(l_tsd_list, l_tsd); - - l_decree->decree_version = DAP_CHAIN_DATUM_DECREE_VERSION; - l_decree->header.ts_created = dap_time_now(); - l_decree->header.type = DAP_CHAIN_DATUM_DECREE_TYPE_COMMON; - l_decree->header.common_decree_params.net_id = a_net->pub.id; - dap_chain_t *l_chain = a_chain; - if (!a_chain) - l_chain = dap_chain_net_get_default_chain_by_chain_type(a_net, CHAIN_TYPE_ANCHOR); - if(!l_chain){ - log_it(L_ERROR, "Can't find chain with anchor support."); - dap_list_free_full(l_tsd_list, NULL); - DAP_DELETE(l_decree); + dap_chain_datum_decree_t *l_decree = dap_chain_datum_decree_new(a_net->pub.id, a_chain->id, + *dap_chain_net_get_cur_cell(a_net), l_total_tsd_size); + if (!l_decree) return NULL; - } - l_decree->header.common_decree_params.chain_id = l_chain->id; - l_decree->header.common_decree_params.cell_id = *dap_chain_net_get_cur_cell(a_net); l_decree->header.sub_type = DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALIDATORS_COUNT; - l_decree->header.data_size = l_total_tsd_size; - l_decree->header.signs_size = 0; - - size_t l_data_tsd_offset = 0; - for ( dap_list_t* l_iter=dap_list_first(l_tsd_list); l_iter; l_iter=l_iter->next){ - dap_tsd_t * l_b_tsd = (dap_tsd_t *) l_iter->data; - size_t l_tsd_size = dap_tsd_size(l_b_tsd); - memcpy((byte_t*)l_decree->data_n_signs + l_data_tsd_offset, l_b_tsd, l_tsd_size); - l_data_tsd_offset += l_tsd_size; - } - dap_list_free_full(l_tsd_list, NULL); - - size_t l_cur_sign_offset = l_decree->header.data_size + l_decree->header.signs_size; - size_t l_total_signs_size = l_decree->header.signs_size; + dap_tsd_write(l_decree->data_n_signs, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT, &a_value, sizeof(uint256_t)); + return dap_chain_datum_decree_sign_in_cycle(&a_cert, l_decree, 1, NULL); +} - dap_sign_t * l_sign = dap_cert_sign(a_cert, l_decree, - sizeof(dap_chain_datum_decree_t) + l_decree->header.data_size, 0); +static dap_chain_datum_decree_t *s_esbocs_decree_set_signs_check(dap_chain_net_t *a_net, dap_chain_t *a_chain, + bool a_enable, dap_cert_t *a_cert) +{ + size_t l_total_tsd_size = sizeof(dap_tsd_t) + sizeof(uint8_t); + dap_chain_datum_decree_t *l_decree = dap_chain_datum_decree_new(a_net->pub.id, a_chain->id, + *dap_chain_net_get_cur_cell(a_net), l_total_tsd_size); + if (!l_decree) + return NULL; + l_decree->header.sub_type = DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_CHECK_SIGNS_STRUCTURE; + uint8_t l_data = a_enable ? 1 : 0; + dap_tsd_write(l_decree->data_n_signs, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_ACTION, &l_data, sizeof(uint8_t)); + return dap_chain_datum_decree_sign_in_cycle(&a_cert, l_decree, 1, NULL); +} - if (l_sign) { - size_t l_sign_size = dap_sign_get_size(l_sign); - l_decree = DAP_REALLOC(l_decree, sizeof(dap_chain_datum_decree_t) + l_cur_sign_offset + l_sign_size); - if (!l_decree) { - log_it(L_CRITICAL, "%s", g_error_memory_alloc); - DAP_DELETE(l_sign); - return NULL; - } - memcpy((byte_t*)l_decree->data_n_signs + l_cur_sign_offset, l_sign, l_sign_size); - l_total_signs_size += l_sign_size; - l_cur_sign_offset += l_sign_size; - l_decree->header.signs_size = l_total_signs_size; - DAP_DELETE(l_sign); - log_it(L_DEBUG,"<-- Signed with '%s'", a_cert->name); - }else{ - log_it(L_ERROR, "Decree signing failed"); - DAP_DELETE(l_decree); +static dap_chain_datum_decree_t *s_esbocs_decree_set_emergency_validator(dap_chain_net_t *a_net, dap_chain_t *a_chain, + dap_hash_fast_t *a_pkey_hash, dap_sign_type_t a_sign_type, + bool a_add, dap_cert_t *a_cert) +{ + size_t l_total_tsd_size = sizeof(dap_tsd_t) * 3 + sizeof(uint8_t) + sizeof(uint32_t) + sizeof(dap_hash_fast_t); + dap_chain_datum_decree_t *l_decree = dap_chain_datum_decree_new(a_net->pub.id, a_chain->id, + *dap_chain_net_get_cur_cell(a_net), l_total_tsd_size); + if (!l_decree) return NULL; - } + l_decree->header.sub_type = DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_EMERGENCY_VALIDATORS; + uint8_t l_data = a_add ? 1 : 0; + byte_t *l_ptr = dap_tsd_write(l_decree->data_n_signs, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_ACTION, &l_data, sizeof(uint8_t)); + uint32_t l_type_numeric = a_sign_type.type; + l_ptr = dap_tsd_write(l_ptr, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGNATURE_TYPE, &l_type_numeric, sizeof(uint32_t)); + dap_tsd_write(l_ptr, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HASH, a_pkey_hash, sizeof(dap_hash_fast_t)); + return dap_chain_datum_decree_sign_in_cycle(&a_cert, l_decree, 1, NULL); +} - return l_decree; +static void s_print_emergency_validators(char **a_str_reply, dap_list_t *a_validator_addrs) +{ + dap_string_t *l_str_out = dap_string_new("Current emergency validators list:\n"); + for (dap_list_t *it = a_validator_addrs; it; it = it->next) { + dap_chain_addr_t *l_addr = it->data; + dap_string_append_printf(l_str_out, "%s\n", dap_chain_hash_fast_to_str_static(&l_addr->data.hash_fast)); + } + *a_str_reply = l_str_out->str; + dap_string_free(l_str_out, false); } /** @@ -2729,65 +2961,166 @@ static dap_chain_datum_decree_t *s_esbocs_decree_set_min_validators_count(dap_ch */ static int s_cli_esbocs(int a_argc, char **a_argv, void **a_str_reply) { - int ret = -666; - int l_arg_index = 2; - dap_chain_net_t * l_chain_net = NULL; - dap_chain_t * l_chain = NULL; - const char *l_cert_str = NULL, - *l_value_str = NULL; + int l_arg_index = 1; + dap_chain_net_t *l_chain_net = NULL; + dap_chain_t *l_chain = NULL; - if (dap_chain_node_cli_cmd_values_parse_net_chain(&l_arg_index, a_argc, a_argv, a_str_reply, &l_chain, &l_chain_net)) + if (dap_chain_node_cli_cmd_values_parse_net_chain(&l_arg_index, a_argc, a_argv, a_str_reply, &l_chain, &l_chain_net, + CHAIN_TYPE_ANCHOR)) return -3; - const char *l_chain_type = dap_chain_net_get_type(l_chain); + const char *l_chain_type = dap_chain_get_cs_type(l_chain); if (strcmp(l_chain_type, "esbocs")) { dap_cli_server_cmd_set_reply_text(a_str_reply, "Type of chain \"%s\" is not block. Chain with current consensus \"%s\" is not supported by this command", l_chain->name, l_chain_type); - return ret; + return -2; } + dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(l_chain); + dap_chain_esbocs_t *l_esbocs = DAP_CHAIN_ESBOCS(l_blocks); + dap_chain_esbocs_pvt_t *l_esbocs_pvt = PVT(l_esbocs); - if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, l_arg_index + 1, "set", NULL)) { - dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-cert", &l_cert_str); - if (!l_cert_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'min_validators_count' requires parameter -cert"); - return -3; - } - dap_cert_t *l_poa_cert = dap_cert_find_by_name(l_cert_str); - if (!l_poa_cert) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate not found"); - return -25; - } + enum { + SUBCMD_UNDEFINED = 0, + SUBCMD_MIN_VALIDATORS_COUNT, + SUBCMD_CHECK_SIGNS_STRUCTURE, + SUBCMD_EMERGENCY_VALIDATOR + } l_subcmd = SUBCMD_UNDEFINED; + const char *l_subcmd_strs[] = { + [SUBCMD_UNDEFINED] = NULL, + [SUBCMD_MIN_VALIDATORS_COUNT] = "min_validators_count", + [SUBCMD_CHECK_SIGNS_STRUCTURE] = "check_signs_structure", + [SUBCMD_EMERGENCY_VALIDATOR] = "emergency_validator", + }; - dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-val_count", &l_value_str); - if (!l_value_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'min_validators_count' requires parameter -val_count"); - return -9; - } - uint256_t l_value = dap_chain_balance_scan(l_value_str); - if (IS_ZERO_256(l_value)) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized number in '-val_count' param"); - return -10; + const size_t l_subcmd_str_count = sizeof(l_subcmd_strs) / sizeof(char *); + const char *l_subcmd_str_arg = NULL; + // Parse commands + for (size_t i = 1; i < l_subcmd_str_count; i++) { + if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, l_arg_index + 1, l_subcmd_strs[i], &l_subcmd_str_arg)) { + l_subcmd = i; + break; } + } + dap_cert_t *l_poa_cert = NULL; + l_arg_index++; + bool l_subcommand_show = false, l_subcommand_add = false; + if (l_subcmd) { + if ((dap_cli_server_cmd_check_option(a_argv, l_arg_index, l_arg_index + 1, "set") > 0 && l_subcmd == SUBCMD_MIN_VALIDATORS_COUNT) || + (dap_cli_server_cmd_check_option(a_argv, l_arg_index, l_arg_index + 1, "enable") > 0 && l_subcmd == SUBCMD_CHECK_SIGNS_STRUCTURE) || + (dap_cli_server_cmd_check_option(a_argv, l_arg_index, l_arg_index + 1, "disable") > 0 && l_subcmd == SUBCMD_CHECK_SIGNS_STRUCTURE) || + (dap_cli_server_cmd_check_option(a_argv, l_arg_index, l_arg_index + 1, "add") > 0 && l_subcmd == SUBCMD_EMERGENCY_VALIDATOR) || + (dap_cli_server_cmd_check_option(a_argv, l_arg_index, l_arg_index + 1, "remove") > 0 && l_subcmd == SUBCMD_EMERGENCY_VALIDATOR)) + { + if (dap_cli_server_cmd_check_option(a_argv, l_arg_index, l_arg_index + 1, "enable") || + dap_cli_server_cmd_check_option(a_argv, l_arg_index, l_arg_index + 1, "add")) + l_subcommand_add = true; + const char *l_cert_str = NULL; + dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-cert", &l_cert_str); + if (!l_cert_str) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'min_validators_count' requires parameter -cert"); + return -3; + } + l_poa_cert = dap_cert_find_by_name(l_cert_str); + if (!l_poa_cert) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate not found"); + return -25; + } + if (!l_poa_cert->enc_key || !l_poa_cert->enc_key->priv_key_data) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate doesn't contain a private key"); + return -26; + } + } else if (dap_cli_server_cmd_check_option(a_argv, l_arg_index, l_arg_index + 1, "show") > 0) + l_subcommand_show = true; + else + dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized subcommand '%s'", a_argv[l_arg_index]); + } - dap_chain_datum_decree_t *l_decree = s_esbocs_decree_set_min_validators_count( - l_chain_net, l_chain, l_value, l_poa_cert); - char *l_decree_hash_str = NULL; - if (l_decree && (l_decree_hash_str = s_esbocs_decree_put(l_decree, l_chain_net))) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Minimum validators count has been set." - " Decree hash %s", l_decree_hash_str); - DAP_DEL_MULTY(l_decree, l_decree_hash_str); - } else { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Minimum validators count setting failed"); - DAP_DEL_Z(l_decree); - return -21; - } - } else if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, l_arg_index + 1, "print", NULL)) { - dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(l_chain); - dap_chain_esbocs_t *l_esbocs = DAP_CHAIN_ESBOCS(l_blocks); - dap_chain_esbocs_pvt_t *l_esbocs_pvt = PVT(l_esbocs); - dap_cli_server_cmd_set_reply_text(a_str_reply, "Minimum validators count is %d", - l_esbocs_pvt->min_validators_count); - } else + int ret = 0; + // Do subcommand action + switch (l_subcmd) { + + case SUBCMD_MIN_VALIDATORS_COUNT: { + if (!l_subcommand_show) { + const char *l_value_str = NULL; + dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-val_count", &l_value_str); + if (!l_value_str) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Command '%s' requires parameter -val_count", l_subcmd_strs[l_subcmd]); + return -9; + } + uint256_t l_value = dap_chain_balance_scan(l_value_str); + if (IS_ZERO_256(l_value)) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized number in '-val_count' param"); + return -10; + } + dap_chain_datum_decree_t *l_decree = s_esbocs_decree_set_min_validators_count( + l_chain_net, l_chain, l_value, l_poa_cert); + char *l_decree_hash_str = NULL; + if (l_decree && (l_decree_hash_str = s_esbocs_decree_put(l_decree, l_chain_net))) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Minimum validators count has been set." + " Decree hash %s", l_decree_hash_str); + DAP_DEL_MULTY(l_decree, l_decree_hash_str); + } else { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Minimum validators count setting failed"); + DAP_DEL_Z(l_decree); + return -21; + } + } else + dap_cli_server_cmd_set_reply_text(a_str_reply, "Minimum validators count is %d", l_esbocs_pvt->min_validators_count); + } break; + + case SUBCMD_CHECK_SIGNS_STRUCTURE: { + if (!l_subcommand_show) { + dap_chain_datum_decree_t *l_decree = s_esbocs_decree_set_signs_check(l_chain_net, l_chain, l_subcommand_add, l_poa_cert); + char *l_decree_hash_str = NULL; + if (l_decree && (l_decree_hash_str = s_esbocs_decree_put(l_decree, l_chain_net))) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Checking signs structure has been %s. Decree hash %s", + l_subcommand_add ? "enabled" : "disabled", l_decree_hash_str); + DAP_DEL_MULTY(l_decree, l_decree_hash_str); + } else { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Checking signs structure setting failed"); + DAP_DEL_Z(l_decree); + return -21; + } + } else + dap_cli_server_cmd_set_reply_text(a_str_reply, "Checking signs structure is %s", l_esbocs_pvt->check_signs_structure ? + "enabled" : "disabled"); + } break; + + case SUBCMD_EMERGENCY_VALIDATOR: { + if (!l_subcommand_show) { + const char *l_hash_str = NULL, *l_type_str = NULL; + dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-pkey_hash", &l_hash_str); + if (!l_hash_str) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Command '%s' requires parameter -pkey_hash", l_subcmd_strs[l_subcmd]); + return -9; + } + dap_hash_fast_t l_pkey_hash; + if (dap_chain_hash_fast_from_str(l_hash_str, &l_pkey_hash)) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Invalid hash format in 'pkey_hash' param"); + return -10; + } + dap_sign_type_t l_sig_type = { .type = SIG_TYPE_DILITHIUM }; + dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-sig_type", &l_type_str); + if (l_type_str) + l_sig_type = dap_sign_type_from_str(l_type_str); + dap_chain_datum_decree_t *l_decree = s_esbocs_decree_set_emergency_validator(l_chain_net, l_chain, &l_pkey_hash, l_sig_type, l_subcommand_add, l_poa_cert); + char *l_decree_hash_str = NULL; + if (l_decree && (l_decree_hash_str = s_esbocs_decree_put(l_decree, l_chain_net))) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Emergency validator %s has been %s. Decree hash %s", + dap_chain_hash_fast_to_str_static(&l_pkey_hash), + l_subcommand_add ? "added" : "deleted", l_decree_hash_str); + DAP_DEL_MULTY(l_decree, l_decree_hash_str); + } else { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Emergency validator %s failed", l_subcommand_add ? "adding" : "deleting"); + DAP_DEL_Z(l_decree); + return -21; + } + } else + s_print_emergency_validators((char **)a_str_reply, l_esbocs_pvt->emergency_validator_addrs); + } break; + + default: dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized subcommand '%s'", a_argv[l_arg_index]); + } return ret; } diff --git a/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h b/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h index 6b2df2be82ec8da3a67bde9187717b4f06d3b2c8..fc2c218bdf45bfa4d4f1a6f5db2af2338716d711 100644 --- a/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h +++ b/modules/consensus/esbocs/include/dap_chain_cs_esbocs.h @@ -27,7 +27,6 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic #include "dap_chain.h" #include "dap_chain_block.h" #include "dap_chain_cs_blocks.h" -#include "dap_cert.h" #include "dap_global_db_driver.h" #define DAP_STREAM_CH_ESBOCS_ID 'E' @@ -156,6 +155,7 @@ typedef struct dap_chain_esbocs_round { // Validators section dap_list_t *validators_list; uint16_t validators_synced_count; + uint16_t *excluded_list; // Synchronization params uint64_t sync_attempt; bool sync_sent; @@ -182,7 +182,7 @@ typedef struct dap_chain_esbocs_penalty_item { typedef struct dap_chain_esbocs_session { pthread_mutex_t mutex; - dap_timerfd_t *cs_timer; + bool cs_timer; dap_chain_block_t *processing_candidate; dap_chain_t *chain; @@ -223,16 +223,30 @@ typedef struct dap_chain_esbocs_block_collect{ #define DAP_CHAIN_ESBOCS(a) ((dap_chain_esbocs_t *)(a)->_inheritor) +typedef enum dap_chain_block_autocollect_type { + DAP_CHAIN_BLOCK_COLLECT_BOTH, + DAP_CHAIN_BLOCK_COLLECT_FEES, + DAP_CHAIN_BLOCK_COLLECT_REWARDS +} dap_chain_block_autocollect_type_t; + int dap_chain_cs_esbocs_init(); void dap_chain_cs_esbocs_deinit(void); -bool dap_chain_esbocs_started(); +bool dap_chain_esbocs_started(dap_chain_net_id_t a_net_id); void dap_chain_esbocs_stop_timer(dap_chain_net_id_t a_net_id); void dap_chain_esbocs_start_timer(dap_chain_net_id_t a_net_id); + dap_pkey_t *dap_chain_esbocs_get_sign_pkey(dap_chain_net_id_t a_net_id); uint256_t dap_chain_esbocs_get_fee(dap_chain_net_id_t a_net_id); bool dap_chain_esbocs_get_autocollect_status(dap_chain_net_id_t a_net_id); -void dap_chain_esbocs_add_block_collect(dap_chain_block_t *a_block_ptr, size_t a_block_size, - dap_chain_esbocs_block_collect_t *a_block_collect_params,int a_type); +void dap_chain_esbocs_add_block_collect(dap_chain_block_cache_t *a_block_cache, + dap_chain_esbocs_block_collect_t *a_block_collect_params, + dap_chain_block_autocollect_type_t a_type); bool dap_chain_esbocs_add_validator_to_clusters(dap_chain_net_id_t a_net_id, dap_stream_node_addr_t *a_validator_addr); bool dap_chain_esbocs_remove_validator_from_clusters(dap_chain_net_id_t a_net_id, dap_stream_node_addr_t *a_validator_addr); + +uint256_t dap_chain_esbocs_get_collecting_level(dap_chain_t *a_chain); +dap_enc_key_t *dap_chain_esbocs_get_sign_key(dap_chain_t *a_chain); +int dap_chain_esbocs_set_min_validators_count(dap_chain_t *a_chain, uint16_t a_new_value); +int dap_chain_esbocs_set_emergency_validator(dap_chain_t *a_chain, bool a_add, uint32_t a_sign_type, dap_hash_fast_t *a_validator_hash); +int dap_chain_esbocs_set_signs_struct_check(dap_chain_t *a_chain, bool a_enable); diff --git a/modules/json_rpc/CMakeLists.txt b/modules/json_rpc/CMakeLists.txt deleted file mode 100644 index 526bc29d7597ec77286a5fbfc59ee15b9c307131..0000000000000000000000000000000000000000 --- a/modules/json_rpc/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ - -add_subdirectory(mempool) -add_subdirectory(common) diff --git a/modules/json_rpc/common/CMakeLists.txt b/modules/json_rpc/common/CMakeLists.txt deleted file mode 100644 index 4cd22f12205316ba754833b58898fb4fb6c748e0..0000000000000000000000000000000000000000 --- a/modules/json_rpc/common/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -cmake_minimum_required(VERSION 3.10) -project(dap_json_rpc_chain_common) - -file(GLOB DAP_JSON_RPC_CHAIN_COMMON_HEADERS include/*.h) -file(GLOB DAP_JSON_RPC_CHAIN_COMMON_SRCS *.c) - -add_library(${PROJECT_NAME} STATIC ${DAP_JSON_RPC_CHAIN_COMMON_SRCS} ${DAP_JSON_RPC_CHAIN_COMMON_HEADERS}) - -target_link_libraries(dap_json_rpc_chain_common dap_core dap_crypto dap_chain_common dap_json-c dap_json_rpc_core dap_json_rpc_crypto) -target_include_directories(dap_json_rpc_chain_common PUBLIC include/) diff --git a/modules/json_rpc/common/dap_json_rpc_chain_common.c b/modules/json_rpc/common/dap_json_rpc_chain_common.c deleted file mode 100644 index c26cbe73306f547ec442cb84a3a77d0b2f520b5c..0000000000000000000000000000000000000000 --- a/modules/json_rpc/common/dap_json_rpc_chain_common.c +++ /dev/null @@ -1,13 +0,0 @@ -#include "dap_json_rpc_chain_common.h" -#include "json.h" - -#define LOG_TAG "dap_json_rpc_chain_common" - -/** - * @brief dap_chain_addr_to_json - * @param a_addr - * @return - */ -json_object *dap_chain_addr_to_json(const dap_chain_addr_t *a_addr) { - return json_object_new_string(dap_chain_addr_to_str(a_addr)); -} diff --git a/modules/json_rpc/common/dap_json_rpc_chain_datum.c b/modules/json_rpc/common/dap_json_rpc_chain_datum.c deleted file mode 100644 index 5b61d66f4075d7ea40e272167d8a72dc07c1ec65..0000000000000000000000000000000000000000 --- a/modules/json_rpc/common/dap_json_rpc_chain_datum.c +++ /dev/null @@ -1,728 +0,0 @@ - -#include "dap_common.h" -#include "dap_time.h" -#include "dap_chain_datum.h" -#include "dap_chain_datum_tx.h" -#include "dap_chain_datum_token.h" -#include "dap_chain_datum_tx_items.h" -#include "dap_chain_datum_decree.h" -#include "dap_chain_datum_anchor.h" -#include "dap_chain_datum_hashtree_roots.h" -#include "dap_enc_base58.h" - -#include "dap_json_rpc_chain_datum.h" -#include "dap_json_rpc_chain_datum_tx.h" -#include "dap_json_rpc_chain_datum_token.h" -#include "dap_json_rpc_chain_datum_anchor.h" -#include "dap_json_rpc_chain_datum_decree.h" -#include "json.h" - -#define LOG_TAG "dap_json_rpc_chain_datum" - -json_object *s_dap_chain_datum_token_tsd_to_json(dap_chain_datum_token_t *a_token, size_t a_token_size) { - dap_tsd_t *l_tsd = dap_chain_datum_token_tsd_get(a_token, a_token_size); - if (l_tsd == NULL) { - json_object *l_tsd_wgn = json_object_new_object(); - if (!l_tsd_wgn){ - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_tsd_wgn_warning = json_object_new_string("<CORRUPTED TSD SECTION>"); - if (!l_tsd_wgn_warning) { - json_object_put(l_tsd_wgn); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_tsd_wgn, "warning", l_tsd_wgn_warning); - return l_tsd_wgn; - } - json_object *l_tsd_array = json_object_new_array(); - if (!l_tsd_array) { - dap_json_rpc_allocation_error; - return NULL; - } - size_t l_tsd_total_size = 0; - switch (a_token->type) { - case DAP_CHAIN_DATUM_TOKEN_TYPE_DECL: - switch (a_token->subtype) { - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE: - l_tsd_total_size = a_token->header_private_decl.tsd_total_size; break; - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: - l_tsd_total_size = a_token->header_native_decl.tsd_total_size; break; - default: break; - } break; - case DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE: - switch (a_token->subtype) { - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE: - l_tsd_total_size = a_token->header_private_update.tsd_total_size; break; - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: - l_tsd_total_size = a_token->header_native_update.tsd_total_size; break; - default: break; - } break; - default: break; - } - size_t l_tsd_size = 0; - for (size_t l_offset = 0; l_offset < l_tsd_total_size; l_offset += l_tsd_size) { - json_object *l_jobj_tsd = json_object_new_object(); - l_tsd = (dap_tsd_t *) (((byte_t*)l_tsd) + l_tsd_size); - l_tsd_size = l_tsd ? dap_tsd_size(l_tsd) : 0; - if (l_tsd_size == 0) { - json_object *l_wgn_text = json_object_new_string("Wrong zero TSD size, exiting s_datum_token_dump_tsd()"); - if (!l_wgn_text) { - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_wgn = json_object_new_object(); - if (!l_wgn) { - json_object_put(l_wgn_text); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_wgn, "error", l_wgn_text); - json_object_array_add(l_tsd_array, l_wgn); - break; - } else if (l_tsd_size+l_offset > l_tsd_total_size) { - char *l_wgn_str = dap_strdup_printf("<CORRUPTED TSD> too big size %u when left maximum %zu", - l_tsd->size, l_tsd_total_size - l_offset); - if (!l_wgn_str) { - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_wgn_text = json_object_new_string(l_wgn_str); - DAP_DELETE(l_wgn_str); - if (!l_wgn_text) { - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_wgn = json_object_new_object(); - if (!l_wgn) { - json_object_put(l_wgn_text); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_wgn, "error", l_wgn_text); - json_object_array_add(l_tsd_array, l_wgn); - break; - } - switch( l_tsd->type){ - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_SET_FLAGS: { - json_object *l_jobj_tsd = json_object_new_object(); - if (!l_jobj_tsd) { - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_SET_FLAGS"); - if (!l_jobj_tsd_type) { - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - uint16_t l_flags = 0; - _dap_tsd_get_scalar(l_tsd, &l_flags); - json_object *l_jobj_tsd_flag = dap_chain_datum_token_flags_to_json(l_flags); - if (!l_jobj_tsd_flag) { - json_object_put(l_jobj_tsd_type); - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type); - json_object_object_add(l_jobj_tsd, "flags", l_jobj_tsd_flag); - json_object_array_add(l_tsd_array, l_jobj_tsd); - } continue; - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_UNSET_FLAGS: { - json_object *l_jobj_tsd = json_object_new_object(); - if (!l_jobj_tsd) { - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_UNSET_FLAGS"); - if (!l_jobj_tsd_type) { - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - uint16_t l_flags = 0; - _dap_tsd_get_scalar(l_tsd, &l_flags); - json_object *l_jobj_tsd_flag = dap_chain_datum_token_flags_to_json(l_flags); - if (!l_jobj_tsd_flag) { - json_object_put(l_jobj_tsd_type); - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type); - json_object_object_add(l_jobj_tsd, "flags", l_jobj_tsd_flag); - json_object_array_add(l_tsd_array, l_jobj_tsd); - } continue; - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SUPPLY: { // 256 - json_object *l_jobj_tsd = json_object_new_object(); - if (!l_jobj_tsd) { - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SUPPLY"); - if (!l_jobj_tsd_type) { - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - uint256_t l_balance_native = uint256_0; - _dap_tsd_get_scalar(l_tsd, &l_balance_native); - json_object *l_jobj_tsd_value = json_object_new_string(dap_uint256_to_char(l_balance_native, NULL)); - if (!l_jobj_tsd_value) { - json_object_put(l_jobj_tsd); - json_object_put(l_jobj_tsd_type); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type); - json_object_object_add(l_jobj_tsd, "value", l_jobj_tsd_value); - json_object_array_add(l_tsd_array, l_jobj_tsd); - } continue; - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SUPPLY_OLD: {// 128 - json_object *l_jobj_tsd = json_object_new_object(); - if (!l_jobj_tsd) { - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SUPPLY_OLD"); - if (!l_jobj_tsd_type) { - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - uint128_t l_balance_native_old = uint128_0; - _dap_tsd_get_scalar(l_tsd, &l_balance_native_old); - json_object *l_jobj_tsd_value = - json_object_new_string(dap_uint256_to_char(GET_256_FROM_128(l_balance_native_old), NULL)); - if (!l_jobj_tsd_value) { - json_object_put(l_jobj_tsd_type); - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type); - json_object_object_add(l_jobj_tsd, "value", l_jobj_tsd_value); - json_object_array_add(l_tsd_array, l_jobj_tsd); - } continue; - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SIGNS_VALID: { - json_object *l_jobj_tsd = json_object_new_object(); - json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_SIGNS_VALID"); - uint16_t l_flags = 0; - _dap_tsd_get_scalar(l_tsd, &l_flags); - json_object *l_jobj_value = json_object_new_uint64(l_flags); - json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type); - json_object_object_add(l_jobj_tsd, "total_signs_valid", l_jobj_value); - json_object_array_add(l_tsd_array, l_jobj_tsd); - } continue; - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_ADD: { - json_object *l_jobj_tsd = json_object_new_object(); - if (!l_jobj_tsd) { - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_ADD"); - if (!l_jobj_tsd_type) { - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type); - if (l_tsd->size >= sizeof(dap_pkey_t)) { - dap_pkey_t *l_pkey = (dap_pkey_t *) l_tsd->data; - dap_hash_fast_t l_hf = {0}; - if (!dap_pkey_get_hash(l_pkey, &l_hf)) { - json_object *l_wgn_text = json_object_new_string("total_pkeys_add: <WRONG CALCULATION FINGERPRINT>"); - if (!l_wgn_text) { - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "warning", l_wgn_text); - } else { - json_object_object_add(l_jobj_tsd, "pkey", - json_object_new_string(dap_chain_hash_fast_to_str_static(&l_hf))); - } - } else { - char *l_wgn_text = dap_strdup_printf("total_pkeys_add: <WRONG SIZE %u>\n", l_tsd->size); - if (!l_wgn_text) { - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_jobj_wgn_text = json_object_new_string(l_wgn_text); - DAP_DELETE(l_wgn_text); - if (!l_jobj_wgn_text) { - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "warning", l_jobj_wgn_text); - } - json_object_array_add(l_tsd_array, l_jobj_tsd); - } continue; - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_REMOVE: { - json_object *l_jobj_tsd = json_object_new_object(); - if (!l_jobj_tsd){ - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_REMOVE"); - if (!l_jobj_tsd_type) { - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type); - if (l_tsd->size == sizeof(dap_chain_hash_fast_t)) { - json_object_object_add(l_jobj_tsd, "pkey", - json_object_new_string(dap_chain_hash_fast_to_str_static((dap_chain_hash_fast_t*) l_tsd->data))); - } else { - char *l_wgn_text = dap_strdup_printf("total_pkeys_remove: <WRONG SIZE %u>\n", l_tsd->size); - if (!l_wgn_text) { - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_jobj_wgn_text = json_object_new_string(l_wgn_text); - DAP_DELETE(l_wgn_text); - if (!l_jobj_wgn_text) { - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "warning", l_jobj_wgn_text); - } - json_object_array_add(l_tsd_array, l_jobj_tsd); - } continue; - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DELEGATE_EMISSION_FROM_STAKE_LOCK: { - json_object *l_jobj_tsd = json_object_new_object(); - if (!l_jobj_tsd) { - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DELEGATE_EMISSION_FROM_STAKE_LOCK"); - if (!l_jobj_tsd_type) { - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type); - dap_chain_datum_token_tsd_delegate_from_stake_lock_t *l_tsd_section = _dap_tsd_get_object(l_tsd, dap_chain_datum_token_tsd_delegate_from_stake_lock_t); - json_object *l_jobj_ticker_token_from = json_object_new_string((char*)l_tsd_section->ticker_token_from); - if (!l_jobj_ticker_token_from) { - json_object_put(l_jobj_ticker_token_from); - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "ticker_token_from", l_jobj_ticker_token_from); - char *balance; dap_uint256_to_char(l_tsd_section->emission_rate, &balance); - json_object *l_jobj_emission_rate = json_object_new_string(balance); - if (!l_jobj_emission_rate) { - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "emission_rate", l_jobj_emission_rate); - json_object_array_add(l_tsd_array, l_jobj_tsd); - } continue; - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_ALLOWED_ADD: { - json_object *l_jobj_tsd = json_object_new_object(); - if (!l_jobj_tsd) { - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_ALLOWED_ADD"); - if (!l_jobj_tsd_type) { - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type); - json_object *l_jobj_datum_type_allowed_add = json_object_new_string(dap_tsd_get_string_const(l_tsd)); - if (!l_jobj_datum_type_allowed_add) { - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "datum_type_allowed_add", l_jobj_datum_type_allowed_add); - json_object_array_add(l_tsd_array, l_jobj_tsd); - }continue; - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_ALLOWED_REMOVE: { - json_object *l_jobj_tsd = json_object_new_object(); - json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_ALLOWED_REMOVE"); - json_object *l_jobj_datum_type_allowed_remove = json_object_new_string(dap_tsd_get_string_const(l_tsd)); - if (!l_jobj_tsd || !l_jobj_tsd_type || !l_jobj_datum_type_allowed_remove) { - json_object_put(l_jobj_datum_type_allowed_remove); - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type); - json_object_object_add(l_jobj_tsd, "datum_type_allowed_remove", l_jobj_datum_type_allowed_remove); - json_object_array_add(l_tsd_array, l_jobj_tsd); - }continue; - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_BLOCKED_ADD: { - json_object *l_jobj_tsd = json_object_new_object(); - json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_BLOCKED_ADD"); - json_object *l_jobj_datum_type_blocked_add = json_object_new_string(dap_tsd_get_string_const(l_tsd)); - if (!l_jobj_tsd || !l_jobj_tsd_type || !l_jobj_datum_type_blocked_add) { - json_object_put(l_jobj_datum_type_blocked_add); - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type); - json_object_object_add(l_jobj_tsd, "datum_type_blocked_add", l_jobj_datum_type_blocked_add); - json_object_array_add(l_tsd_array, l_jobj_tsd); - } continue; - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_BLOCKED_REMOVE: { - json_object *l_jobj_tsd = json_object_new_object(); - json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_DATUM_TYPE_BLOCKED_REMOVE"); - json_object *l_jobj_datum_type_blocked_remove = json_object_new_string(dap_tsd_get_string_const(l_tsd)); - if (!l_jobj_tsd || !l_jobj_tsd_type || !l_jobj_datum_type_blocked_remove) { - json_object_put(l_jobj_datum_type_blocked_remove); - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type); - json_object_object_add(l_jobj_tsd, "datum_type_blocked_remove", l_jobj_datum_type_blocked_remove); - json_object_array_add(l_tsd_array, l_jobj_tsd); - } continue; - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD: { - json_object *l_jobj_tsd = json_object_new_object(); - json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD"); - json_object *l_jobj_tx_sender_allowed_add = json_object_new_string(dap_tsd_get_string_const(l_tsd)); - if (!l_jobj_tsd || !l_jobj_tsd_type || !l_jobj_tx_sender_allowed_add) { - json_object_put(l_jobj_tx_sender_allowed_add); - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type); - json_object_object_add(l_jobj_tsd, "tx_sender_allowed_add",l_jobj_tx_sender_allowed_add); - json_object_array_add(l_tsd_array, l_jobj_tsd); - } continue; - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_REMOVE: { - json_object *l_jobj_tsd = json_object_new_object(); - json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_REMOVE"); - json_object *l_jobj_tx_sender_allowed_remove = json_object_new_string(dap_tsd_get_string_const(l_tsd)); - if (!l_jobj_tsd || !l_jobj_tsd_type || !l_jobj_tx_sender_allowed_remove) { - json_object_put(l_jobj_tx_sender_allowed_remove); - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type); - json_object_object_add(l_jobj_tsd, "tx_sender_allowed_remove",l_jobj_tx_sender_allowed_remove); - json_object_array_add(l_tsd_array, l_jobj_tsd); - }continue; - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_ADD: { - json_object *l_jobj_tsd = json_object_new_object(); - json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_ADD"); - json_object *l_jobj_tx_sender_blocked_add = json_object_new_string(dap_tsd_get_string_const(l_tsd)); - if (!l_jobj_tsd || !l_jobj_tsd_type || !l_jobj_tx_sender_blocked_add) { - json_object_put(l_jobj_tx_sender_blocked_add); - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type); - json_object_object_add(l_jobj_tsd, "tx_sender_blocked_add", l_jobj_tx_sender_blocked_add); - json_object_array_add(l_tsd_array, l_jobj_tsd); - } continue; - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_REMOVE: { - json_object *l_jobj_tsd = json_object_new_object(); - json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_REMOVE"); - json_object *l_jobj_tx_sender_blocked_remove = json_object_new_string(dap_tsd_get_string_const(l_tsd)); - if (!l_jobj_tsd || !l_jobj_tsd_type || !l_jobj_tx_sender_blocked_remove) { - json_object_put(l_jobj_tx_sender_blocked_remove); - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type); - json_object_object_add(l_jobj_tsd, "tx_sender_blocked_remove", l_jobj_tx_sender_blocked_remove); - json_object_array_add(l_tsd_array, l_jobj_tsd); - } continue; - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD: { - json_object *l_jobj_tsd = json_object_new_object(); - json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD"); - json_object *l_tx_receiver_allowed_add = json_object_new_string(dap_tsd_get_string_const(l_tsd)); - if (!l_jobj_tsd || !l_jobj_tsd_type || !l_tx_receiver_allowed_add) { - json_object_put(l_tx_receiver_allowed_add); - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type); - json_object_object_add(l_jobj_tsd, "tx_receiver_allowed_add", l_tx_receiver_allowed_add); - json_object_array_add(l_tsd_array, l_jobj_tsd); - } continue; - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_REMOVE: { - json_object *l_jobj_tsd = json_object_new_object(); - json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_REMOVE"); - json_object *l_jobj_tx_receiver_allowed_remove = json_object_new_string(dap_tsd_get_string_const(l_tsd)); - if (!l_jobj_tsd || !l_jobj_tsd_type || !l_jobj_tx_receiver_allowed_remove){ - json_object_put(l_jobj_tx_receiver_allowed_remove); - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type); - json_object_object_add(l_jobj_tsd, "tx_receiver_allowed_remove", l_jobj_tx_receiver_allowed_remove); - json_object_array_add(l_tsd_array, l_jobj_tsd); - } continue; - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_ADD: { - json_object *l_jobj_tsd = json_object_new_object(); - json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_ADD"); - json_object *l_jobj_tx_receiver_blocked_add = json_object_new_string(dap_tsd_get_string_const(l_tsd)); - if (!l_jobj_tsd || !l_jobj_tsd_type || !l_jobj_tx_receiver_blocked_add){ - json_object_put(l_jobj_tx_receiver_blocked_add); - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type); - json_object_object_add(l_jobj_tsd, "tx_receiver_blocked_add", l_jobj_tx_receiver_blocked_add); - json_object_array_add(l_tsd_array, l_jobj_tsd); - } continue; - case DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_REMOVE: { - json_object *l_jobj_tsd = json_object_new_object(); - json_object *l_jobj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_REMOVE"); - json_object *l_jobj_tx_receiver_blocked_remove = json_object_new_string(dap_tsd_get_string_const(l_tsd)); - if (!l_jobj_tsd || !l_jobj_tsd_type || !l_jobj_tx_receiver_blocked_remove) { - json_object_put(l_jobj_tx_receiver_blocked_remove); - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "type", l_jobj_tsd_type); - json_object_object_add(l_jobj_tsd, "tx_receiver_blocked_remove", l_jobj_tx_receiver_blocked_remove); - json_object_array_add(l_tsd_array, l_jobj_tsd); - } continue; - default: { - char *l_wgn_text = dap_strdup_printf("<0x%04hX>: <size %u>\n", l_tsd->type, l_tsd->size); - if (!l_wgn_text){ - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_jobj_wgn_text = json_object_new_string(l_wgn_text); - DAP_DELETE(l_wgn_text); - json_object *l_jobj_warning = json_object_new_object(); - if (!l_jobj_wgn_text || !l_jobj_warning) { - json_object_put(l_jobj_wgn_text); - json_object_put(l_jobj_warning); - json_object_put(l_jobj_tsd); - json_object_put(l_tsd_array); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_warning, "warning", l_jobj_wgn_text); - json_object_array_add(l_tsd_array, l_jobj_warning); - } - } - } - return l_tsd_array; -} - -typedef enum dap_chain_datum_to_json_err_list { - CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_SERIALIZATION_TX_TO_JSON = DAP_JSON_RPC_ERR_CODE_METHOD_ERR_START, - CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_SERIALIZATION_DECL_TO_JSON, - CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_READ_DECL, - CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_SERIALIZATION_TSD_SECTION_DECL_TO_JSON, - CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_SERIALIZATION_EMISSION_TO_JSON, - CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_READ_EMISSION, - CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_SERIALIZATION_ANCHOR_TO_JSON, - CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_SERIALIZATION_DECREE_TO_JSON -}dap_chain_datum_to_json_err_list_t; - -json_object * dap_chain_datum_to_json(dap_chain_datum_t* a_datum){ - json_object *l_object = json_object_new_object(); - if (!l_object){ - dap_json_rpc_allocation_error; - return NULL; - } - char *l_hash_data_str; - dap_get_data_hash_str_static(a_datum->data, a_datum->header.data_size, l_hash_data_str); - json_object *l_obj_data_hash = json_object_new_string(l_hash_data_str); - if (!l_obj_data_hash) { - json_object_put(l_object); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_obj_version = json_object_new_int(a_datum->header.version_id); - if (!l_obj_version) { - json_object_put(l_object); - json_object_put(l_obj_data_hash); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_obj_size = json_object_new_int(a_datum->header.data_size); - if (!l_obj_size) { - json_object_put(l_object); - json_object_put(l_obj_data_hash); - json_object_put(l_obj_version); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_obj_type = json_object_new_string(dap_chain_datum_type_id_to_str(a_datum->header.type_id)); - if (!l_obj_type) { - json_object_put(l_object); - json_object_put(l_obj_data_hash); - json_object_put(l_obj_version); - json_object_put(l_obj_size); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_obj_data = dap_chain_datum_data_to_json(a_datum); - - json_object_object_add(l_object, "hash", l_obj_data_hash); - json_object_object_add(l_object, "data_size", l_obj_size); - json_object_object_add(l_object, "version", l_obj_version); - - char l_time_str[DAP_TIME_STR_SIZE]; - if (a_datum->header.ts_create) { - dap_time_to_str_rfc822(l_time_str, DAP_TIME_STR_SIZE, a_datum->header.ts_create); /* Convert ts to "Sat May 17 01:17:08 2014\n" */ - l_time_str[strlen(l_time_str)-1] = '\0'; /* Remove "\n"*/ - } - json_object *l_obj_ts_created = json_object_new_string(l_time_str); - json_object_object_add(l_object, "ts_create", l_obj_ts_created); - json_object_object_add(l_object, "type", l_obj_type); - if (a_datum->header.type_id == DAP_CHAIN_DATUM_TX) { - json_object_object_add(l_object, "items", l_obj_data); - } else { - json_object_object_add(l_object, "data", l_obj_data); - } - return l_object; -} - -json_object * dap_chain_datum_data_to_json(dap_chain_datum_t *a_datum) { - if (!a_datum) - return json_object_new_null(); - json_object *l_obj_data; - switch (a_datum->header.type_id) { - case DAP_CHAIN_DATUM_TX: - l_obj_data = dap_chain_datum_tx_to_json((dap_chain_datum_tx_t*)a_datum->data, NULL); - if (!l_obj_data) { - dap_json_rpc_error_add(CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_SERIALIZATION_TX_TO_JSON, - "Can't convert DAP_CHAIN_DATUM_TX to JSON"); - return NULL; - } - break; - case DAP_CHAIN_DATUM_DECREE: - l_obj_data = dap_chain_datum_decree_to_json((dap_chain_datum_decree_t*)a_datum->data); - if (!l_obj_data) { - dap_json_rpc_error_add(CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_SERIALIZATION_DECREE_TO_JSON, - "Can't convert DAP_CHAIN_DATUM_DECREE to JSON"); - return NULL; - } - break; - case DAP_CHAIN_DATUM_ANCHOR: - l_obj_data = dap_chain_datum_anchor_to_json((dap_chain_datum_anchor_t*)a_datum->data); - if (!l_obj_data) { - dap_json_rpc_error_add(CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_SERIALIZATION_ANCHOR_TO_JSON, - "Can't convert DAP_CHAIN_DATUM_ANCHOR to JSON"); - return NULL; - } - break; - case DAP_CHAIN_DATUM_TOKEN_DECL: { - size_t l_token_size = a_datum->header.data_size; - dap_chain_datum_token_t *l_token = dap_chain_datum_token_read(a_datum->data, &l_token_size); - if (!l_token) { - dap_json_rpc_error_add(CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_READ_DECL, - "The contents of the token delcaration could not be read."); - return NULL; - } - l_obj_data = dap_chain_datum_token_to_json(l_token, l_token_size); - if (!l_obj_data) { - dap_json_rpc_error_add(CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_SERIALIZATION_DECL_TO_JSON, - "Can't convert DAP_CHAIN_DATUM_TOKEN_DECL to JSON"); - DAP_DELETE(l_token); - return NULL; - } - json_object *l_obj_tsd_data = s_dap_chain_datum_token_tsd_to_json(l_token, l_token_size); - if (!l_obj_tsd_data) { - json_object_put(l_obj_data); - DAP_DELETE(l_token); - log_it(L_ERROR, "It was not possible to read the contents of the TSD sections of the token delcaration."); - dap_json_rpc_error_add(CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_SERIALIZATION_TSD_SECTION_DECL_TO_JSON, - "It was not possible to read the contents of the TSD sections of the token delcaration."); - return NULL; - } - json_object_object_add(l_obj_data, "TSD", l_obj_tsd_data); - DAP_DELETE(l_token); - } break; - case DAP_CHAIN_DATUM_TOKEN_EMISSION: { - size_t l_emission_size = a_datum->header.data_size; - dap_chain_datum_token_emission_t *l_emission = dap_chain_datum_emission_read(a_datum->data, &l_emission_size); - if (l_emission_size == 0 || !l_emission) { - log_it(L_ERROR, "Failed to read emission"); - dap_json_rpc_error_add(CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_READ_EMISSION, - "Failed to read emission."); - return NULL; - } else { - l_obj_data = dap_chain_datum_emission_to_json(l_emission, l_emission_size); - DAP_DELETE(l_emission); - if (!l_obj_data) { - dap_json_rpc_error_add(CHAIN_DATUM_TO_JSON_ERR_CAN_NOT_SERIALIZATION_EMISSION_TO_JSON, - "Can't convert DAP_CHAIN_DATUM_TOKEN_DECL to JSON"); - return NULL; - } - } - } break; - default: - l_obj_data = json_object_new_null(); - break; - } - return l_obj_data; -} diff --git a/modules/json_rpc/common/dap_json_rpc_chain_datum_anchor.c b/modules/json_rpc/common/dap_json_rpc_chain_datum_anchor.c deleted file mode 100644 index e41c242d9755b3ed00a872d8a2d97b2c868a4e73..0000000000000000000000000000000000000000 --- a/modules/json_rpc/common/dap_json_rpc_chain_datum_anchor.c +++ /dev/null @@ -1,169 +0,0 @@ -#include "dap_json_rpc_chain_datum_anchor.h" -#include "json.h" - -#define LOG_TAG "dap_json_rpc_chain_datum_anchor" - - -json_object *s_dap_chain_datum_anchor_sign_to_json(byte_t * a_signs, size_t a_certs_size) { - json_object *l_jobs_signs = json_object_new_array(); - size_t l_offset = 0; - for (int i = 1; l_offset < (a_certs_size); i++) { - json_object *l_jobj_sign = json_object_new_object(); - dap_sign_t *l_sign = (dap_sign_t*)(a_signs + l_offset); - l_offset += dap_sign_get_size(l_sign); - if (l_sign->header.sign_size == 0) { - json_object *l_wrn_text = json_object_new_string("<CORRUPTED - 0 size signature>"); - json_object_object_add(l_jobj_sign, "warning", l_wrn_text); - continue; - } - - dap_chain_hash_fast_t l_pkey_hash = {0}; - if (dap_sign_get_pkey_hash(l_sign, &l_pkey_hash) == false) { - json_object *l_wrn_text = json_object_new_string("<CORRUPTED - can't calc hash>"); - json_object_object_add(l_jobj_sign, "warning", l_wrn_text); - continue; - } - json_object *l_jobj_hash_str = json_object_new_string(dap_chain_hash_fast_to_str_static(&l_pkey_hash)); - json_object *l_jobj_type_str = json_object_new_string(dap_sign_type_to_str(l_sign->header.type)); - json_object *l_jobj_sign_size = json_object_new_uint64(l_sign->header.sign_size); - json_object_object_add(l_jobj_sign, "hash", l_jobj_hash_str); - json_object_object_add(l_jobj_sign, "type", l_jobj_type_str); - json_object_object_add(l_jobj_sign, "size", l_jobj_sign_size); - json_object_array_add(l_jobs_signs, l_jobj_sign); - } - return l_jobs_signs; -} - -json_object *dap_chain_datum_anchor_to_json(dap_chain_datum_anchor_t *a_anchor){ - json_object *l_obj_anchor = json_object_new_object(); - if (!l_obj_anchor) { - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_obj_version = json_object_new_uint64(a_anchor->anchor_version); - if (!l_obj_version){ - json_object_put(l_obj_anchor); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_obj_ts_created = json_object_new_uint64(a_anchor->header.ts_created); - if (!l_obj_ts_created) { - json_object_put(l_obj_version); - json_object_put(l_obj_anchor); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_obj_tsd_array = json_object_new_array(); - if(!l_obj_tsd_array) { - json_object_put(l_obj_ts_created); - json_object_put(l_obj_version); - json_object_put(l_obj_anchor); - dap_json_rpc_allocation_error; - return NULL; - } - size_t l_tsd_offset = 0, tsd_data_size = a_anchor->header.data_size; - - while(l_tsd_offset < tsd_data_size){ - json_object *l_jobj_tsd = json_object_new_object(); - if (!l_jobj_tsd) { - json_object_put(l_obj_tsd_array); - json_object_put(l_obj_ts_created); - json_object_put(l_obj_version); - json_object_put(l_obj_anchor); - dap_json_rpc_allocation_error; - return NULL; - } - dap_tsd_t *l_tsd = (dap_tsd_t*)a_anchor->data_n_sign + l_tsd_offset; - size_t l_tsd_size = l_tsd->size + sizeof(dap_tsd_t); - if(l_tsd_size > tsd_data_size){ - json_object *l_jobj_wgn = json_object_new_string("TSD size is greater than all data size. It's possible corrupt data."); - if (!l_jobj_wgn){ - json_object_put(l_jobj_tsd); - json_object_put(l_obj_tsd_array); - json_object_put(l_obj_ts_created); - json_object_put(l_obj_ts_created); - json_object_put(l_obj_version); - json_object_put(l_obj_anchor); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "warning", l_jobj_wgn); - json_object_array_add(l_obj_tsd_array, l_jobj_tsd); - break; - } - if (l_tsd->type == DAP_CHAIN_DATUM_ANCHOR_TSD_TYPE_DECREE_HASH){ - json_object *l_obj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_ANCHOR_TSD_TYPE_DECREE_HASH"); - if (!l_obj_tsd_type){ - json_object_put(l_jobj_tsd); - json_object_put(l_obj_tsd_array); - json_object_put(l_obj_ts_created); - json_object_put(l_obj_ts_created); - json_object_put(l_obj_version); - json_object_put(l_obj_anchor); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "type", l_obj_tsd_type); - if(l_tsd->size > sizeof(dap_hash_fast_t)){ - json_object *l_jobj_wgn = json_object_new_string("Wrong fee tsd data size."); - if (!l_jobj_wgn){ - json_object_put(l_jobj_tsd); - json_object_put(l_obj_tsd_array); - json_object_put(l_obj_ts_created); - json_object_put(l_obj_ts_created); - json_object_put(l_obj_version); - json_object_put(l_obj_anchor); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "warning", l_jobj_wgn); - json_object_array_add(l_obj_tsd_array, l_jobj_tsd); - break; - } - dap_hash_fast_t l_out_hash = {0}; - _dap_tsd_get_scalar(l_tsd, &l_out_hash); - char *l_hash_str = dap_hash_fast_to_str_new(&l_out_hash); - if (!l_hash_str) { - json_object_put(l_jobj_tsd); - json_object_put(l_obj_tsd_array); - json_object_put(l_obj_ts_created); - json_object_put(l_obj_ts_created); - json_object_put(l_obj_version); - json_object_put(l_obj_anchor); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_obj_tsd_hash = json_object_new_string(l_hash_str); - DAP_DELETE(l_hash_str); - if (!l_obj_tsd_hash){ - json_object_put(l_jobj_tsd); - json_object_put(l_obj_tsd_array); - json_object_put(l_obj_ts_created); - json_object_put(l_obj_ts_created); - json_object_put(l_obj_version); - json_object_put(l_obj_anchor); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "hash", l_obj_tsd_hash); - } - json_object_array_add(l_obj_tsd_array, l_jobj_tsd); - l_tsd_offset += l_tsd_size; - } - json_object_object_add(l_obj_anchor, "version", l_obj_version); - json_object_object_add(l_obj_anchor, "ts_created", l_obj_ts_created); - json_object_object_add(l_obj_anchor, "TSD", l_obj_tsd_array); - json_object *l_jobj_signs = s_dap_chain_datum_anchor_sign_to_json(a_anchor->data_n_sign + a_anchor->header.data_size, - a_anchor->header.signs_size); - if (!l_jobj_signs) { - json_object_put(l_obj_tsd_array); - json_object_put(l_obj_ts_created); - json_object_put(l_obj_ts_created); - json_object_put(l_obj_version); - json_object_put(l_obj_anchor); - dap_json_rpc_error_add(DAP_JSON_RPC_ERR_CODE_SERIALIZATION_SIGN_TO_JSON, "I can't serialize the anchor signature in JSON."); - return NULL; - } - json_object_object_add(l_obj_anchor, "signs", l_jobj_signs); - return l_obj_anchor; -} 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 deleted file mode 100644 index 95d2cedcc88c33ec686dcacca946a23101dd593e..0000000000000000000000000000000000000000 --- a/modules/json_rpc/common/dap_json_rpc_chain_datum_decree.c +++ /dev/null @@ -1,550 +0,0 @@ - -#include "dap_json_rpc_chain_datum_decree.h" -#include "dap_json_rpc_chain_common.h" -#include "json.h" - - -#define LOG_TAG "dap_json_rpc_chain_datum_decree" - -json_object *s_dap_chain_datum_decree_certs_dump_json(byte_t * a_signs, size_t a_certs_size){ - json_object *l_jobj_signatures = json_object_new_array(); - if (!l_jobj_signatures) { - dap_json_rpc_allocation_error; - return NULL; - } - size_t l_offset = 0; - for (int i = 1; l_offset < (a_certs_size); i++) { - json_object *l_jobj_signature = json_object_new_object(); - if (!l_jobj_signature) { - json_object_put(l_jobj_signatures); - dap_json_rpc_allocation_error; - return NULL; - } - dap_sign_t *l_sign = (dap_sign_t *) (a_signs + l_offset); - l_offset += dap_sign_get_size(l_sign); - if (l_sign->header.sign_size == 0) { - json_object *l_wrn_text = json_object_new_string("<CORRUPTED - 0 size signature>"); - if(!l_wrn_text) { - json_object_put(l_jobj_signature); - json_object_put(l_jobj_signatures); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_signature, "warning", l_wrn_text); - continue; - } - - dap_chain_hash_fast_t l_pkey_hash = {0}; - if (dap_sign_get_pkey_hash(l_sign, &l_pkey_hash) == false) { - json_object *l_wrn_text = json_object_new_string("<CORRUPTED - can't calc hash>"); - if (!l_wrn_text){ - json_object_put(l_jobj_signature); - json_object_put(l_jobj_signatures); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_signature, "warning", l_wrn_text); - continue; - } - - json_object *l_jobj_hash_str - = json_object_new_string(dap_chain_hash_fast_to_str_static(&l_pkey_hash)); - if (!l_jobj_hash_str) { - json_object_put(l_jobj_signature); - json_object_put(l_jobj_signatures); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_jobj_type_str = json_object_new_string(dap_sign_type_to_str(l_sign->header.type)); - if (!l_jobj_type_str) { - json_object_put(l_jobj_hash_str); - json_object_put(l_jobj_signature); - json_object_put(l_jobj_signatures); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_jobj_sign_size = json_object_new_uint64(l_sign->header.sign_size); - if (!l_jobj_sign_size) { - json_object_put(l_jobj_hash_str); - json_object_put(l_jobj_type_str); - json_object_put(l_jobj_signature); - json_object_put(l_jobj_signatures); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_signature, "hash", l_jobj_hash_str); - json_object_object_add(l_jobj_signature, "type", l_jobj_type_str); - json_object_object_add(l_jobj_signature, "size", l_jobj_sign_size); - json_object_array_add(l_jobj_signatures, l_jobj_signature); - } - return l_jobj_signatures; -} - -json_object *dap_chain_datum_decree_to_json(dap_chain_datum_decree_t *a_decree){ - json_object *l_jobj_decree = json_object_new_object(); - if (!l_jobj_decree) { - dap_json_rpc_allocation_error; - return NULL; - } - char *l_type_str = ""; - switch(a_decree->header.type) - { - case DAP_CHAIN_DATUM_DECREE_TYPE_COMMON: - l_type_str = "DECREE_TYPE_COMMON"; - break; - case DAP_CHAIN_DATUM_DECREE_TYPE_SERVICE: - l_type_str = "DECREE_TYPE_SERVICE"; - break; - default: - l_type_str = "DECREE_TYPE_UNKNOWN"; - } - json_object *l_jobj_type = json_object_new_string(l_type_str); - if (!l_jobj_type) { - json_object_put(l_jobj_decree); - dap_json_rpc_allocation_error; - return NULL; - } - const char *l_subtype_str = dap_chain_datum_decree_subtype_to_str(a_decree->header.sub_type); - json_object *l_json_subtype = json_object_new_string(l_subtype_str); - if (!l_json_subtype) { - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_json_tsd_array = json_object_new_array(); - if (!l_json_tsd_array){ - json_object_put(l_json_subtype); - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - dap_json_rpc_allocation_error; - return NULL; - } - for (size_t l_offset = 0; l_offset < a_decree->header.data_size;) { - dap_tsd_t *l_tsd = (dap_tsd_t *)((byte_t*)a_decree->data_n_signs + l_offset); - l_offset += dap_tsd_size(l_tsd); - json_object *l_jobj_tsd = json_object_new_object(); - if (!l_jobj_tsd) { - json_object_put(l_json_tsd_array); - json_object_put(l_json_subtype); - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - dap_json_rpc_allocation_error; - return NULL; - } - switch(l_tsd->type) { - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN: { - json_object *l_obj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGN"); - if (!l_obj_tsd_type) { - json_object_put(l_json_tsd_array); - json_object_put(l_json_subtype); - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - json_object_put(l_jobj_tsd); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "type", l_obj_tsd_type); - } break; - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE: { - json_object *l_obj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE"); - if (!l_obj_tsd_type) { - json_object_put(l_json_tsd_array); - json_object_put(l_json_subtype); - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - json_object_put(l_jobj_tsd); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "type", l_obj_tsd_type); - if (l_tsd->size > sizeof(uint256_t)) { - json_object *l_text_wgn = json_object_new_string("Fee: <WRONG SIZE>"); - if (!l_text_wgn) { - json_object_put(l_json_tsd_array); - json_object_put(l_json_subtype); - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - json_object_put(l_jobj_tsd); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "warning", l_text_wgn); - break; - } - uint256_t l_fee_value = uint256_0; - _dap_tsd_get_scalar(l_tsd, &l_fee_value); - json_object *l_jobj_fee = json_object_new_string(dap_uint256_to_char(l_fee_value, NULL)); - if (!l_jobj_fee) { - json_object_put(l_json_tsd_array); - json_object_put(l_json_subtype); - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - json_object_put(l_jobj_tsd); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "value", l_jobj_fee); - } break; - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_OWNER: { - json_object *l_obj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_DECREE_TSD_TYPE_OWNER"); - if (!l_obj_tsd_type){ - json_object_put(l_json_tsd_array); - json_object_put(l_json_subtype); - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - json_object_put(l_jobj_tsd); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "type", l_obj_tsd_type); - if (l_tsd->size < sizeof(dap_pkey_t)) { - json_object *l_text_wgn = json_object_new_string("Owner fingerprint: <WRONG SIZE>"); - if (!l_text_wgn){ - json_object_put(l_json_tsd_array); - json_object_put(l_json_subtype); - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - json_object_put(l_jobj_tsd); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "warning", l_text_wgn); - break; - } - dap_pkey_t *l_owner_pkey = DAP_NEW_Z_SIZE(dap_pkey_t, l_tsd->size); - if(!l_owner_pkey) { - json_object_put(l_json_tsd_array); - json_object_put(l_json_subtype); - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - json_object_put(l_jobj_tsd); - dap_json_rpc_allocation_error; - return NULL; - } - memcpy(l_owner_pkey, l_tsd->data, l_tsd->size); - dap_hash_fast_t l_owner_pkey_hash = {0}; - dap_hash_fast(l_owner_pkey->pkey, l_owner_pkey->header.size, &l_owner_pkey_hash); - char l_owner_pkey_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; - dap_chain_hash_fast_to_str(&l_owner_pkey_hash, l_owner_pkey_str, sizeof(l_owner_pkey_str)); - json_object *l_jobj_owner_pkey = json_object_new_string(l_owner_pkey_str); - if (!l_jobj_owner_pkey) { - json_object_put(l_json_tsd_array); - json_object_put(l_json_subtype); - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - json_object_put(l_jobj_tsd); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "owner_fingerprint", l_jobj_owner_pkey); - DAP_DELETE(l_owner_pkey); - } break; - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER: { - json_object *l_obj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_DECREE_TSD_TYPE_MIN_OWNER"); - if (!l_obj_tsd_type){ - json_object_put(l_json_tsd_array); - json_object_put(l_json_subtype); - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - json_object_put(l_jobj_tsd); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "type", l_obj_tsd_type); - if (l_tsd->size > sizeof(uint256_t)){ - json_object *l_text_wgn = json_object_new_string("Owner min: <WRONG SIZE>"); - if (!l_text_wgn) { - json_object_put(l_json_tsd_array); - json_object_put(l_json_subtype); - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - json_object_put(l_jobj_tsd); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "warning", l_text_wgn); - break; - } - uint256_t l_owner_min = {0}; - _dap_tsd_get_scalar(l_tsd, &l_owner_min); - json_object *l_jobj_owner_min = json_object_new_string(dap_uint256_to_char(l_owner_min, NULL)); - if (!l_jobj_owner_min) { - json_object_put(l_json_tsd_array); - json_object_put(l_json_subtype); - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - json_object_put(l_jobj_tsd); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "owner_min", l_jobj_owner_min); - } break; - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE_WALLET: { - json_object *l_obj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_DECREE_TSD_TYPE_FEE_WALLET"); - if (!l_obj_tsd_type) { - json_object_put(l_json_tsd_array); - json_object_put(l_json_subtype); - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - json_object_put(l_jobj_tsd); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "type", l_obj_tsd_type); - if (l_tsd->size > sizeof(dap_chain_addr_t)) { - json_object *l_text_wgn = json_object_new_string("Wallet for fee: <WRONG SIZE>"); - if (!l_text_wgn) { - json_object_put(l_json_tsd_array); - json_object_put(l_json_subtype); - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - json_object_put(l_jobj_tsd); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "warning", l_text_wgn); - break; - } - dap_chain_addr_t l_addr_fee_wallet = {0}; - _dap_tsd_get_scalar(l_tsd, &l_addr_fee_wallet); - json_object *l_jobj_addr_fee_wallet = dap_chain_addr_to_json(&l_addr_fee_wallet); - if (!l_jobj_addr_fee_wallet) { - json_object_put(l_json_tsd_array); - json_object_put(l_json_subtype); - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - json_object_put(l_jobj_tsd); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "addr", l_jobj_addr_fee_wallet); - } break; - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_TX_HASH: { - json_object *l_obj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_TX_HASH"); - json_object_object_add(l_jobj_tsd, "type", l_obj_tsd_type); - if (l_tsd->size > sizeof(dap_hash_fast_t)) { - json_object *l_text_wgn = json_object_new_string("Stake tx: <WRONG SIZE>"); - json_object_object_add(l_jobj_tsd, "warning", l_text_wgn); - break; - } - dap_hash_fast_t l_stake_tx = {0}; - _dap_tsd_get_scalar(l_tsd, &l_stake_tx); - json_object *l_jobj_tx_hash = - json_object_new_string(dap_chain_hash_fast_to_str_static(&l_stake_tx)); - if (!l_jobj_tx_hash) { - json_object_put(l_json_tsd_array); - json_object_put(l_json_subtype); - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - json_object_put(l_jobj_tsd); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "hash", l_jobj_tx_hash); -// char *l_stake_tx_hash = dap_strcmp(a_hash_out_type, "hex") -// ? dap_enc_base58_encode_hash_to_str(&l_stake_tx) -// : dap_chain_hash_fast_to_str_new(&l_stake_tx); -// dap_string_append_printf(a_str_out, "\tStake tx: %s\n", l_stake_tx_hash); - } break; - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_VALUE: { - json_object *l_obj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_VALUE"); - if (!l_obj_tsd_type){ - json_object_put(l_json_tsd_array); - json_object_put(l_json_subtype); - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - json_object_put(l_jobj_tsd); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "type", l_obj_tsd_type); - if (l_tsd->size > sizeof(uint256_t)) { - json_object *l_text_wgn = json_object_new_string("Stake value: <WRONG SIZE>"); - if (!l_text_wgn){ - json_object_put(l_json_tsd_array); - json_object_put(l_json_subtype); - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - json_object_put(l_jobj_tsd); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "warning", l_text_wgn); - break; - } - uint256_t l_stake_value = uint256_0; - _dap_tsd_get_scalar(l_tsd, &l_stake_value); - json_object *l_jobj_stake_value = json_object_new_string(dap_uint256_to_char(l_stake_value, NULL)); - if (!l_jobj_stake_value){ - json_object_put(l_json_tsd_array); - json_object_put(l_json_subtype); - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - json_object_put(l_jobj_tsd); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "value", l_jobj_stake_value); - } break; - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR: { - json_object *l_obj_tsd_type = json_object_new_string("DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNING_ADDR"); - json_object_object_add(l_jobj_tsd, "type", l_obj_tsd_type); - if (l_tsd->size > sizeof(dap_chain_addr_t)) { - json_object *l_text_wgn = json_object_new_string("Signing addr: <WRONG SIZE>"); - json_object_object_add(l_jobj_tsd, "warning", l_text_wgn); - break; - } - dap_chain_addr_t l_stake_addr_signing = {0}; - _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; - 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); - json_object_object_add(l_jobj_tsd, "pkey", l_jobj_pkey_signing); -// char *l_pkey_signing_str = dap_strcmp(a_hash_out_type, "hex") -// ? dap_enc_base58_encode_hash_to_str(l_pkey_signing) -// : dap_chain_hash_fast_to_str_new(l_pkey_signing); -// dap_string_append_printf(a_str_out, "\tSigning pkey fingerprint: %s\n", l_pkey_signing_str); - } break; - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNER_NODE_ADDR: { - json_object *l_obj_tsd_type = json_object_new_string( - "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNER_NODE_ADDR"); - if (!l_obj_tsd_type) { - json_object_put(l_json_tsd_array); - json_object_put(l_json_subtype); - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - json_object_put(l_jobj_tsd); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "type", l_obj_tsd_type); - if(l_tsd->size > sizeof(dap_chain_node_addr_t)){ - json_object *l_text_wgn = json_object_new_string("Node addr: <WRONG SIZE>"); - if (!l_text_wgn){ - json_object_put(l_json_tsd_array); - json_object_put(l_json_subtype); - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - json_object_put(l_jobj_tsd); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "warning", l_text_wgn); - break; - } - dap_chain_node_addr_t l_node_addr = {0}; - _dap_tsd_get_scalar(l_tsd, &l_node_addr); - char *l_node_addr_str = dap_strdup_printf(NODE_ADDR_FP_STR,NODE_ADDR_FP_ARGS_S(l_node_addr)); - if (!l_node_addr_str) { - json_object_put(l_json_tsd_array); - json_object_put(l_json_subtype); - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - json_object_put(l_jobj_tsd); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_jobj_node_addr = json_object_new_string(l_node_addr_str); - DAP_DELETE(l_node_addr_str); - if (!l_jobj_node_addr){ - json_object_put(l_json_tsd_array); - json_object_put(l_json_subtype); - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - json_object_put(l_jobj_tsd); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "node", l_jobj_node_addr); - } break; - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE: { - json_object *l_obj_tsd_type = json_object_new_string( - "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE"); - json_object_object_add(l_jobj_tsd, "type", l_obj_tsd_type); - if (l_tsd->size > sizeof(uint256_t)) { - json_object *l_text_wgn = json_object_new_string("Min value: <WRONG SIZE>"); - json_object_object_add(l_jobj_tsd, "warning", l_text_wgn); - break; - } - uint256_t l_min_value = uint256_0; - _dap_tsd_get_scalar(l_tsd, &l_min_value); - json_object_object_add(l_jobj_tsd, "value", json_object_new_string(dap_uint256_to_char(l_min_value, NULL))); - } break; - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT: { - json_object *l_obj_tsd_type = json_object_new_string( - "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_SIGNERS_COUNT"); - if (!l_obj_tsd_type) { - json_object_put(l_json_tsd_array); - json_object_put(l_json_subtype); - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - json_object_put(l_jobj_tsd); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "type", l_obj_tsd_type); - if (l_tsd->size > sizeof(uint256_t)) { - json_object *l_text_wgn = json_object_new_string("Min signers count: <WRONG SIZE>"); - if(!l_text_wgn){ - json_object_put(l_json_tsd_array); - json_object_put(l_json_subtype); - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - json_object_put(l_jobj_tsd); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "warning", l_text_wgn); - break; - } - uint256_t l_min_signers_count = uint256_0; - _dap_tsd_get_scalar(l_tsd, &l_min_signers_count); - json_object *l_jobj_min_signers_count = json_object_new_string(dap_uint256_to_char(l_min_signers_count, NULL)); - if (!l_jobj_min_signers_count) { - json_object_put(l_json_tsd_array); - json_object_put(l_json_subtype); - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - json_object_put(l_jobj_tsd); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "count", l_jobj_min_signers_count); - } break; - default: { - json_object *l_obj_tsd_type = json_object_new_string( - "<UNKNOWN_TYPE_TSD_SECTION>"); - if (!l_obj_tsd_type){ - json_object_put(l_json_tsd_array); - json_object_put(l_json_subtype); - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - json_object_put(l_jobj_tsd); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_tsd, "type", l_obj_tsd_type); - } break; - } - json_object_array_add(l_json_tsd_array, l_jobj_tsd); - } - json_object *l_jobj_signs = s_dap_chain_datum_decree_certs_dump_json(a_decree->data_n_signs + a_decree->header.data_size, - a_decree->header.signs_size); - if (!l_jobj_signs){ - json_object_put(l_json_tsd_array); - json_object_put(l_json_subtype); - json_object_put(l_jobj_type); - json_object_put(l_jobj_decree); - dap_json_rpc_error_add(DAP_JSON_RPC_ERR_CODE_SERIALIZATION_SIGN_TO_JSON, "Can't serialize the decree signature in JSON."); - return NULL; - } - json_object_object_add(l_jobj_decree, "type", l_jobj_type); - json_object_object_add(l_jobj_decree, "subtype", l_json_subtype); - json_object_object_add(l_jobj_decree, "TSD", l_json_tsd_array); - json_object_object_add(l_jobj_decree, "signs", l_jobj_signs); - return l_jobj_decree; -} diff --git a/modules/json_rpc/common/dap_json_rpc_chain_datum_token.c b/modules/json_rpc/common/dap_json_rpc_chain_datum_token.c deleted file mode 100644 index aa4139aa4ce2b4a7e2d264759098a4fd6e881eea..0000000000000000000000000000000000000000 --- a/modules/json_rpc/common/dap_json_rpc_chain_datum_token.c +++ /dev/null @@ -1,379 +0,0 @@ - - -#include "dap_json_rpc_chain_datum_token.h" -#include "dap_json_rpc_chain_common.h" -#include "dap_json_rpc_sign.h" -#include "json.h" - -#define LOG_TAG "dap_json_rpc_chain_datum_token" - -json_object *dap_chain_datum_token_flags_to_json(uint16_t a_flags){ - if (!a_flags) { - return json_object_new_null(); - } - json_object *l_jobj_flags = json_object_new_array(); - for (uint16_t i = 0; BIT(i) <= DAP_CHAIN_DATUM_TOKEN_FLAG_MAX; i++){ - if(a_flags & (1 << i)){ - json_object *l_jobj_flag_txt = json_object_new_string(c_dap_chain_datum_token_flag_str[BIT(i)]); - json_object_array_add(l_jobj_flags, l_jobj_flag_txt); - } - } - return l_jobj_flags; -} - - -json_object *dap_chain_datum_token_to_json(dap_chain_datum_token_t * a_token, size_t a_token_size){ - json_object *l_jobj_token = json_object_new_object(); - if (!l_jobj_token){ - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_jobj_type; - json_object *l_jobj_version = json_object_new_uint64(a_token->version); - if (!l_jobj_version) { - json_object_put(l_jobj_token); - dap_json_rpc_allocation_error; - return NULL; - } - switch (a_token->type) { - case DAP_CHAIN_DATUM_TOKEN_TYPE_DECL: - l_jobj_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TYPE_DECL"); - break; - case DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE: - l_jobj_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TYPE_UPDATE"); - break; - default: - l_jobj_type = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_TYPE_UNKNOWN"); - break; - } - if (!l_jobj_type) { - json_object_put(l_jobj_version); - json_object_put(l_jobj_token); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_token, "version", l_jobj_version); - json_object_object_add(l_jobj_token, "type", l_jobj_type); - json_object *l_jobj_subtype = NULL; - json_object *l_jobj_header = json_object_new_object(); - if (!l_jobj_header){ - json_object_put(l_jobj_token); - dap_json_rpc_allocation_error; - return NULL; - } - size_t l_tsd_total_size = 0; - switch (a_token->subtype) { - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE: { - json_object *l_jobj_decimals = json_object_new_uint64(a_token->header_simple.decimals); - if (!l_jobj_decimals){ - json_object_put(l_jobj_header); - json_object_put(l_jobj_token); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_header, "decimals", l_jobj_decimals); - l_jobj_subtype = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_SUBTYPE_SIMPLE"); - }break; - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE: { - json_object *l_jobj_flags = NULL; - json_object *l_jobj_decimals = NULL; - if (a_token->type == DAP_CHAIN_DATUM_TOKEN_TYPE_DECL) { - l_jobj_flags = json_object_new_string(s_flag_str_from_code(a_token->header_private_decl.flags)); - if (!l_jobj_flags){ - json_object_put(l_jobj_header); - json_object_put(l_jobj_token); - dap_json_rpc_allocation_error; - return NULL; - } - l_jobj_decimals = json_object_new_uint64(a_token->header_private_decl.decimals); - if (!l_jobj_decimals) { - json_object_put(l_jobj_flags); - json_object_put(l_jobj_header); - json_object_put(l_jobj_token); - dap_json_rpc_allocation_error; - return NULL; - } - l_tsd_total_size = a_token->header_private_decl.tsd_total_size; - } else { - l_jobj_flags = json_object_new_string(s_flag_str_from_code(a_token->header_private_update.flags)); - if (!l_jobj_flags) { - json_object_put(l_jobj_header); - json_object_put(l_jobj_token); - dap_json_rpc_allocation_error; - return NULL; - } - l_jobj_decimals = json_object_new_uint64(a_token->header_private_update.decimals); - if (!l_jobj_decimals) { - json_object_put(l_jobj_flags); - json_object_put(l_jobj_header); - json_object_put(l_jobj_token); - dap_json_rpc_allocation_error; - return NULL; - } - l_tsd_total_size = a_token->header_private_update.tsd_total_size; - } - json_object_object_add(l_jobj_header, "flags", l_jobj_flags); - json_object_object_add(l_jobj_header, "decimals", l_jobj_decimals); - l_jobj_subtype = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PRIVATE"); - } break; - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE: { - json_object *l_jobj_flags = NULL; - json_object *l_jobj_decimals = NULL; - if (a_token->type == DAP_CHAIN_DATUM_TOKEN_TYPE_DECL) { - l_jobj_flags = json_object_new_string(s_flag_str_from_code(a_token->header_native_decl.flags)); - if (!l_jobj_flags) { - json_object_put(l_jobj_header); - json_object_put(l_jobj_token); - dap_json_rpc_allocation_error; - return NULL; - } - l_jobj_decimals = json_object_new_uint64(a_token->header_native_decl.decimals); - if (!l_jobj_decimals){ - json_object_put(l_jobj_flags); - json_object_put(l_jobj_header); - json_object_put(l_jobj_token); - dap_json_rpc_allocation_error; - return NULL; - } - l_tsd_total_size = a_token->header_native_decl.tsd_total_size; - } else { - l_jobj_flags = json_object_new_string(s_flag_str_from_code(a_token->header_native_update.flags)); - if (!l_jobj_flags) { - json_object_put(l_jobj_header); - json_object_put(l_jobj_token); - dap_json_rpc_allocation_error; - return NULL; - } - l_jobj_decimals = json_object_new_uint64(a_token->header_native_update.decimals); - if (!l_jobj_decimals) { - json_object_put(l_jobj_flags); - json_object_put(l_jobj_header); - json_object_put(l_jobj_token); - dap_json_rpc_allocation_error; - return NULL; - } - l_tsd_total_size = a_token->header_native_update.tsd_total_size; - } - json_object_object_add(l_jobj_header, "flags", l_jobj_flags); - json_object_object_add(l_jobj_header, "decimals", l_jobj_decimals); - l_jobj_subtype = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_SUBTYPE_NATIVE"); - } break; - case DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PUBLIC: { - json_object *l_jobj_flags = json_object_new_string(s_flag_str_from_code(a_token->header_public.flags)); - if (!l_jobj_flags){ - json_object_put(l_jobj_header); - json_object_put(l_jobj_token); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_jobj_premine_supply = json_object_new_string(dap_uint256_to_char(a_token->header_public.premine_supply, NULL)); - if (!l_jobj_premine_supply) { - json_object_put(l_jobj_flags); - json_object_put(l_jobj_header); - json_object_put(l_jobj_token); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_jobj_premine_address = dap_chain_addr_to_json(&a_token->header_public.premine_address); - if (!l_jobj_premine_address) { - json_object_put(l_jobj_flags); - json_object_put(l_jobj_premine_supply); - json_object_put(l_jobj_header); - json_object_put(l_jobj_token); - dap_json_rpc_error_add(DAP_JSON_RPC_ERR_CODE_SERIALIZATION_ADDR_TO_JSON, - "Failed to convert address to JSON."); - return NULL; - } - json_object_object_add(l_jobj_header, "flags", l_jobj_flags); - json_object_object_add(l_jobj_header, "premine_supply", l_jobj_premine_supply); - json_object_object_add(l_jobj_header, "premine_address", l_jobj_premine_address); - l_jobj_subtype = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_SUBTYPE_PUBLIC"); - } break; - default: { - l_jobj_subtype = json_object_new_string("DAP_CHAIN_DATUM_TOKEN_SUBTYPE_UNKNOWN"); - } break; - } - if (!l_jobj_subtype) { - json_object_put(l_jobj_header); - json_object_put(l_jobj_token); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_token, "subtype", l_jobj_subtype); - json_object_object_add(l_jobj_token, "header", l_jobj_header); - json_object *l_jobj_ticker = json_object_new_string(a_token->ticker); - if (!l_jobj_ticker) { - json_object_put(l_jobj_token); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_token, "ticker", l_jobj_ticker); - json_object *l_jobj_signs_valid = json_object_new_uint64(a_token->signs_valid); - if (!l_jobj_signs_valid) { - json_object_put(l_jobj_token); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_token, "signs_valid", l_jobj_signs_valid); - json_object *l_jobj_signs_total = json_object_new_uint64(a_token->signs_total); - if (!l_jobj_signs_total) { - json_object_put(l_jobj_token); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_jobj_token, "signs_total", l_jobj_signs_total); - json_object *l_obj_signs = json_object_new_array(); - if (!l_obj_signs) { - json_object_put(l_jobj_token); - dap_json_rpc_allocation_error; - return NULL; - } - size_t l_offset = 0; - size_t l_certs_field_size = a_token_size - sizeof(*a_token); - while ((l_offset + l_tsd_total_size) < l_certs_field_size) { - dap_sign_t *l_sign = (dap_sign_t *) ((byte_t*)a_token->data_n_tsd + l_tsd_total_size + l_offset); - l_offset += dap_sign_get_size(l_sign); - json_object *l_obj_sign = dap_sign_to_json(l_sign); - if (!l_obj_sign || !dap_sign_get_size(l_sign)) { - json_object_put(l_obj_signs); - json_object_put(l_jobj_token); - dap_json_rpc_error_add(DAP_JSON_RPC_ERR_CODE_SERIALIZATION_SIGN_TO_JSON, "Failed to convert signature to JSON."); - return NULL; - } - json_object_array_add(l_obj_signs, l_obj_sign); - } - json_object_object_add(l_jobj_token, "signs", l_obj_signs); - return l_jobj_token; -} - - -json_object *dap_chain_datum_emission_to_json(dap_chain_datum_token_emission_t *a_emission, size_t a_emission_size){ - json_object *l_emi_obj = json_object_new_object(); - json_object *l_emi_version = json_object_new_uint64(a_emission->hdr.version); - json_object *l_emi_type = json_object_new_string(c_dap_chain_datum_token_emission_type_str[a_emission->hdr.type]); - json_object *l_emi_address = dap_chain_addr_to_json(&a_emission->hdr.address); - json_object *l_emi_header = json_object_new_object(); - json_object *l_emi_data = json_object_new_object(); - if (!l_emi_obj || !l_emi_version || !l_emi_type || !l_emi_address || !l_emi_header || ! l_emi_data) { - json_object_put(l_emi_obj); - json_object_put(l_emi_version); - json_object_put(l_emi_type); - json_object_put(l_emi_address); - json_object_put(l_emi_header); - json_object_put(l_emi_data); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_emi_header, "version", l_emi_version); - json_object_object_add(l_emi_header, "type", l_emi_type); - json_object_object_add(l_emi_header, "address", l_emi_address); - json_object_object_add(l_emi_obj, "header", l_emi_header); - switch (a_emission->hdr.type){ - case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH: { - json_object *l_obj_size = json_object_new_uint64(a_emission->data.type_auth.size); - json_object *l_obj_tsd_total_size = json_object_new_uint64(a_emission->data.type_auth.tsd_total_size); - json_object *l_obj_signs_count = json_object_new_uint64(a_emission->data.type_auth.signs_count); - if (!l_obj_size || !l_obj_tsd_total_size || !l_obj_signs_count) { - json_object_put(l_obj_size); - json_object_put(l_obj_tsd_total_size); - json_object_put(l_obj_signs_count); - json_object_put(l_emi_data); - json_object_put(l_emi_obj); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_emi_data, "size", l_obj_size); - json_object_object_add(l_emi_data, "tsd_total_size", l_obj_tsd_total_size); - json_object_object_add(l_emi_data, "signs_count", l_obj_signs_count); - if (((void *) a_emission->tsd_n_signs + a_emission->data.type_auth.tsd_total_size) > - ((void *) a_emission + a_emission_size)) { - char *l_err_str = dap_strdup_printf("Malformed DATUM type %d, TSD section is out-of-buffer (%" DAP_UINT64_FORMAT_U " vs %zu)", - a_emission->hdr.type, a_emission->data.type_auth.tsd_total_size, a_emission_size); - if (!l_err_str){ - json_object_put(l_emi_data); - json_object_put(l_emi_obj); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_err_tsd = json_object_new_string(l_err_str); - DAP_DELETE(l_err_str); - if (!l_err_tsd) { - json_object_put(l_emi_data); - json_object_put(l_emi_obj); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_emi_data, "ERROR", l_err_tsd); - } - json_object *l_obj_signs = json_object_new_array(); - if (!l_obj_signs){ - json_object_put(l_emi_data); - json_object_put(l_emi_obj); - dap_json_rpc_allocation_error; - return NULL; - } - size_t l_offset = a_emission->data.type_auth.tsd_total_size; - for (int i = 0; i < a_emission->data.type_auth.signs_count; i++) { - dap_sign_t *l_sign = (dap_sign_t *) ((byte_t*)a_emission->tsd_n_signs + l_offset); - l_offset += dap_sign_get_size(l_sign); - json_object *l_obj_sign = dap_sign_to_json(l_sign); - if (!l_obj_sign) { - json_object_put(l_obj_signs); - json_object_put(l_emi_data); - json_object_put(l_emi_obj); - dap_json_rpc_error_add(3, "Failed to serialize signature to JSON object."); - return NULL; - } - json_object_array_add(l_obj_signs, l_obj_sign); - } - json_object_object_add(l_emi_data, "signs", l_obj_signs); - - } break; - case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_ALGO: { - json_object *l_code_name = json_object_new_string(a_emission->data.type_algo.codename); - if (!l_code_name) { - json_object_put(l_emi_data); - json_object_put(l_emi_obj); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_emi_data, "codename", l_code_name); - } break; - case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_ATOM_OWNER: { - json_object *l_value_start = json_object_new_uint64(a_emission->data.type_atom_owner.value_start); - json_object *l_value_change_algo_codename = json_object_new_string( - a_emission->data.type_atom_owner.value_change_algo_codename); - if (!l_value_start || !l_value_change_algo_codename) { - json_object_put(l_value_start); - json_object_put(l_value_change_algo_codename); - json_object_put(l_emi_data); - json_object_put(l_emi_obj); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_emi_data, "value_start", l_value_start); - json_object_object_add(l_emi_data, "value_change_algo_codename", l_value_change_algo_codename); - } break; - case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_SMART_CONTRACT: - { - json_object *l_obj_addr = dap_chain_addr_to_json(&a_emission->data.type_presale.addr); - json_object *l_obj_flags = json_object_new_int64(a_emission->data.type_presale.flags); - json_object *l_obj_lock_time = json_object_new_uint64(a_emission->data.type_presale.lock_time); - if (!l_obj_addr || !l_obj_flags || !l_obj_lock_time) { - json_object_put(l_obj_addr); - json_object_put(l_obj_flags); - json_object_put(l_obj_lock_time); - json_object_put(l_emi_data); - json_object_put(l_emi_obj); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_emi_data, "addr", l_obj_addr); - json_object_object_add(l_emi_data, "flags", l_obj_flags); - json_object_object_add(l_emi_data, "lock_time", l_obj_lock_time); - }break; - } - json_object_object_add(l_emi_obj, "data", l_emi_data); - return l_emi_obj; -} - 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 deleted file mode 100644 index 5df5fdb51304e87c431a9a3c84c274fbc718ff7f..0000000000000000000000000000000000000000 --- a/modules/json_rpc/common/dap_json_rpc_chain_datum_tx.c +++ /dev/null @@ -1,149 +0,0 @@ -#include <memory.h> -#include <assert.h> -#include "dap_common.h" -#include "dap_sign.h" -#include "dap_chain_datum_tx.h" -#include "dap_chain_datum_tx_items.h" - -#include "dap_json_rpc_chain_datum_tx.h" -#include "dap_json_rpc_chain_datum_tx_items.h" -#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" - - - -json_object *dap_chain_datum_tx_to_json(dap_chain_datum_tx_t *a_tx, dap_chain_net_id_t *a_net_id){ - json_object *l_obj_items = json_object_new_array(); - if (!l_obj_items) { - dap_json_rpc_allocation_error; - return NULL; - } - uint32_t - l_tx_items_size_total = 0, - l_tx_items_size = a_tx->header.tx_items_size; - while(l_tx_items_size_total < l_tx_items_size) { - uint8_t *item = a_tx->tx_items + l_tx_items_size_total; - size_t l_tx_item_size = dap_chain_datum_item_tx_get_size(item); - if (l_tx_item_size == 0) { - json_object_put(l_obj_items); - l_obj_items = json_object_new_null(); - break; - } - dap_chain_tx_item_type_t l_item_type = dap_chain_datum_tx_item_get_type(item); - json_object *l_obj_item_type = NULL, *l_obj_item_data = NULL; - switch (l_item_type) { - case TX_ITEM_TYPE_IN: - l_obj_item_type = json_object_new_string("TX_ITEM_TYPE_IN"); - l_obj_item_data = dap_chain_datum_tx_item_in_to_json((dap_chain_tx_in_t*)item); - break; - case TX_ITEM_TYPE_OUT: - l_obj_item_type = json_object_new_string("TX_ITEM_TYPE_OUT"); - l_obj_item_data = dap_chain_datum_tx_item_out_to_json((dap_chain_tx_out_t*)item); - break; - case TX_ITEM_TYPE_IN_REWARD: - l_obj_item_type = json_object_new_string("TX_ITEM_TYPE_IN_REWARD"); - l_obj_item_data = dap_chain_datum_tx_item_in_reward_to_json((dap_chain_tx_in_reward_t*)item); - break; - case TX_ITEM_TYPE_IN_EMS: - l_obj_item_type = json_object_new_string("TX_ITEM_TYPE_IN_EMS"); - l_obj_item_data = dap_chain_datum_tx_item_in_ems_to_json((dap_chain_tx_in_ems_t*)item); - break; - case TX_ITEM_TYPE_SIG: - l_obj_item_type = json_object_new_string("TX_ITEM_TYPE_SIG"); - l_obj_item_data = dap_chain_datum_tx_item_sig_to_json((dap_chain_tx_sig_t*)item); - break; - case TX_ITEM_TYPE_RECEIPT: - l_obj_item_type = json_object_new_string("TX_ITEM_TYPE_RECEIPT"); - l_obj_item_data = dap_chain_datum_tx_receipt_to_json((dap_chain_datum_tx_receipt_t*)item); - break; - case TX_ITEM_TYPE_IN_COND: - l_obj_item_type = json_object_new_string("TX_ITEM_TYPE_IN_COND"); - l_obj_item_data = dap_chain_datum_tx_item_in_cond_to_json((dap_chain_tx_in_cond_t*)item); - break; - case TX_ITEM_TYPE_OUT_COND: - l_obj_item_type = json_object_new_string("TX_ITEM_TYPE_OUT_COND"); - - - switch (((dap_chain_tx_out_cond_t*)item)->header.subtype) { - case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY: - l_obj_item_data = dap_chain_datum_tx_item_out_cond_srv_pay_to_json((dap_chain_tx_out_cond_t*)item); - break; - case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK: - l_obj_item_data = dap_chain_net_srv_stake_lock_cond_out_to_json((dap_chain_tx_out_cond_t*)item); - break; - case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE: - l_obj_item_data = dap_chain_datum_tx_item_out_cond_srv_stake_to_json((dap_chain_tx_out_cond_t*)item); - break; - case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE: - l_obj_item_data = dap_chain_datum_tx_item_out_cond_srv_xchange_to_json((dap_chain_tx_out_cond_t*)item); - break; - case DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE: - l_obj_item_data = json_object_new_object(); - break; - default:break; - } - // add time - dap_time_t l_ts_exp = ((dap_chain_tx_out_cond_t*)item)->header.ts_expires; - char l_time_str[32] = "never"; - if (l_ts_exp) { - dap_time_to_str_rfc822(l_time_str, DAP_TIME_STR_SIZE, l_ts_exp); /* Convert ts to "Sat May 17 01:17:08 2014\n" */ - l_time_str[strlen(l_time_str)-1] = '\0'; /* Remove "\n"*/ - } - json_object_object_add(l_obj_item_data, "ts_expires", json_object_new_string(l_time_str)); - json_object_object_add(l_obj_item_data, "subtype", json_object_new_string(dap_chain_tx_out_cond_subtype_to_str(((dap_chain_tx_out_cond_t*)item)->header.subtype))); - char *l_val_str, *l_val_datoshi_str = dap_uint256_to_char(((dap_chain_tx_out_cond_t*)item)->header.value, &l_val_str); - json_object_object_add(l_obj_item_data, "value", json_object_new_string(l_val_str)); - json_object_object_add(l_obj_item_data, "value_datoshi", json_object_new_string(l_val_datoshi_str)); - char uid_str[32]; - sprintf(uid_str, "0x%016"DAP_UINT64_FORMAT_x"", ((dap_chain_tx_out_cond_t*)item)->header.srv_uid.uint64); - json_object_object_add(l_obj_item_data, "uid", json_object_new_string(uid_str)); - break; - case TX_ITEM_TYPE_OUT_EXT: - l_obj_item_type = json_object_new_string("TX_ITEM_TYPE_OUT_EXT"); - l_obj_item_data = dap_chain_datum_tx_item_out_ext_to_json((dap_chain_tx_out_ext_t*)item); - break; - case TX_ITEM_TYPE_TSD: - l_obj_item_type = json_object_new_string("TX_ITEM_TYPE_TSD"); - l_obj_item_data = dap_chain_datum_tx_item_tsd_to_json((dap_chain_tx_tsd_t*)item); - break; - case TX_ITEM_TYPE_VOTE: - l_obj_item_type = json_object_new_string("TX_ITEM_TYPE_VOTE"); - 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"); - l_obj_item_data = dap_chain_datum_tx_item_voting_tsd_to_json(a_tx); - break; - default: { - char *l_hash_str; - dap_get_data_hash_str_static(a_tx, dap_chain_datum_tx_get_size(a_tx), l_hash_str); - log_it(L_NOTICE, "Transaction %s has an item whose type cannot be handled by the dap_chain_datum_tx_to_json function.", l_hash_str); - break; - } - } - if (!l_obj_item_type){ - json_object_array_add(l_obj_items, json_object_new_null()); - } else { - if (!l_obj_item_data) - l_obj_item_data = json_object_new_null(); - json_object *l_obj_item = json_object_new_object(); - if (!l_obj_item) { - json_object_put(l_obj_item_type); - json_object_put(l_obj_item_data); - json_object_put(l_obj_items); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_obj_item, "type", l_obj_item_type); - json_object_object_add(l_obj_item, "data", l_obj_item_data); - json_object_array_add(l_obj_items, l_obj_item); - } - l_tx_items_size_total += l_tx_item_size; - } - return l_obj_items; -} diff --git a/modules/json_rpc/common/dap_json_rpc_chain_datum_tx_items.c b/modules/json_rpc/common/dap_json_rpc_chain_datum_tx_items.c deleted file mode 100644 index 3e0c0cd28474cbaf6884ba71c76d4f13f45a9234..0000000000000000000000000000000000000000 --- a/modules/json_rpc/common/dap_json_rpc_chain_datum_tx_items.c +++ /dev/null @@ -1,305 +0,0 @@ -#include <stdint.h> -#include <string.h> - -#include "dap_common.h" -#include "dap_enc_key.h" -#include "dap_chain_common.h" -#include "dap_sign.h" -#include "dap_hash.h" -#include "dap_chain_datum_tx.h" -#include "dap_chain_datum_tx_in.h" -#include "dap_chain_datum_tx_out.h" -#include "dap_chain_datum_tx_in_cond.h" -#include "dap_chain_datum_tx_out_cond.h" -#include "dap_chain_datum_tx_items.h" -#include "dap_enc_base58.h" - -#include "dap_json_rpc_chain_datum_tx_items.h" -#include "dap_json_rpc_chain_common.h" -#include "dap_json_rpc_sign.h" -#include "json.h" - -#define LOG_TAG "dap_json_rpc_chain_datum_tx_items" - -json_object *dap_chain_datum_tx_item_out_cond_srv_pay_to_json(dap_chain_tx_out_cond_t *item) { - char *l_coins_str, - *l_value_str = dap_uint256_to_char(((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.unit_price_max_datoshi, &l_coins_str); - char *l_hash_str = dap_enc_base58_encode_hash_to_str_static(&((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.pkey_hash); - json_object *l_obj = json_object_new_object(); - char unit_str[32]; - snprintf(unit_str, 32, "0x%08x", ((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.unit.uint32); - json_object_object_add(l_obj, "unit", json_object_new_string(unit_str)); - json_object_object_add(l_obj, "pkey", json_object_new_string(l_hash_str)); - json_object_object_add(l_obj, "max_price", json_object_new_string(l_coins_str)); - json_object_object_add(l_obj, "max_price_datoshi", json_object_new_string(l_value_str)); - return l_obj; -} - -json_object* dap_chain_datum_tx_item_out_cond_srv_xchange_to_json(dap_chain_tx_out_cond_t* a_srv_xchange) { - if (a_srv_xchange->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE){ - json_object *l_object = json_object_new_object(); - json_object_object_add(l_object, "value", json_object_new_string(dap_uint256_to_char(a_srv_xchange->header.value, NULL))); - json_object_object_add(l_object, "rate", ( { - char *l_rate; dap_uint256_to_char(a_srv_xchange->subtype.srv_xchange.rate, &l_rate); - json_object_new_string(l_rate); } )); - json_object_object_add(l_object, "srv_uid", json_object_new_uint64(a_srv_xchange->header.srv_uid.uint64)); - json_object_object_add(l_object, "buy_net_id", dap_chain_net_id_to_json(a_srv_xchange->subtype.srv_xchange.buy_net_id)); - json_object_object_add(l_object, "sell_net_id", dap_chain_net_id_to_json(a_srv_xchange->subtype.srv_xchange.sell_net_id)); - json_object_object_add(l_object, "buy_token", json_object_new_string(a_srv_xchange->subtype.srv_xchange.buy_token)); - json_object_object_add(l_object, "seller_addr", dap_chain_addr_to_json(&a_srv_xchange->subtype.srv_xchange.seller_addr)); - //TODO: Parse TSD - return l_object; - } - return NULL; -} - -json_object *dap_chain_datum_tx_item_out_cond_srv_stake_to_json(dap_chain_tx_out_cond_t* a_srv_stake) { - if (a_srv_stake->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE) { - json_object *l_object = json_object_new_object(); - json_object *l_obj_value = json_object_new_string(dap_uint256_to_char(a_srv_stake->header.value, NULL)); - json_object *l_obj_srv_uid = json_object_new_uint64(a_srv_stake->header.srv_uid.uint64); - json_object *l_obj_signing_addr = dap_chain_addr_to_json(&a_srv_stake->subtype.srv_stake_pos_delegate.signing_addr); - char *l_signer_node_addr = dap_strdup_printf( - NODE_ADDR_FP_STR, - NODE_ADDR_FP_ARGS_S(a_srv_stake->subtype.srv_stake_pos_delegate.signer_node_addr)); - json_object *l_obj_signer_node_addr = json_object_new_string(l_signer_node_addr); - DAP_DELETE(l_signer_node_addr); - json_object_object_add(l_object, "value", l_obj_value); - json_object_object_add(l_object, "srv_uid", l_obj_srv_uid); - json_object_object_add(l_object, "signind_addr", l_obj_signing_addr); - json_object_object_add(l_object, "signer_node_addr", l_obj_signer_node_addr); - return l_object; - } - return NULL; -} - - -json_object *dap_chain_net_srv_stake_lock_cond_out_to_json(dap_chain_tx_out_cond_t *a_stake_lock) -{ - if (a_stake_lock->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK) { - json_object *l_object = json_object_new_object(); - json_object_object_add(l_object, "value", json_object_new_string(dap_uint256_to_char(a_stake_lock->header.value, NULL))); - json_object_object_add(l_object, "srv_uid", json_object_new_uint64(a_stake_lock->header.srv_uid.uint64)); - json_object_object_add(l_object, "reinvest_percent", - json_object_new_string(dap_uint256_to_char(a_stake_lock->subtype.srv_stake_lock.reinvest_percent, NULL))); - json_object_object_add(l_object, "time_unlock", json_object_new_uint64(a_stake_lock->subtype.srv_stake_lock.time_unlock)); - json_object_object_add(l_object, "flags", json_object_new_uint64(a_stake_lock->subtype.srv_stake_lock.flags)); - return l_object; - } - return NULL; -} - - -json_object* dap_chain_datum_tx_item_out_to_json(const dap_chain_tx_out_t *a_out) { - json_object *l_object = json_object_new_object(); - char *l_val_coins, *l_val_datoshi = dap_uint256_to_char(a_out->header.value, &l_val_coins); - json_object_object_add(l_object, "value", json_object_new_string(l_val_coins)); - json_object_object_add(l_object, "value_datoshi", json_object_new_string(l_val_datoshi)); - json_object_object_add(l_object, "address", dap_chain_addr_to_json(&a_out->addr)); - return l_object; -} - - -json_object* dap_chain_datum_tx_item_out_ext_to_json(const dap_chain_tx_out_ext_t *a_out_ext) { - json_object *l_obj = json_object_new_object(); - json_object_object_add(l_obj, "value", json_object_new_string(dap_uint256_to_char(a_out_ext->header.value, NULL))); - json_object_object_add(l_obj, "addr", dap_chain_addr_to_json(&a_out_ext->addr)); - json_object_object_add(l_obj, "token", json_object_new_string(a_out_ext->token)); - return l_obj; -} - -json_object* dap_chain_datum_tx_item_in_cond_to_json(dap_chain_tx_in_cond_t *a_in_cond){ - json_object *l_obj = json_object_new_object(); - if (!l_obj) { - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_obj_receipt_idx = json_object_new_uint64(a_in_cond->header.receipt_idx); - if (!l_obj_receipt_idx) { - json_object_put(l_obj); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_obj_out_prev_idx = json_object_new_uint64(a_in_cond->header.tx_out_prev_idx); - if (!l_obj_out_prev_idx) { - json_object_put(l_obj_receipt_idx); - json_object_put(l_obj); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_obj_prev_hash = NULL; - if (dap_hash_fast_is_blank(&a_in_cond->header.tx_prev_hash)){ - l_obj_prev_hash = json_object_new_null(); - } else { - char *l_prev_hash = dap_hash_fast_to_str_new(&a_in_cond->header.tx_prev_hash); - if(!l_prev_hash) { - json_object_put(l_obj_out_prev_idx); - json_object_put(l_obj_receipt_idx); - json_object_put(l_obj); - dap_json_rpc_allocation_error; - return NULL; - } - l_obj_prev_hash = json_object_new_string(dap_strdup(l_prev_hash)); - if (!l_obj_prev_hash) { - json_object_put(l_obj_out_prev_idx); - json_object_put(l_obj_receipt_idx); - json_object_put(l_obj); - DAP_DELETE(l_prev_hash); - dap_json_rpc_allocation_error; - return NULL; - } - DAP_DELETE(l_prev_hash); - } - json_object_object_add(l_obj, "receipt_idx", l_obj_receipt_idx); - json_object_object_add(l_obj, "out_prev_idx", l_obj_out_prev_idx); - json_object_object_add(l_obj, "tx_prev_hash", l_obj_prev_hash); - return l_obj; -} - -json_object* dap_chain_datum_tx_item_in_to_json(dap_chain_tx_in_t *a_in){ - json_object *l_obj_in = json_object_new_object(); - if (!l_obj_in) { - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_obj_prev_idx = json_object_new_uint64(a_in->header.tx_out_prev_idx); - if (!l_obj_prev_idx) { - json_object_put(l_obj_in); - dap_json_rpc_allocation_error; - return NULL; - } - char l_hash[DAP_CHAIN_HASH_FAST_STR_SIZE]; - dap_chain_hash_fast_to_str(&a_in->header.tx_prev_hash, l_hash, sizeof(l_hash)); - json_object *l_obj_hash = json_object_new_string(l_hash); - if (!l_obj_hash) { - json_object_put(l_obj_in); - json_object_put(l_obj_prev_idx); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_obj_in, "prev_idx", l_obj_prev_idx); - json_object_object_add(l_obj_in, "prev_hash", l_obj_hash); - return l_obj_in; -} - -json_object* dap_chain_datum_tx_item_in_reward_to_json(dap_chain_tx_in_reward_t *a_in_reward){ - json_object *l_jobj_ret = json_object_new_object(); - char *l_hash_block = dap_hash_fast_to_str_new(&a_in_reward->block_hash); - if (!l_jobj_ret && !l_hash_block) { - json_object_put(l_jobj_ret); - DAP_DEL_Z(l_hash_block); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_jobj_block_hash = json_object_new_string(l_hash_block); - DAP_DEL_Z(l_hash_block); - if (!l_jobj_block_hash) { - return NULL; - } - json_object_object_add(l_jobj_ret, "block_hash", l_jobj_block_hash); - return l_jobj_ret; -} - -json_object* dap_chain_datum_tx_item_tsd_to_json(dap_chain_tx_tsd_t *a_tsd){ - json_object *l_object = json_object_new_object(); - if (!l_object) { - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_obj_tsd_type = json_object_new_int(a_tsd->header.type); - if(!l_obj_tsd_type) { - json_object_put(l_object); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_obj_tsd_size = json_object_new_uint64(a_tsd->header.size); - if (!l_obj_tsd_size) { - json_object_put(l_obj_tsd_type); - json_object_put(l_object); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_obj_data = json_object_new_string_len((char *)a_tsd->tsd, a_tsd->header.size); - if (!l_obj_data) { - json_object_put(l_obj_tsd_size); - json_object_put(l_obj_tsd_type); - json_object_put(l_object); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_object, "type", l_obj_tsd_type); - json_object_object_add(l_object, "size", l_obj_tsd_size); - json_object_object_add(l_object, "data", l_obj_data); - return l_object; -} - -json_object *dap_chain_datum_tx_item_in_ems_to_json(const dap_chain_tx_in_ems_t *a_in_ems) -{ - json_object *l_object = json_object_new_object(); - if (!l_object) { - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_obj_ticker = json_object_new_string(a_in_ems->header.ticker); - if (!l_obj_ticker){ - json_object_put(l_object); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_obj_chain_id = json_object_new_uint64(a_in_ems->header.token_emission_chain_id.uint64); - if (!l_obj_chain_id) { - json_object_put(l_object); - json_object_put(l_obj_ticker); - dap_json_rpc_allocation_error; - return NULL; - } - char l_ehf[DAP_CHAIN_HASH_FAST_STR_SIZE]; - dap_chain_hash_fast_to_str(&a_in_ems->header.token_emission_hash, l_ehf, sizeof(l_ehf)); - json_object *l_obj_ehf = json_object_new_string(l_ehf); - if (!l_obj_ehf) { - json_object_put(l_object); - json_object_put(l_obj_chain_id); - json_object_put(l_obj_ticker); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_object, "ticker", l_obj_ticker); - json_object_object_add(l_object, "chain_id", l_obj_chain_id); - json_object_object_add(l_object, "emission_hash", l_obj_ehf); - return l_object; -} - -json_object *dap_chain_datum_tx_item_out_cond_fee_to_json(dap_chain_tx_out_cond_t *a_fee) { - return a_fee->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE - ? ( { - json_object *l_obj = json_object_new_object(); - json_object_object_add(l_obj, "balance", json_object_new_string(dap_uint256_to_char(a_fee->header.value, NULL))); - l_obj; - } ) - : NULL; -} - -json_object* dap_chain_datum_tx_item_sig_to_json(const dap_chain_tx_sig_t *a_sig){ - json_object *l_object = json_object_new_object(); - if (!l_object) { - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_sign_size = json_object_new_uint64(a_sig->header.sig_size); - if (!l_sign_size) { - json_object_put(l_object); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_sign = dap_sign_to_json((dap_sign_t*)a_sig->sig); - if (!l_sign) { - json_object_put(l_object); - json_object_put(l_sign_size); - dap_json_rpc_error_add(DAP_JSON_RPC_ERR_CODE_SERIALIZATION_SIGN_TO_JSON, - "Error serializing signature to JSON."); - return NULL; - } - json_object_object_add(l_object, "sign_size", l_sign_size); - json_object_object_add(l_object, "sign", l_sign); - return l_object; -} diff --git a/modules/json_rpc/common/dap_json_rpc_chain_datum_tx_receipt.c b/modules/json_rpc/common/dap_json_rpc_chain_datum_tx_receipt.c deleted file mode 100644 index 9e24faf6a2f7434bb39d4eec7a140310521d86a9..0000000000000000000000000000000000000000 --- a/modules/json_rpc/common/dap_json_rpc_chain_datum_tx_receipt.c +++ /dev/null @@ -1,80 +0,0 @@ -#include "dap_common.h" -#include "dap_enc_key.h" -#include "dap_sign.h" -#include "dap_chain_datum_tx_receipt.h" - -#include "dap_json_rpc_sign.h" -#include "dap_json_rpc_chain_datum_tx_receipt.h" -#include "json.h" - -#define LOG_TAG "dap_json_rpc_chain_datum_tx_receipt" - - -json_object* dap_chain_receipt_info_to_json(dap_chain_receipt_info_t *a_info){ - json_object *l_obj = json_object_new_object(); - if (!l_obj) { - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_obj, "uid", json_object_new_uint64(a_info->srv_uid.uint64)); -#if DAP_CHAIN_NET_SRV_UID_SIZE == 8 - json_object_object_add(l_obj, "ext_size", json_object_new_uint64(a_info->addition)); -#endif - json_object_object_add(l_obj, "units", json_object_new_uint64(a_info->units)); - json_object_object_add(l_obj, "units_type", json_object_new_string(dap_chain_srv_unit_enum_to_str(a_info->units_type.enm))); - - char *l_value, *l_datoshi_value = dap_uint256_to_char(a_info->value_datoshi, &l_value); - json_object_object_add(l_obj, "value", json_object_new_string(l_value)); - json_object_object_add(l_obj, "value_datoshi", json_object_new_string(l_datoshi_value)); - return l_obj; -} - -json_object *dap_chain_datum_tx_receipt_to_json(dap_chain_datum_tx_receipt_t *a_receipt) { - json_object *l_obj = json_object_new_object(); - if (!l_obj) { - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_obj_info = dap_chain_receipt_info_to_json(&a_receipt->receipt_info); - if (!l_obj_info) { - json_object_put(l_obj); - return NULL; - } - json_object *l_obj_size = json_object_new_uint64(a_receipt->size); - if (!l_obj_size) { - json_object_put(l_obj); - json_object_put(l_obj_info); - dap_json_rpc_allocation_error; - return NULL; - } - //Provider - dap_sign_t *l_first_sign = dap_chain_datum_tx_receipt_sign_get(a_receipt, a_receipt->size, 1); - //Client - dap_sign_t *l_second_sign = dap_chain_datum_tx_receipt_sign_get(a_receipt, a_receipt->size, 2); - json_object *l_obj_signs = json_object_new_object(); - if (!l_obj_signs) { - json_object_put(l_obj_size); - json_object_put(l_obj_info); - json_object_put(l_obj); - dap_json_rpc_allocation_error; - return NULL; - } - json_object *l_obj_provider_sign = dap_sign_to_json(l_first_sign); - json_object *l_obj_client_sign = dap_sign_to_json(l_second_sign); - json_object_object_add(l_obj_signs, "provider", l_obj_provider_sign); - json_object_object_add(l_obj_signs, "client", l_obj_client_sign); - json_object *l_exts_data = json_object_new_string_len((char *)a_receipt->exts_n_signs, a_receipt->exts_size); - if (!l_exts_data) { - json_object_put(l_obj_size); - json_object_put(l_obj_info); - json_object_put(l_obj_signs); - json_object_put(l_obj); - dap_json_rpc_allocation_error; - return NULL; - } - json_object_object_add(l_obj, "info", l_obj_info); - json_object_object_add(l_obj, "size", l_obj_size); - json_object_object_add(l_obj, "sings", l_obj_signs); - json_object_object_add(l_obj, "exts_data", l_exts_data); - return l_obj; -} diff --git a/modules/json_rpc/common/include/dap_json_rpc_chain_common.h b/modules/json_rpc/common/include/dap_json_rpc_chain_common.h deleted file mode 100644 index d88b9b4a561a2fc74048ab397b443412781e9147..0000000000000000000000000000000000000000 --- a/modules/json_rpc/common/include/dap_json_rpc_chain_common.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Authors: - * Alexey V. Stratulat <alexey.stratulat@demlabs.net> - * Olzhas Zharasbaev <oljas.jarasbaev@demlabs.net> - * DeM Labs Inc. https://demlabs.net - * DeM Labs Open source community https://gitlab.demlabs.net/cellframe/cellframe-sdk - * Copyright (c) 2017-2023 - * All rights reserved. - - This file is part of DAP (Demlabs Application Protocol) the open source project - - DAP (Demlabs Application Protocol) is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - DAP is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. -*/ - -#pragma once - -#include "dap_chain_common.h" -#include "dap_json_rpc_errors.h" - -json_object *dap_chain_addr_to_json(const dap_chain_addr_t *a_addr); - -DAP_STATIC_INLINE json_object *dap_chain_net_id_to_json(dap_chain_net_id_t a_net_id) { - return json_object_new_uint64(a_net_id.uint64); -} diff --git a/modules/json_rpc/common/include/dap_json_rpc_chain_datum.h b/modules/json_rpc/common/include/dap_json_rpc_chain_datum.h deleted file mode 100644 index 6f4767fae3425c250ceba167baea67016ed086f8..0000000000000000000000000000000000000000 --- a/modules/json_rpc/common/include/dap_json_rpc_chain_datum.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Authors: - * Alexey V. Stratulat <alexey.stratulat@demlabs.net> - * Olzhas Zharasbaev <oljas.jarasbaev@demlabs.net> - * DeM Labs Inc. https://demlabs.net - * DeM Labs Open source community https://gitlab.demlabs.net/cellframe/cellframe-sdk - * Copyright (c) 2017-2023 - * All rights reserved. - - This file is part of DAP (Demlabs Application Protocol) the open source project - - DAP (Demlabs Application Protocol) is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - DAP is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. -*/ -#pragma once - -#include "dap_chain_datum.h" -#include "dap_json_rpc_errors.h" - -json_object * dap_chain_datum_to_json(dap_chain_datum_t* a_datum); -json_object * dap_chain_datum_data_to_json(dap_chain_datum_t *a_datum); \ No newline at end of file diff --git a/modules/json_rpc/common/include/dap_json_rpc_chain_datum_anchor.h b/modules/json_rpc/common/include/dap_json_rpc_chain_datum_anchor.h deleted file mode 100644 index 64c2f0bf16e398b04be30417c0596f41c7ac1ac8..0000000000000000000000000000000000000000 --- a/modules/json_rpc/common/include/dap_json_rpc_chain_datum_anchor.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Authors: - * Alexey V. Stratulat <alexey.stratulat@demlabs.net> - * Olzhas Zharasbaev <oljas.jarasbaev@demlabs.net> - * DeM Labs Inc. https://demlabs.net - * DeM Labs Open source community https://gitlab.demlabs.net/cellframe/cellframe-sdk - * Copyright (c) 2017-2023 - * All rights reserved. - - This file is part of DAP (Demlabs Application Protocol) the open source project - - DAP (Demlabs Application Protocol) is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - DAP is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. -*/ - - -#pragma once - -#include "dap_chain_datum_anchor.h" -#include "dap_json_rpc_errors.h" - -json_object *dap_chain_datum_anchor_to_json(dap_chain_datum_anchor_t *a_anchor); - diff --git a/modules/json_rpc/common/include/dap_json_rpc_chain_datum_decree.h b/modules/json_rpc/common/include/dap_json_rpc_chain_datum_decree.h deleted file mode 100644 index de30d1c0d5af54f5a153892bbfb0251021ef565b..0000000000000000000000000000000000000000 --- a/modules/json_rpc/common/include/dap_json_rpc_chain_datum_decree.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Authors: - * Alexey V. Stratulat <alexey.stratulat@demlabs.net> - * Olzhas Zharasbaev <oljas.jarasbaev@demlabs.net> - * DeM Labs Inc. https://demlabs.net - * DeM Labs Open source community https://gitlab.demlabs.net/cellframe/cellframe-sdk - * Copyright (c) 2017-2023 - * All rights reserved. - - This file is part of DAP (Demlabs Application Protocol) the open source project - - DAP (Demlabs Application Protocol) is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - DAP is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. -*/ -#pragma once - -#include "dap_chain_datum_decree.h" -#include "dap_json_rpc_errors.h" - -/** - * @brief dap_chain_datum_decree_to_json Convert dap_chain_datum_decree_t tp json_object - * @param a_decree pointer to decree - * @return pointer json_object - */ -json_object *dap_chain_datum_decree_to_json(dap_chain_datum_decree_t *a_decree); diff --git a/modules/json_rpc/common/include/dap_json_rpc_chain_datum_token.h b/modules/json_rpc/common/include/dap_json_rpc_chain_datum_token.h deleted file mode 100644 index b63649e5471fa4251ca2b6a0e085f30beb6b0d83..0000000000000000000000000000000000000000 --- a/modules/json_rpc/common/include/dap_json_rpc_chain_datum_token.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Authors: - * Alexey V. Stratulat <alexey.stratulat@demlabs.net> - * Olzhas Zharasbaev <oljas.jarasbaev@demlabs.net> - * DeM Labs Inc. https://demlabs.net - * DeM Labs Open source community https://gitlab.demlabs.net/cellframe/cellframe-sdk - * Copyright (c) 2017-2023 - * All rights reserved. - - This file is part of DAP (Demlabs Application Protocol) the open source project - - DAP (Demlabs Application Protocol) is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - DAP is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. -*/ - -#pragma once - -#include "dap_chain_datum_token.h" -#include "dap_json_rpc_errors.h" - -json_object *dap_chain_datum_token_to_json(dap_chain_datum_token_t * a_token, size_t a_token_size); -json_object *dap_chain_datum_token_flags_to_json(uint16_t a_flags); -json_object *dap_chain_datum_emission_to_json(dap_chain_datum_token_emission_t *a_emission, size_t a_emission_size); diff --git a/modules/json_rpc/common/include/dap_json_rpc_chain_datum_tx.h b/modules/json_rpc/common/include/dap_json_rpc_chain_datum_tx.h deleted file mode 100644 index 7d4e64ef59e30c827278df7e0887127f99e8d202..0000000000000000000000000000000000000000 --- a/modules/json_rpc/common/include/dap_json_rpc_chain_datum_tx.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Authors: - * Alexey V. Stratulat <alexey.stratulat@demlabs.net> - * Olzhas Zharasbaev <oljas.jarasbaev@demlabs.net> - * DeM Labs Inc. https://demlabs.net - * DeM Labs Open source community https://gitlab.demlabs.net/cellframe/cellframe-sdk - * Copyright (c) 2017-2023 - * All rights reserved. - - This file is part of DAP (Demlabs Application Protocol) the open source project - - DAP (Demlabs Application Protocol) is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - DAP is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. -*/ - -#pragma once - -#include "dap_chain_datum_tx.h" -#include "dap_json_rpc_errors.h" - -json_object * dap_chain_datum_tx_to_json(dap_chain_datum_tx_t *a_tx, dap_chain_net_id_t *a_net_id); diff --git a/modules/json_rpc/common/include/dap_json_rpc_chain_datum_tx_items.h b/modules/json_rpc/common/include/dap_json_rpc_chain_datum_tx_items.h deleted file mode 100644 index 815c8e89b2557287aa4611f45c1335f96971575b..0000000000000000000000000000000000000000 --- a/modules/json_rpc/common/include/dap_json_rpc_chain_datum_tx_items.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Authors: - * Alexey V. Stratulat <alexey.stratulat@demlabs.net> - * Olzhas Zharasbaev <oljas.jarasbaev@demlabs.net> - * DeM Labs Inc. https://demlabs.net - * DeM Labs Open source community https://gitlab.demlabs.net/cellframe/cellframe-sdk - * Copyright (c) 2017-2023 - * All rights reserved. - - This file is part of DAP (Demlabs Application Protocol) the open source project - - DAP (Demlabs Application Protocol) is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - DAP is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. -*/ -#pragma once - -#include "dap_chain_datum_tx_items.h" -#include "dap_json_rpc_errors.h" - - -json_object *dap_chain_datum_tx_item_in_ems_to_json(const dap_chain_tx_in_ems_t *a_in_ems); -json_object* dap_chain_datum_tx_item_in_to_json(dap_chain_tx_in_t *a_in); -json_object* dap_chain_datum_tx_item_in_reward_to_json(dap_chain_tx_in_reward_t *a_in_reward); -json_object* dap_chain_datum_tx_item_tsd_to_json(dap_chain_tx_tsd_t *a_tsd); -json_object* dap_chain_datum_tx_item_in_cond_to_json(dap_chain_tx_in_cond_t *a_in_cond); -json_object* dap_chain_datum_tx_item_out_to_json(const dap_chain_tx_out_t *a_out); -json_object* dap_chain_datum_tx_item_out_ext_to_json(const dap_chain_tx_out_ext_t *a_out_ext); -json_object *dap_chain_datum_tx_item_out_cond_fee_to_json(dap_chain_tx_out_cond_t *a_fee); -json_object *dap_chain_datum_tx_item_out_cond_srv_pay_to_json(dap_chain_tx_out_cond_t *item); -json_object* dap_chain_datum_tx_item_out_cond_srv_xchange_to_json(dap_chain_tx_out_cond_t* a_srv_xchange); -json_object *dap_chain_datum_tx_item_out_cond_srv_stake_to_json(dap_chain_tx_out_cond_t* a_srv_stake); -json_object *dap_chain_net_srv_stake_lock_cond_out_to_json(dap_chain_tx_out_cond_t *a_stake_lock); -json_object* dap_chain_datum_tx_item_sig_to_json(const dap_chain_tx_sig_t *a_sig); diff --git a/modules/json_rpc/common/include/dap_json_rpc_chain_datum_tx_receipt.h b/modules/json_rpc/common/include/dap_json_rpc_chain_datum_tx_receipt.h deleted file mode 100644 index c27cfcfd0b79a1224068b055bd5480afa71f4b22..0000000000000000000000000000000000000000 --- a/modules/json_rpc/common/include/dap_json_rpc_chain_datum_tx_receipt.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Authors: - * Alexey V. Stratulat <alexey.stratulat@demlabs.net> - * Olzhas Zharasbaev <oljas.jarasbaev@demlabs.net> - * DeM Labs Inc. https://demlabs.net - * DeM Labs Open source community https://gitlab.demlabs.net/cellframe/cellframe-sdk - * Copyright (c) 2017-2023 - * All rights reserved. - - This file is part of DAP (Demlabs Application Protocol) the open source project - - DAP (Demlabs Application Protocol) is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - DAP is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. -*/ -#pragma once - -#include "dap_chain_datum_tx_receipt.h" -#include "dap_json_rpc_errors.h" - -json_object *dap_chain_receipt_info_to_json(dap_chain_receipt_info_t *a_info); -json_object *dap_chain_datum_tx_receipt_to_json(dap_chain_datum_tx_receipt_t *a_receipt); \ No newline at end of file diff --git a/modules/json_rpc/mempool/CMakeLists.txt b/modules/json_rpc/mempool/CMakeLists.txt deleted file mode 100644 index 86dd39002f2fcdb106097bb8e27b241869f6b3ff..0000000000000000000000000000000000000000 --- a/modules/json_rpc/mempool/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -cmake_minimum_required(VERSION 3.10) -project (dap_json_rpc_chain_mempool) - - -file(GLOB DAP_JSON_RPC_CHAIN_MEMPOOL_HEADERS include/*.h) -file(GLOB DAP_JSON_RPC_CHAIN_MEMPOOL_SRCS *.c) - -add_library(${PROJECT_NAME} STATIC ${DAP_JSON_RPC_CHAIN_MEMPOOL_SRCS} ${DAP_JSON_RPC_CHAIN_MEMPOOL_HEADERS}) - -target_link_libraries(dap_json_rpc_chain_mempool dap_http_server dap_client dap_chain_net dap_global_db dap_core dap_chain_cs_blocks dap_chain_mempool dap_json_rpc_core dap_chain_btc_rpc) -target_include_directories(dap_json_rpc_chain_mempool PUBLIC include/ ) diff --git a/modules/json_rpc/mempool/dap_chain_mempool_rpc.c b/modules/json_rpc/mempool/dap_chain_mempool_rpc.c deleted file mode 100644 index 3f97641be08af203e9d91170c3b8b033416c7795..0000000000000000000000000000000000000000 --- a/modules/json_rpc/mempool/dap_chain_mempool_rpc.c +++ /dev/null @@ -1,149 +0,0 @@ -#include <stddef.h> -#include <stdio.h> -#include <string.h> -#include <stdio.h> -#include <assert.h> -#include <memory.h> - -#ifdef _WIN32 -#include <winsock2.h> -#include <windows.h> -#include <mswsock.h> -#include <ws2tcpip.h> -#include <io.h> -#include <time.h> -#include <pthread.h> -#endif - -#include "dap_common.h" -#include "dap_hash.h" -#include "dap_http_client.h" -#include "dap_http_simple.h" -#include "dap_enc_base58.h" -#include "dap_enc_http.h" -#include "http_status_code.h" -#include "dap_chain_common.h" -#include "dap_chain_node.h" -#include "dap_global_db.h" -#include "dap_enc.h" -#include <dap_enc_http.h> -#include <dap_enc_key.h> -#include <dap_enc_ks.h> -#include "dap_chain_mempool.h" - -#include "dap_common.h" -#include "dap_list.h" -#include "dap_chain.h" -#include "dap_chain_net.h" -#include "dap_chain_net_tx.h" -#include "dap_sign.h" -#include "dap_chain_datum_tx.h" -#include "dap_chain_datum_tx_items.h" -#include "dap_chain_net_srv.h" -#include "dap_chain_cs_blocks.h" - -#include "dap_chain_mempool_rpc.h" -#include "dap_json_rpc_chain_datum.h" -#include "dap_json_rpc_request_handler.h" -#include "dap_json_rpc_response_handler.h" -#include "json.h" - -#define LOG_TAG "dap_chain_mempool_rpc" - -int dap_chain_mempool_rpc_init(void) { - dap_json_rpc_registration_request_handler("mempool_list", dap_chain_mempool_rpc_handler_list); - dap_json_rpc_registration_request_handler("memtest", dap_chain_mempool_rpc_handler_test); - return 0; -} - -void dap_chain_mempool_rpc_handler_test(dap_json_rpc_params_t *a_params, - dap_json_rpc_response_t *a_response, const char *a_method) { - UNUSED(a_method); - char *l_tn = NULL; -// char *l_chain_str = NULL; - for (uint32_t i = 0; i < a_params->length; i++) { - dap_json_rpc_param_t *l_prm = a_params->params[i]; - if (i == 0) - l_tn = l_prm->value_param; - } - if (dap_strcmp(l_tn, "NULL") == 0) { - a_response->type = TYPE_RESPONSE_NULL; - } else if (dap_strcmp(l_tn, "STRING") == 0) { - a_response->type = TYPE_RESPONSE_STRING; - a_response->result_string = dap_strdup("This test string"); - } else if (dap_strcmp(l_tn, "INTEGER") == 0) { - a_response->type = TYPE_RESPONSE_INTEGER; - a_response->result_int = 4555745; - } else if (dap_strcmp(l_tn, "BOOLEAN") == 0) { - a_response->type = TYPE_RESPONSE_BOOLEAN; - a_response->result_boolean = true; - } else if (dap_strcmp(l_tn, "DOUBLE") == 0) { - a_response->type = TYPE_RESPONSE_DOUBLE; - a_response->result_double = 75.545; - } else if (dap_strcmp(l_tn, "JSON") == 0) { - a_response->type = TYPE_RESPONSE_JSON; - json_object *l_obj = json_object_new_object(); - json_object *l_int = json_object_new_uint64(45577445); - json_object *l_boolean = json_object_new_boolean((json_bool)1); - json_object *l_double = json_object_new_double(457.74514); - json_object *l_arr = json_object_new_array(); - for (int i = 1000; i < 1997; i++) { - json_object *l_cur = json_object_new_int(i); - json_object_array_add(l_arr, l_cur); - } - json_object_object_add(l_obj, "int", l_int); - json_object_object_add(l_obj, "boolean", l_boolean); - json_object_object_add(l_obj, "double", l_double); - json_object_object_add(l_obj, "array", l_arr); - a_response->result_json_object = json_object_get(l_obj); - json_object_put(l_obj); - } else { - //set ERR code - } -} - -void dap_chain_mempool_rpc_handler_list(dap_json_rpc_params_t *a_params, - dap_json_rpc_response_t *a_response, const char *a_method) { - char *l_net_str = NULL; - char *l_chain_str = NULL; - for (uint32_t i = 0; i < a_params->length; i++) { - dap_json_rpc_param_t *l_prm = a_params->params[i]; - if (i == 0) - l_net_str = l_prm->value_param; - if (i == 1) - l_chain_str = l_prm->value_param; - } - dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str); - dap_chain_t *l_chain = dap_chain_net_get_chain_by_name(l_net, l_chain_str); - a_response->type = TYPE_RESPONSE_STRING; - char * l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool_new(l_chain); - if(!l_gdb_group_mempool){ - a_response->result_string = "{\"datums\":[]}"; - return; - } - size_t l_objs_size = 0; - dap_global_db_obj_t *l_objs = dap_global_db_get_all_sync(l_gdb_group_mempool, &l_objs_size); - json_object *l_object = json_object_new_object(); - json_object *l_object_array = json_object_new_array(); - - for(size_t i = 0; i < l_objs_size; i++) { - dap_chain_datum_t *l_datum = (dap_chain_datum_t *)l_objs[i].value; - //dap_time_t l_ts_create = (dap_time_t) l_datum->header.ts_create; - if (!l_datum->header.data_size || (l_datum->header.data_size > l_objs[i].value_len)) { - log_it(L_ERROR, "Trash datum in GDB %s.%s, key: %s data_size:%u, value_len:%zu", - l_net->pub.name, l_chain->name, l_objs[i].key, l_datum->header.data_size, l_objs[i].value_len); - dap_global_db_del(l_gdb_group_mempool, l_objs[i].key, NULL, NULL); - continue; - } - - json_object *l_obj_datum = dap_chain_datum_to_json(l_datum); - json_object_array_add(l_object_array, l_obj_datum); - } - json_object_object_add(l_object, "datums", l_object_array); - a_response->type = TYPE_RESPONSE_JSON; - a_response->result_json_object = l_object; - - DAP_DELETE(l_gdb_group_mempool); -} - -#undef LOG_TAG diff --git a/modules/json_rpc/mempool/include/dap_chain_mempool_rpc.h b/modules/json_rpc/mempool/include/dap_chain_mempool_rpc.h deleted file mode 100644 index b9c0efa9bb0d768cb8e619e29a17003303967ce8..0000000000000000000000000000000000000000 --- a/modules/json_rpc/mempool/include/dap_chain_mempool_rpc.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Authors: - * Alexey V. Stratulat <alexey.stratulat@demlabs.net> - * Olzhas Zharasbaev <oljas.jarasbaev@demlabs.net> - * DeM Labs Inc. https://demlabs.net - * DeM Labs Open source community https://gitlab.demlabs.net/cellframe/cellframe-sdk - * Copyright (c) 2017-2023 - * All rights reserved. - - This file is part of DAP (Demlabs Application Protocol) the open source project - - DAP (Demlabs Application Protocol) is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - DAP is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. -*/ - -#pragma once - -#include "dap_json_rpc_errors.h" -#include "dap_json_rpc_response.h" -#include "dap_json_rpc_params.h" - - -int dap_chain_mempool_rpc_init(void); -void dap_chain_mempool_rpc_handler_list(dap_json_rpc_params_t *a_params, - dap_json_rpc_response_t *a_response, const char *a_method); -void dap_chain_mempool_rpc_handler_test(dap_json_rpc_params_t *a_params, - dap_json_rpc_response_t *a_response, const char *a_method); diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c index 503e1d728167342629fc8aa5cf8a66f6d728a3ad..b5628e56bb07cd750e59cc6884c24d3d7be365af 100644 --- a/modules/mempool/dap_chain_mempool.c +++ b/modules/mempool/dap_chain_mempool.c @@ -125,7 +125,7 @@ char *dap_chain_mempool_datum_add(const dap_chain_datum_t *a_datum, dap_chain_t } char *l_gdb_group = dap_chain_net_get_gdb_group_mempool_new(a_chain); - int l_res = dap_global_db_set(l_gdb_group, l_key_str, a_datum, dap_chain_datum_size(a_datum), false, NULL, NULL); + int l_res = dap_global_db_set_sync(l_gdb_group, l_key_str, a_datum, dap_chain_datum_size(a_datum), false);//, NULL, NULL); if (l_res == DAP_GLOBAL_DB_RC_SUCCESS) log_it(L_NOTICE, "Datum %s with hash %s was placed in mempool group %s", l_type_str, l_key_str, l_gdb_group); else @@ -383,7 +383,7 @@ char *dap_chain_mempool_tx_coll_fee_create(dap_chain_cs_blocks_t *a_blocks, dap_ // Check and apply sovereign tax for this key uint256_t l_value_tax = {}; - dap_chain_net_srv_stake_item_t *l_key_item = dap_chain_net_srv_stake_check_pkey_hash(&l_sign_pkey_hash); + dap_chain_net_srv_stake_item_t *l_key_item = dap_chain_net_srv_stake_check_pkey_hash(l_chain->net_id, &l_sign_pkey_hash); if (l_key_item && !IS_ZERO_256(l_key_item->sovereign_tax) && !dap_chain_addr_is_blank(&l_key_item->sovereign_addr)) { MULT_256_COIN(l_value_out, l_key_item->sovereign_tax, &l_value_tax); @@ -512,7 +512,7 @@ char *dap_chain_mempool_tx_reward_create(dap_chain_cs_blocks_t *a_blocks, dap_en } // Check and apply sovereign tax for this key uint256_t l_value_tax = {}; - dap_chain_net_srv_stake_item_t *l_key_item = dap_chain_net_srv_stake_check_pkey_hash(&l_sign_pkey_hash); + dap_chain_net_srv_stake_item_t *l_key_item = dap_chain_net_srv_stake_check_pkey_hash(l_chain->net_id, &l_sign_pkey_hash); if (l_key_item && !IS_ZERO_256(l_key_item->sovereign_tax) && !dap_chain_addr_is_blank(&l_key_item->sovereign_addr)) { MULT_256_COIN(l_value_out, l_key_item->sovereign_tax, &l_value_tax); @@ -584,7 +584,7 @@ int dap_chain_mempool_tx_create_massive( dap_chain_t * a_chain, dap_enc_key_t *a uint256_t l_value_need = {}; MULT_256_256(dap_chain_uint256_from(a_tx_num), l_single_val, &l_value_need); uint256_t l_value_transfer = {}; // how many coins to transfer - char *l_balance; dap_uint256_to_char(l_value_need, &l_balance); + const char *l_balance; dap_uint256_to_char(l_value_need, &l_balance); log_it(L_DEBUG, "Create %"DAP_UINT64_FORMAT_U" transactions, summary %s", a_tx_num, l_balance); dap_ledger_t *l_ledger = dap_chain_net_by_id(a_chain->net_id)->pub.ledger; dap_list_t *l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, a_token_ticker, @@ -627,7 +627,7 @@ int dap_chain_mempool_tx_create_massive( dap_chain_t * a_chain, dap_enc_key_t *a if (compare256(l_value_to_items, l_single_val) == -1) { char l_log_str[256] = { '\0' }; l_balance = dap_uint256_to_char(l_value_to_items, NULL); - dap_snprintf(l_log_str, sizeof(l_log_str), + snprintf(l_log_str, sizeof(l_log_str), "Not enough values on output to produce enough inputs: %s when need ", l_balance); strcat(l_log_str, dap_uint256_to_char(l_single_val, NULL)); log_it(L_ERROR, "%s", l_log_str); diff --git a/modules/mempool/include/dap_chain_mempool_rpc.h b/modules/mempool/include/dap_chain_mempool_rpc.h index 60388908103c0d002071f8d2c90126914214c82c..90aca98b3214a954c9a7fe237cab42bf6188c597 100644 --- a/modules/mempool/include/dap_chain_mempool_rpc.h +++ b/modules/mempool/include/dap_chain_mempool_rpc.h @@ -2,7 +2,9 @@ #include "dap_json_rpc.h" int dap_chain_mempool_rpc_init(void); + void dap_chain_mempool_rpc_handler_list(dap_json_rpc_params_t *a_params, dap_json_rpc_response_t *a_response, const char *a_method); void dap_chain_mempool_rpc_handler_test(dap_json_rpc_params_t *a_params, dap_json_rpc_response_t *a_response, const char *a_method); + diff --git a/modules/net/CMakeLists.txt b/modules/net/CMakeLists.txt index 4cc53c5c4e335ae4ddd37c241026abad795140a8..f07876b697a07630c1f1270df99d5d0929b8b24b 100644 --- a/modules/net/CMakeLists.txt +++ b/modules/net/CMakeLists.txt @@ -29,8 +29,8 @@ endif() add_library(${PROJECT_NAME} STATIC ${DAP_CHAIN_NET_SRCS} ${DAP_CHAIN_NET_HEADERS} ${IPUTILS_SRCS} ${IPUTILS_HEADERS}) target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_client dap_io dap_notify_srv dap_cli_server dap_chain dap_chain_wallet - dap_chain_net_srv dap_chain_mempool dap_global_db dap_chain_net_srv_xchange dap_chain_cs_none - dap_stream_ch_chain_net dap_chain_cs_esbocs dap_json_rpc dap_json_rpc_chain_common) + dap_chain_net_srv dap_chain_net_srv_voting dap_chain_mempool dap_global_db dap_chain_net_srv_xchange dap_chain_cs_none + dap_stream_ch_chain_net dap_chain_cs_esbocs dap_json_rpc ) if(LINUX) target_link_libraries(${PROJECT_NAME} resolv) endif() diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c index 1daae4728d93a6773aa040937f780a2972b43051..c65f1ccbff03e1901921b64ec018bd127cb83441 100644 --- a/modules/net/dap_chain_ledger.c +++ b/modules/net/dap_chain_ledger.c @@ -72,9 +72,18 @@ typedef struct dap_chain_ledger_votings_callbacks{ dap_chain_ledger_voting_callback_t voting_callback; dap_chain_ledger_voting_delete_callback_t voting_delete_callback; } dap_chain_ledger_votings_callbacks_t; +typedef struct dap_ledger_service_info { + dap_chain_net_srv_uid_t service_uid; // hash key + char tag_str[32]; // tag string name + dap_ledger_tag_check_callback_t callback; //callback for check if a tx for particular service + UT_hash_handle hh; +} dap_ledger_service_info_t; static dap_ledger_verificator_t *s_verificators; +static dap_ledger_service_info_t *s_services; + static pthread_rwlock_t s_verificators_rwlock; +static pthread_rwlock_t s_services_rwlock; static dap_chain_ledger_votings_callbacks_t s_voting_callbacks; @@ -217,6 +226,8 @@ typedef struct dap_ledger_tx_item { byte_t multichannel; dap_time_t ts_spent; byte_t pad[7]; + dap_chain_net_srv_uid_t tag; //tag (or service this tx is belong to) + dap_chain_tx_tag_action_type_t action; // TODO dynamically allocates the memory in order not to limit the number of outputs in transaction dap_chain_hash_fast_t tx_hash_spent_fast[MAX_OUT_ITEMS]; // spent outs list } DAP_ALIGN_PACKED cache_data; @@ -365,6 +376,157 @@ static size_t s_threshold_free_timer_tick = 900000; // 900000 ms = 15 minutes. struct json_object *wallet_info_json_collect(dap_ledger_t *a_ledger, dap_ledger_wallet_balance_t* a_bal); +//add a service declaration for tx tagging and more +static bool s_tag_check_block_reward(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_datum_tx_item_groups_t *a_items_grp, dap_chain_tx_tag_action_type_t *a_action) +{ + //reward tag + if (a_items_grp->items_in_reward) + { + if (a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REGULAR; + return true; + } + return false; +} + +dap_chain_tx_out_cond_t* dap_chain_ledger_get_tx_out_cond_linked_to_tx_in_cond(dap_ledger_t *a_ledger, dap_chain_tx_in_cond_t *a_in_cond) +{ + dap_hash_fast_t *l_tx_prev_hash = &a_in_cond->header.tx_prev_hash; + uint32_t l_tx_prev_out_idx = a_in_cond->header.tx_out_prev_idx; + dap_chain_datum_tx_t *l_tx_prev = dap_ledger_tx_find_by_hash (a_ledger,l_tx_prev_hash); + + if (!l_tx_prev) return NULL; + byte_t* l_item_res = dap_chain_datum_tx_item_get_nth(l_tx_prev, TX_ITEM_TYPE_OUT_ALL, l_tx_prev_out_idx); + dap_chain_tx_item_type_t l_type = *(uint8_t *)l_item_res; + + if (l_type != TX_ITEM_TYPE_OUT_COND) return NULL; + + + return (dap_chain_tx_out_cond_t*)l_item_res; +} + +static dap_chain_addr_t s_get_out_addr(byte_t *out_item) { + dap_chain_tx_item_type_t l_type = *(uint8_t *)out_item; + + switch (l_type) { + case TX_ITEM_TYPE_OUT: { + dap_chain_tx_out_t *l_tx_out = (dap_chain_tx_out_t *)out_item; + return l_tx_out->addr; + } break; + case TX_ITEM_TYPE_OUT_EXT: { // 256 + dap_chain_tx_out_ext_t *l_tx_out = (dap_chain_tx_out_ext_t *)out_item; + return l_tx_out->addr; + } break; + } + + dap_chain_addr_t l_tx_out_to={0}; + return l_tx_out_to; +} + +static bool s_tag_check_transfer(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_datum_tx_item_groups_t *a_items_grp, dap_chain_tx_tag_action_type_t *a_action) +{ + //crosschain transfer + //regular transfer + //comission transfer + + // fee transfer: in_cond item linked to out_cond_fee + if (a_items_grp->items_in_cond) + { + for (dap_list_t *it = a_items_grp->items_in_cond; it; it = it->next) { + dap_chain_tx_in_cond_t *l_tx_in = it->data; + dap_chain_tx_out_cond_t *l_tx_out_cond = dap_chain_ledger_get_tx_out_cond_linked_to_tx_in_cond(a_ledger, l_tx_in); + + if (l_tx_out_cond && l_tx_out_cond->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE) { + if (a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_TRANSFER_COMISSION; + return true; + } + } + } + + //crosschain transfer: outs destination net-id differs from current net-id + // to differ with wrong stakes -> no ems in required + + if (!a_items_grp->items_in_ems) + { + dap_chain_addr_t addr_to = {0}; + for (dap_list_t *it = a_items_grp->items_out_all; it; it = it->next) { + + dap_chain_addr_t l_tx_out_to = s_get_out_addr(it->data); + + //tag cross-chain _outputs_ transactions (recepient-tx is emission-based) + if (l_tx_out_to.net_id.uint64 != a_ledger->net->pub.id.uint64 && !dap_chain_addr_is_blank(&l_tx_out_to)) { + if (a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_TRANSFER_CROSSCHAIN; + return true; + } + } + } + + + //regular transfers + //have no other ins except regular in + //have no OUT_COND except fee + //have no vote + //no TSD! + + + //have any of those -> not regular transfer + if (a_items_grp->items_in_cond || + a_items_grp->items_in_ems || + a_items_grp->items_in_reward ) { + return false; + } + + //have any of those -> not regular transfer + if ( + a_items_grp->items_out_cond_srv_pay || + a_items_grp->items_out_cond_srv_stake_lock || + a_items_grp->items_out_cond_srv_stake_pos_delegate || + a_items_grp->items_out_cond_srv_xchange) + { + return false; + } + + //not voting or vote... + if (a_items_grp->items_vote || a_items_grp->items_voting || a_items_grp->items_tsd) + return false; + + //not tsd sects (staking!) + if(a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REGULAR; + return true; +} + +int dap_ledger_service_add(dap_chain_net_srv_uid_t a_uid, char *tag_str, dap_ledger_tag_check_callback_t a_callback) +{ + + dap_ledger_service_info_t *l_new_sinfo; + + int l_tmp = a_uid.raw_ui64; + + pthread_rwlock_rdlock(&s_services_rwlock); + HASH_FIND_INT(s_services, &l_tmp, l_new_sinfo); + pthread_rwlock_unlock(&s_services_rwlock); + if (l_new_sinfo) { + l_new_sinfo->callback = a_callback; + return 1; + } + + l_new_sinfo = DAP_NEW(dap_ledger_service_info_t); + if (!l_new_sinfo) { + log_it(L_CRITICAL, "Memory allocation error"); + return -1; + } + l_new_sinfo->service_uid = a_uid; + l_new_sinfo->callback = a_callback; + strcpy(l_new_sinfo->tag_str, tag_str); + + pthread_rwlock_wrlock(&s_services_rwlock); + HASH_ADD_INT(s_services, service_uid.raw_ui64, l_new_sinfo); + pthread_rwlock_unlock(&s_services_rwlock); + + log_it(L_NOTICE, "Successfully registered service tag %s with uid %02" DAP_UINT64_FORMAT_X, tag_str, a_uid.raw_ui64); + + return 0; +} + /** * @brief dap_ledger_init * current function version set s_debug_more parameter, if it define in config, and returns 0 @@ -373,7 +535,16 @@ struct json_object *wallet_info_json_collect(dap_ledger_t *a_ledger, dap_ledger_ int dap_ledger_init() { s_debug_more = dap_config_get_item_bool_default(g_config,"ledger","debug_more",false); + pthread_rwlock_init(&s_verificators_rwlock, NULL); + pthread_rwlock_init(&s_services_rwlock, NULL); + + //register native ledger services + dap_chain_net_srv_uid_t l_uid_transfer = { .uint64 = DAP_CHAIN_NET_SRV_TRANSFER_ID }; + dap_ledger_service_add(l_uid_transfer, "transfer", s_tag_check_transfer); + + dap_chain_net_srv_uid_t l_uid_breward = { .uint64 = DAP_CHAIN_NET_SRV_BLOCK_REWARD_ID }; + dap_ledger_service_add(l_uid_breward, "block_reward", s_tag_check_block_reward); return 0; } @@ -384,6 +555,7 @@ int dap_ledger_init() void dap_ledger_deinit() { pthread_rwlock_destroy(&s_verificators_rwlock); + pthread_rwlock_destroy(&s_services_rwlock); } /** @@ -462,7 +634,7 @@ struct json_object *wallet_info_json_collect(dap_ledger_t *a_ledger, dap_ledger_ } struct json_object *l_token = json_object_new_object(); json_object_object_add(l_token, "name", json_object_new_string(a_bal->token_ticker)); - char *l_balance_coins, *l_balance_datoshi = dap_uint256_to_char(a_bal->balance, &l_balance_coins); + const char *l_balance_coins, *l_balance_datoshi = dap_uint256_to_char(a_bal->balance, &l_balance_coins); json_object_object_add(l_token, "full_balance", json_object_new_string(l_balance_coins)); json_object_object_add(l_token, "datoshi", json_object_new_string(l_balance_datoshi)); json_object_object_add(l_network, "tokens", l_token); @@ -1051,7 +1223,7 @@ static bool s_ledger_token_supply_check_update(dap_ledger_t *a_ledger, dap_ledge else l_overflow = SUBTRACT_256_256(a_token_item->current_supply, a_value, &a_token_item->current_supply); assert(!l_overflow); - char *l_balance; dap_uint256_to_char(a_token_item->current_supply, &l_balance); + const char *l_balance; dap_uint256_to_char(a_token_item->current_supply, &l_balance); log_it(L_NOTICE, "New current supply %s for token %s", l_balance, a_token_item->ticker); s_ledger_token_cache_update(a_ledger, a_token_item); return true; @@ -1228,7 +1400,7 @@ int dap_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_toke } int l_res_token_tsd_parse = 0; - char *l_balance_dbg = NULL; + const char *l_balance_dbg = NULL; if (s_debug_more) dap_uint256_to_char(l_token->total_supply, &l_balance_dbg); @@ -1785,6 +1957,9 @@ static int s_tsd_sign_apply(dap_ledger_t *a_ledger, dap_ledger_token_item_t *a_t uint16_t l_tmp = 0; a_token_item->auth_signs_valid = _dap_tsd_get_scalar(l_new_signs_valid, &l_tmp); } + + if (l_added_pkeys) dap_list_free(l_added_pkeys); + if (l_remove_pkeys) dap_list_free(l_remove_pkeys); return 0; } @@ -1813,11 +1988,17 @@ json_object *dap_ledger_threshold_info(dap_ledger_t *a_ledger, size_t a_limit, s uint32_t l_counter = 0; pthread_rwlock_rdlock(&l_ledger_pvt->threshold_txs_rwlock); size_t l_arr_start = 0; - if (a_offset > 1) { - l_arr_start = a_limit * a_offset; + if (a_offset > 0) { + l_arr_start = a_offset; + json_object* json_obj_tx = json_object_new_object(); + json_object_object_add(json_obj_tx, "offset", json_object_new_int(l_arr_start)); + json_object_array_add(json_arr_out, json_obj_tx); } size_t l_arr_end = HASH_COUNT(l_ledger_pvt->threshold_txs); if (a_limit) { + json_object* json_obj_tx = json_object_new_object(); + json_object_object_add(json_obj_tx, "limit", json_object_new_int(a_limit)); + json_object_array_add(json_arr_out, json_obj_tx); l_arr_end = l_arr_start + a_limit; if (l_arr_end > HASH_COUNT(l_ledger_pvt->threshold_txs)) { l_arr_end = HASH_COUNT(l_ledger_pvt->threshold_txs); @@ -1825,7 +2006,7 @@ json_object *dap_ledger_threshold_info(dap_ledger_t *a_ledger, size_t a_limit, s } size_t i_tmp = 0; HASH_ITER(hh, l_ledger_pvt->threshold_txs, l_tx_item, l_tx_tmp){ - if (i_tmp < l_arr_start || i_tmp > l_arr_end) { + if (i_tmp < l_arr_start || i_tmp >= l_arr_end) { i_tmp++; continue; } @@ -1885,11 +2066,17 @@ json_object *dap_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_chain_ha return NULL; } size_t l_arr_start = 0; - if (a_offset > 1) { - l_arr_start = a_limit * a_offset; + if (a_offset > 0) { + l_arr_start = a_offset; + json_object* json_obj_tx = json_object_new_object(); + json_object_object_add(json_obj_tx, "offset", json_object_new_int(l_arr_start)); + json_object_array_add(json_arr_out, json_obj_tx); } size_t l_arr_end = HASH_COUNT(l_ledger_pvt->threshold_txs); if (a_limit) { + json_object* json_obj_tx = json_object_new_object(); + json_object_object_add(json_obj_tx, "limit", json_object_new_int(l_arr_start)); + json_object_array_add(json_arr_out, json_obj_tx); l_arr_end = l_arr_start + a_limit; if (l_arr_end > HASH_COUNT(l_ledger_pvt->threshold_txs)) { l_arr_end = HASH_COUNT(l_ledger_pvt->threshold_txs); @@ -1899,7 +2086,7 @@ json_object *dap_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_chain_ha pthread_rwlock_rdlock(&l_ledger_pvt->threshold_txs_rwlock); HASH_ITER(hh, l_ledger_pvt->threshold_txs, l_tx_item, l_tx_tmp){ if (!memcmp(l_threshold_hash, &l_tx_item->tx_hash_fast, sizeof(dap_chain_hash_fast_t))){ - if (i_tmp < l_arr_start || i_tmp > l_arr_end) { + if (i_tmp < l_arr_start || i_tmp >= l_arr_end) { i_tmp++; continue; } @@ -1918,7 +2105,7 @@ json_object *dap_ledger_threshold_hash_info(dap_ledger_t *a_ledger, dap_chain_ha dap_ledger_token_emission_item_t *l_emission_item, *l_emission_tmp; HASH_ITER(hh, l_ledger_pvt->threshold_emissions, l_emission_item, l_emission_tmp){ if (!memcmp(&l_emission_item->datum_token_emission_hash,l_threshold_hash, sizeof(dap_chain_hash_fast_t))){ - if (i_tmp < l_arr_start || i_tmp > l_arr_end) { + if (i_tmp < l_arr_start || i_tmp >= l_arr_end) { i_tmp++; continue; } @@ -1946,10 +2133,16 @@ json_object *dap_ledger_balance_info(dap_ledger_t *a_ledger, size_t a_limit, siz dap_ledger_wallet_balance_t *l_balance_item, *l_balance_tmp; size_t l_arr_start = 0; if (a_offset > 1) { - l_arr_start = a_limit * a_offset; + l_arr_start = a_offset; + json_object* json_obj_tx = json_object_new_object(); + json_object_object_add(json_obj_tx, "offset", json_object_new_int(l_arr_start)); + json_object_array_add(json_arr_out, json_obj_tx); } size_t l_arr_end = HASH_COUNT(l_ledger_pvt->balance_accounts); if (a_limit) { + json_object* json_obj_tx = json_object_new_object(); + json_object_object_add(json_obj_tx, "limit", json_object_new_int(l_arr_start)); + json_object_array_add(json_arr_out, json_obj_tx); l_arr_end = l_arr_start + a_limit; if (l_arr_end > HASH_COUNT(l_ledger_pvt->balance_accounts)) { l_arr_end = HASH_COUNT(l_ledger_pvt->balance_accounts); @@ -1957,7 +2150,7 @@ json_object *dap_ledger_balance_info(dap_ledger_t *a_ledger, size_t a_limit, siz } size_t i_tmp = 0; HASH_ITER(hh, l_ledger_pvt->balance_accounts, l_balance_item, l_balance_tmp) { - if (i_tmp < l_arr_start || i_tmp > l_arr_end) { + if (i_tmp < l_arr_start || i_tmp >= l_arr_end) { i_tmp++; continue; } @@ -2058,11 +2251,17 @@ json_object *dap_ledger_token_info(dap_ledger_t *a_ledger, size_t a_limit, size_ dap_ledger_token_item_t *l_token_item, *l_tmp_item; pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); size_t l_arr_start = 0; - if (a_offset > 1) { - l_arr_start = a_limit * a_offset; + if (a_offset > 0) { + l_arr_start = a_offset; + json_object* json_obj_tx = json_object_new_object(); + json_object_object_add(json_obj_tx, "offset", json_object_new_int(l_arr_start)); + json_object_array_add(json_arr_out, json_obj_tx); } size_t l_arr_end = HASH_COUNT(PVT(a_ledger)->tokens); if (a_limit) { + json_object* json_obj_tx = json_object_new_object(); + json_object_object_add(json_obj_tx, "limit", json_object_new_int(a_limit)); + json_object_array_add(json_arr_out, json_obj_tx); l_arr_end = l_arr_start + a_limit; if (l_arr_end > HASH_COUNT(PVT(a_ledger)->tokens)) { l_arr_end = HASH_COUNT(PVT(a_ledger)->tokens); @@ -2070,7 +2269,7 @@ json_object *dap_ledger_token_info(dap_ledger_t *a_ledger, size_t a_limit, size_ } size_t i_tmp = 0; HASH_ITER(hh, PVT(a_ledger)->tokens, l_token_item, l_tmp_item) { - if (i_tmp < l_arr_start || i_tmp > l_arr_end) { + if (i_tmp < l_arr_start || i_tmp >= l_arr_end) { i_tmp++; continue; } @@ -2888,7 +3087,7 @@ int dap_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emissi // Add it to cache s_ledger_emission_cache_update(a_ledger, l_token_emission_item); if (s_debug_more) { - char *l_balance; dap_uint256_to_char(l_token_emission_item->datum_token_emission->hdr.value, &l_balance); + const char *l_balance; dap_uint256_to_char(l_token_emission_item->datum_token_emission->hdr.value, &l_balance); log_it(L_NOTICE, "Added token emission datum to emissions cache: type=%s value=%s token=%s to_addr=%s ", c_dap_chain_datum_token_emission_type_str[l_token_emission_item->datum_token_emission->hdr.type], l_balance, c_token_ticker, @@ -2908,7 +3107,7 @@ int dap_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emissi pthread_rwlock_unlock(&l_ledger_pvt->threshold_emissions_rwlock); l_ret = -5; if (s_debug_more) { - char *l_balance; dap_uint256_to_char(l_token_emission_item->datum_token_emission->hdr.value, &l_balance); + const char *l_balance; dap_uint256_to_char(l_token_emission_item->datum_token_emission->hdr.value, &l_balance); log_it(L_NOTICE, "Added token emission datum to emissions threshold: type=%s value=%s token=%s to_addr=%s ", c_dap_chain_datum_token_emission_type_str[l_token_emission_item->datum_token_emission->hdr.type], l_balance, c_token_ticker, @@ -3197,7 +3396,7 @@ void dap_ledger_addr_get_token_ticker_all(dap_ledger_t *a_ledger, dap_chain_addr return; } l_count = 0; - char *l_addr = dap_chain_addr_to_str(a_addr); + const char *l_addr = dap_chain_addr_to_str(a_addr); pthread_rwlock_rdlock(&PVT(a_ledger)->balance_accounts_rwlock); HASH_ITER(hh, PVT(a_ledger)->balance_accounts, wallet_balance, tmp) { char **l_keys = dap_strsplit(wallet_balance->key, " ", -1); @@ -3215,7 +3414,11 @@ void dap_ledger_addr_get_token_ticker_all(dap_ledger_t *a_ledger, dap_chain_addr } } - +const char *dap_ledger_get_description_by_ticker(dap_ledger_t *a_ledger, const char *a_token_ticker){ + if (!a_ledger || !a_token_ticker) + return NULL; + return s_ledger_find_token(a_ledger, a_token_ticker)->description_token; +} /** * Get transaction in the cache by hash @@ -3491,14 +3694,149 @@ inline static bool s_ledger_check_token_ticker(const char *a_ticker) return false; } +/* +services we know now +0x01 - VPN +0x02 - xchange +0x03, 0x13 - pos_delegate +0x04 bridge +0x.05 - custom datum +0x06 voting +0x12 - stake_lock +*/ + +const char *dap_ledger_tx_action_str(dap_chain_tx_tag_action_type_t a_tag) +{ + + if (a_tag == DAP_CHAIN_TX_TAG_ACTION_UNKNOWN) return "unknown"; + if (a_tag == DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REGULAR) return "regular"; + if (a_tag == DAP_CHAIN_TX_TAG_ACTION_TRANSFER_COMISSION) return "comission"; + if (a_tag == DAP_CHAIN_TX_TAG_ACTION_TRANSFER_CROSSCHAIN) return "crosschain"; + if (a_tag == DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REWARD) return "reward"; + if (a_tag == DAP_CHAIN_TX_TAG_ACTION_OPEN) return "open"; + if (a_tag == DAP_CHAIN_TX_TAG_ACTION_USE) return "use"; + if (a_tag == DAP_CHAIN_TX_TAG_ACTION_EXTEND) return "extend"; + if (a_tag == DAP_CHAIN_TX_TAG_ACTION_CLOSE) return "close"; + if (a_tag == DAP_CHAIN_TX_TAG_ACTION_CHANGE) return "change"; + + return "WTFSUBTAG"; + +} + +dap_chain_tx_tag_action_type_t dap_ledger_tx_action_str_to_action_t(const char *a_str) +{ + if (!a_str) + return DAP_CHAIN_TX_TAG_ACTION_UNKNOWN; + + if (strcmp("unknown", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_UNKNOWN; + if (strcmp("regular", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REGULAR; + if (strcmp("comission", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_TRANSFER_COMISSION; + if (strcmp("crosschain", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_TRANSFER_CROSSCHAIN; + if (strcmp("reward", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REWARD; + if (strcmp("open", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_OPEN; + if (strcmp("use", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_USE; + if (strcmp("extend", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_EXTEND; + if (strcmp("close", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_CLOSE; + if (strcmp("change", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_CHANGE; + + return DAP_CHAIN_TX_TAG_ACTION_UNKNOWN; +} + +bool dap_ledger_tx_service_info(dap_ledger_t *a_ledger, dap_hash_fast_t *a_tx_hash, + dap_chain_net_srv_uid_t *a_uid, char **a_service_name, dap_chain_tx_tag_action_type_t *a_action) +{ + //find tx + dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); + dap_chain_datum_tx_t *l_tx_ret = NULL; + dap_ledger_tx_item_t *l_tx_item; + pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock); + HASH_FIND(hh, l_ledger_pvt->ledger_items, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_tx_item); + pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock); + + + if(l_tx_item) { + dap_ledger_service_info_t *l_sinfo; + pthread_rwlock_rdlock(&s_services_rwlock); + HASH_FIND_INT(s_services, &l_tx_item->cache_data.tag, l_sinfo); + pthread_rwlock_unlock(&s_services_rwlock); + if (l_sinfo) + { + if(a_uid) *a_uid = l_sinfo->service_uid; + if (a_service_name) *a_service_name = l_sinfo->tag_str; + if (a_action) *a_action = l_tx_item->cache_data.action; + return true; + } + } + + if (a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_UNKNOWN; + return false; +} + + +bool dap_ledger_deduct_tx_tag(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_net_srv_uid_t *a_tag, dap_chain_tx_tag_action_type_t *a_action) +{ + dap_ledger_service_info_t *l_sinfo_current, *l_sinfo_tmp; + + + dap_chain_datum_tx_item_groups_t l_items_groups = {0}; + dap_chain_datum_tx_group_items(a_tx, &l_items_groups); + + bool l_res = false; + int l_deductions_ok = 0; + + pthread_rwlock_rdlock(&s_services_rwlock); + HASH_ITER(hh, s_services , l_sinfo_current, l_sinfo_tmp) { + dap_chain_tx_tag_action_type_t action = DAP_CHAIN_TX_TAG_ACTION_UNKNOWN; + if (l_sinfo_current->callback && l_sinfo_current->callback(a_ledger, a_tx, &l_items_groups, &action)){ + if (a_tag) *a_tag = l_sinfo_current->service_uid; + if (a_action) *a_action = action; + l_res = true; + l_deductions_ok ++; + } + } + pthread_rwlock_unlock(&s_services_rwlock); + + if (l_deductions_ok > 1) + { + char l_tx_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; + dap_chain_hash_fast_t * l_tx_hash = dap_chain_node_datum_tx_calc_hash(a_tx); + dap_chain_hash_fast_to_str(l_tx_hash, l_tx_hash_str, sizeof(l_tx_hash_str)); + + + log_it(L_WARNING, "Transaction %s identyfied by multiple services (%d):", l_tx_hash_str, l_deductions_ok); + + pthread_rwlock_rdlock(&s_services_rwlock); + HASH_ITER(hh, s_services , l_sinfo_current, l_sinfo_tmp) { + dap_chain_tx_tag_action_type_t action = DAP_CHAIN_TX_TAG_ACTION_UNKNOWN; + if (l_sinfo_current->callback && l_sinfo_current->callback(a_ledger, a_tx, &l_items_groups,&action)) { + log_it(L_WARNING, "%s %s", l_sinfo_current->tag_str, dap_ledger_tx_action_str(action)); + } + } + + pthread_rwlock_unlock(&s_services_rwlock); + } + + dap_chain_datum_tx_group_items_free(&l_items_groups); + + return l_res; +} + /** * Checking a new transaction before adding to the cache * * return 0 OK, otherwise error */ // Checking a new transaction before adding to the cache -int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, - bool a_from_threshold, dap_list_t **a_list_bound_items, dap_list_t **a_list_tx_out, char **a_main_ticker, bool a_check_for_removing) +int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, + dap_chain_datum_tx_t *a_tx, + dap_hash_fast_t *a_tx_hash, + bool a_from_threshold, + dap_list_t **a_list_bound_items, + dap_list_t **a_list_tx_out, + char **a_main_ticker, + dap_chain_net_srv_uid_t *a_tag, + dap_chain_tx_tag_action_type_t *a_action, + bool a_check_for_removing) { if (!a_tx) { log_it(L_DEBUG, "NULL transaction, check broken"); @@ -3514,6 +3852,8 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx char l_tx_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; dap_chain_hash_fast_to_str(a_tx_hash, l_tx_hash_str, sizeof(l_tx_hash_str)); log_it(L_WARNING, "Transaction %s already present in the cache", l_tx_hash_str); + if (a_tag) *a_tag = l_ledger_item->cache_data.tag; + if (a_action) *a_action = l_ledger_item->cache_data.action; } return DAP_LEDGER_TX_ALREADY_CACHED; } @@ -3561,6 +3901,8 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx dap_pkey_t *l_tx_first_sign_pkey = NULL; bool l_girdled_ems_used = false; uint256_t l_taxed_value = {}; + + if(a_tag) dap_ledger_deduct_tx_tag(a_ledger, a_tx, a_tag, a_action); // find all previous transactions for (dap_list_t *it = l_list_in; it; it = it->next) { @@ -3845,7 +4187,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx l_tx_prev_hash = &l_tx_in->header.tx_prev_hash; if (dap_hash_fast_is_blank(l_tx_prev_hash)) { DAP_DELETE(l_bound_item); - l_list_bound_items = dap_list_remove_link(l_list_bound_items, dap_list_last(l_list_bound_items)); + l_list_bound_items = dap_list_delete_link(l_list_bound_items, dap_list_last(l_list_bound_items)); continue; // old base tx compliance } l_tx_prev_out_idx = l_tx_in->header.tx_out_prev_idx; @@ -3978,7 +4320,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx if (!dap_chain_addr_is_blank(l_addr_from) && s_ledger_permissions_check(l_token_item, DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD, l_addr_from, sizeof(*l_addr_from)) != 0 ){ - char *l_tmp_tx_in_from = dap_chain_addr_to_str(l_addr_from); + const char *l_tmp_tx_in_from = dap_chain_addr_to_str(l_addr_from); debug_if(s_debug_more, L_WARNING, "No permission for addr %s", l_tmp_tx_in_from ? l_tmp_tx_in_from : "(null)"); l_err_num = DAP_LEDGER_PERMISSION_CHECK_FAILED; break; @@ -3988,7 +4330,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx (l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_UNFROZEN ) ){ // in black list if (s_ledger_permissions_check(l_token_item, DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_ADD, l_addr_from, sizeof(*l_addr_from)) == 0 ){ - char *l_tmp_tx_in_from = dap_chain_addr_to_str(l_addr_from); + const char *l_tmp_tx_in_from = dap_chain_addr_to_str(l_addr_from); debug_if(s_debug_more, L_WARNING, "No permission for addr %s", l_tmp_tx_in_from ? l_tmp_tx_in_from : "(null)"); l_err_num = DAP_LEDGER_PERMISSION_CHECK_FAILED; break; @@ -4130,7 +4472,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx HASH_ADD_STR(l_values_from_cur_tx, token_ticker, l_value_cur); } - dap_chain_net_srv_stake_item_t *l_key_item = dap_chain_net_srv_stake_check_pkey_hash(&l_tx_first_sign_pkey_hash); + dap_chain_net_srv_stake_item_t *l_key_item = dap_chain_net_srv_stake_check_pkey_hash(a_ledger->net->pub.id, &l_tx_first_sign_pkey_hash); bool l_tax_check = l_key_item && !dap_chain_addr_is_blank(&l_key_item->sovereign_addr) && !IS_ZERO_256(l_key_item->sovereign_tax); // find 'out' items @@ -4236,7 +4578,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx (l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_FROZEN) ){ // check if we're in white list if(!dap_chain_addr_is_blank(&l_tx_out_to) && s_ledger_permissions_check(l_token_item, DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD,&l_tx_out_to , sizeof (l_tx_out_to)) != 0 ){ - char * l_tmp_tx_out_to = dap_chain_addr_to_str(&l_tx_out_to); + const char *l_tmp_tx_out_to = dap_chain_addr_to_str(&l_tx_out_to); debug_if(s_debug_more, L_WARNING, "No permission for addr %s", l_tmp_tx_out_to?l_tmp_tx_out_to:"(null)"); l_err_num = -20; break; @@ -4247,7 +4589,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx ){ // If all is allowed - check if we're in black list if(s_ledger_permissions_check(l_token_item, DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_ADD ,&l_tx_out_to, sizeof (l_tx_out_to)) == 0 ){ - char * l_tmp_tx_out_to = dap_chain_addr_to_str(&l_tx_out_to); + const char *l_tmp_tx_out_to = dap_chain_addr_to_str(&l_tx_out_to); debug_if(s_debug_more, L_WARNING, "No permission for addr %s", l_tmp_tx_out_to?l_tmp_tx_out_to:"(null)"); l_err_num = -22; break; @@ -4387,7 +4729,7 @@ int dap_ledger_tx_add_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, } int l_ret_check = dap_ledger_tx_cache_check(a_ledger, a_tx, a_datum_hash, - false, NULL, NULL, NULL, false); + false, NULL, NULL, NULL, NULL, NULL, false); if(s_debug_more) { char l_tx_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; dap_chain_hash_fast_to_str(a_datum_hash, l_tx_hash_str, sizeof(l_tx_hash_str)); @@ -4474,9 +4816,12 @@ int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ha int l_ret_check; l_item_tmp = NULL; + dap_chain_net_srv_uid_t l_tag = { .uint64 = 0 }; + dap_chain_tx_tag_action_type_t l_action = DAP_CHAIN_TX_TAG_ACTION_UNKNOWN; + if( (l_ret_check = dap_ledger_tx_cache_check(a_ledger, a_tx, a_tx_hash, a_from_threshold, &l_list_bound_items, &l_list_tx_out, - &l_main_token_ticker, false))) { + &l_main_token_ticker, &l_tag, &l_action, false))) { if (l_ret_check == DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS || l_ret_check == DAP_CHAIN_CS_VERIFY_CODE_TX_NO_EMISSION) { if (!l_from_threshold) { @@ -4515,6 +4860,10 @@ int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ha debug_if(s_debug_more, L_WARNING, "dap_ledger_tx_add() tx %s not passed the check: %s ", l_tx_hash_str, dap_ledger_tx_check_err_str(l_ret_check)); } + + if ( l_list_bound_items ) + dap_list_free_full(l_list_bound_items, NULL); + return l_ret_check; } debug_if(s_debug_more, L_DEBUG, "dap_ledger_tx_add() check passed for tx %s", l_tx_hash_str); @@ -4591,7 +4940,7 @@ int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ha case TX_ITEM_TYPE_IN: { dap_ledger_wallet_balance_t *wallet_balance = NULL; l_cur_token_ticker = l_bound_item->in.token_ticker; - char *l_addr_str = dap_chain_addr_to_str(&l_bound_item->in.addr_from); + const char *l_addr_str = dap_chain_addr_to_str(&l_bound_item->in.addr_from); char *l_wallet_balance_key = dap_strjoin(" ", l_addr_str, l_cur_token_ticker, (char*)NULL); pthread_rwlock_rdlock(&PVT(a_ledger)->balance_accounts_rwlock); HASH_FIND_STR(PVT(a_ledger)->balance_accounts, l_wallet_balance_key, wallet_balance); @@ -4606,6 +4955,7 @@ int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ha if(s_debug_more) log_it(L_ERROR,"!!! Attempt to SPEND from some non-existent balance !!!: %s %s", l_addr_str, l_cur_token_ticker); } + DAP_DELETE(l_wallet_balance_key); } break; @@ -4704,7 +5054,7 @@ int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ha else if (l_addr->net_id.uint64 != a_ledger->net->pub.id.uint64 && !dap_chain_addr_is_blank(l_addr)) l_cross_network = true; - char *l_addr_str = dap_chain_addr_to_str(l_addr); + const char *l_addr_str = dap_chain_addr_to_str(l_addr); dap_ledger_wallet_balance_t *wallet_balance = NULL; char *l_wallet_balance_key = dap_strjoin(" ", l_addr_str, l_cur_token_ticker, (char*)NULL); debug_if(s_debug_more, L_DEBUG, "GOT %s to addr: %s", @@ -4763,6 +5113,8 @@ int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ha int l_outs_count = 0; dap_list_t *l_list_tmp = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_OUT_ALL, &l_outs_count); l_tx_item->cache_data.n_outs = l_outs_count; + l_tx_item->cache_data.tag = l_tag; + l_tx_item->cache_data.action = l_action; // TODO: dump the UTXO in debug mode if need if(l_list_tmp) @@ -5136,7 +5488,7 @@ int dap_ledger_tx_load(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_c { if (dap_chain_net_get_load_mode(a_ledger->net)) { if (PVT(a_ledger)->cache_tx_check_callback) - PVT(a_ledger)->cache_tx_check_callback(a_tx_hash); + PVT(a_ledger)->cache_tx_check_callback(a_ledger, a_tx_hash); dap_ledger_tx_item_t *l_tx_item; unsigned l_hash_value; HASH_VALUE(a_tx_hash, sizeof(dap_chain_hash_fast_t), l_hash_value); @@ -5360,7 +5712,7 @@ uint256_t dap_ledger_calc_balance(dap_ledger_t *a_ledger, const dap_chain_addr_t uint256_t l_ret = uint256_0; dap_ledger_wallet_balance_t *l_balance_item = NULL;// ,* l_balance_item_tmp = NULL; - char *l_addr = dap_chain_addr_to_str(a_addr); + const char *l_addr = dap_chain_addr_to_str(a_addr); char *l_wallet_balance_key = dap_strjoin(" ", l_addr, a_token_ticker, (char*)NULL); pthread_rwlock_rdlock(&PVT(a_ledger)->balance_accounts_rwlock); HASH_FIND_STR(PVT(a_ledger)->balance_accounts, l_wallet_balance_key, l_balance_item); @@ -6234,14 +6586,14 @@ void dap_ledger_set_cache_tx_check_callback(dap_ledger_t *a_ledger, dap_ledger_c PVT(a_ledger)->cache_tx_check_callback = a_callback; } -const char *dap_ledger_tx_get_main_ticker(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, int *a_ledger_rc) +const char *dap_ledger_tx_calculate_main_ticker(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, int *a_ledger_rc) { - const char *l_main_ticker = NULL; - dap_chain_hash_fast_t * l_tx_hash = dap_chain_node_datum_tx_calc_hash(a_tx); - int l_rc = dap_ledger_tx_cache_check(a_ledger, a_tx, l_tx_hash, false, NULL, NULL, (char **)&l_main_ticker, false); - + char *l_main_ticker = NULL; + dap_chain_hash_fast_t *l_tx_hash = dap_chain_node_datum_tx_calc_hash(a_tx); + int l_rc = dap_ledger_tx_cache_check(a_ledger, a_tx, l_tx_hash, false, NULL, NULL, &l_main_ticker, NULL, NULL, false); if (l_rc == DAP_LEDGER_TX_ALREADY_CACHED) - l_main_ticker = dap_ledger_tx_get_token_ticker_by_hash(a_ledger, l_tx_hash); + l_main_ticker = (char *)dap_ledger_tx_get_token_ticker_by_hash(a_ledger, l_tx_hash); + DAP_DEL_Z(l_tx_hash); if (a_ledger_rc) *a_ledger_rc = l_rc; diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c index a2d37ba66ecb3f2e73a5337932441c4e05d84ef6..fbbf4809d3f5d66d702aced1689d77bbcb945ec2 100644 --- a/modules/net/dap_chain_net.c +++ b/modules/net/dap_chain_net.c @@ -71,14 +71,7 @@ #include "dap_config.h" #include "dap_hash.h" #include "dap_cert.h" -#include "dap_cert_file.h" #include "dap_chain_datum_tx.h" -#include "dap_chain_datum_tx_in_cond.h" -#include "dap_chain_datum_tx_items.h" -#include "dap_chain_datum_tx_out.h" -#include "dap_chain_datum_tx_out_cond.h" -#include "dap_timerfd.h" -#include "dap_stream_worker.h" #include "dap_worker.h" #include "dap_proc_thread.h" #include "dap_enc_http.h" @@ -86,21 +79,16 @@ #include "dap_chain_cell.h" #include "dap_chain_datum_decree.h" #include "dap_chain_datum_anchor.h" -#include "dap_chain_tx.h" #include "dap_chain_net.h" #include "dap_chain_net_node_list.h" #include "dap_chain_net_tx.h" #include "dap_chain_net_anchor.h" #include "dap_chain_net_decree.h" -#include "dap_chain_net_srv.h" #include "dap_chain_net_balancer.h" #include "dap_chain_node_client.h" -#include "dap_chain_node_cli.h" #include "dap_chain_node_cli_cmd.h" #include "dap_notify_srv.h" #include "dap_chain_ledger.h" -#include "dap_chain_cs_none.h" -#include "dap_client_http.h" #include "dap_global_db.h" #include "dap_stream_ch_chain_net_pkt.h" #include "dap_stream_ch_chain_net.h" @@ -108,19 +96,17 @@ #include "dap_stream_ch.h" #include "dap_stream.h" #include "dap_stream_ch_pkt.h" -#include "dap_chain_node_dns_client.h" -#include "dap_module.h" #include "rand/dap_rand.h" -#include "json.h" #include "json_object.h" #include "dap_chain_net_srv_stake_pos_delegate.h" #include "dap_chain_net_srv_xchange.h" #include "dap_chain_cs_esbocs.h" -#include "dap_chain_net_voting.h" +#include "dap_chain_net_srv_voting.h" #include "dap_global_db_cluster.h" #include "dap_link_manager.h" #include "dap_stream_cluster.h" #include "dap_http_ban_list_client.h" +#include "dap_net.h" #include <stdio.h> #include <sys/types.h> @@ -211,6 +197,9 @@ typedef struct dap_chain_net_item{ #define PVT_S(a) ((dap_chain_net_pvt_t *)a.pvt) static dap_chain_net_item_t *s_net_items = NULL, *s_net_ids = NULL; +static pthread_mutex_t s_net_cond_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t s_net_cond = PTHREAD_COND_INITIALIZER; +static uint16_t s_net_loading_count = 0; static const char *c_net_states[] = { [NET_STATE_OFFLINE] = "NET_STATE_OFFLINE", @@ -247,7 +236,7 @@ static void s_net_states_notify(dap_chain_net_t * l_net); static void s_nodelist_change_notify(dap_store_obj_t *a_obj, void *a_arg); //static void s_net_proc_kill( dap_chain_net_t * a_net ); static int s_net_init(const char * a_net_name, uint16_t a_acl_idx); -static int s_net_load(dap_chain_net_t *a_net); +static bool s_net_load(void *a_arg); static int s_net_try_online(dap_chain_net_t *a_net); static int s_cli_net(int argc, char ** argv, void **a_str_reply); static uint8_t *s_net_set_acl(dap_chain_hash_fast_t *a_pkey_hash); @@ -265,7 +254,7 @@ int dap_chain_net_init() dap_chain_ch_init(); dap_stream_ch_chain_net_init(); dap_chain_node_client_init(); - dap_chain_net_voting_init(); + dap_chain_net_srv_voting_init(); dap_http_ban_list_client_init(); dap_link_manager_init(&s_link_manager_callbacks); dap_chain_node_init(); @@ -307,7 +296,7 @@ int dap_chain_net_init() continue; // don't search in directories char l_full_path[MAX_PATH + 1] = {0}; - dap_snprintf(l_full_path, sizeof(l_full_path), "%s/%s", l_net_dir_str, l_dir_entry->d_name); + snprintf(l_full_path, sizeof(l_full_path), "%s/%s", l_net_dir_str, l_dir_entry->d_name); if(dap_dir_test(l_full_path)) { continue; } @@ -708,10 +697,6 @@ static dap_chain_net_t *s_net_new(dap_chain_net_id_t *a_id, const char *a_name, DAP_NEW_Z_SIZE_RET_VAL(PVT(l_ret)->node_info, dap_chain_node_info_t, sizeof(dap_chain_node_info_t) + DAP_HOSTADDR_STRLEN + 1, NULL, l_ret); // func work l_ret->pub.id.uint64 = a_id->uint64; - pthread_mutexattr_t l_mutex_attr; - pthread_mutexattr_init(&l_mutex_attr); - pthread_mutexattr_settype(&l_mutex_attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutexattr_destroy(&l_mutex_attr); if (strcmp (a_node_role, "root_master")==0){ PVT(l_ret)->node_role.enums = NODE_ROLE_ROOT_MASTER; @@ -747,17 +732,19 @@ static dap_chain_net_t *s_net_new(dap_chain_net_id_t *a_id, const char *a_name, */ void dap_chain_net_load_all() { - int l_ret = 0; - if(!HASH_COUNT(s_net_items)){ + pthread_mutex_lock(&s_net_cond_lock); + s_net_loading_count = HASH_COUNT(s_net_items); + if (!s_net_loading_count) { log_it(L_ERROR, "Can't find any nets"); + pthread_mutex_unlock(&s_net_cond_lock); return; } dap_chain_net_item_t *l_net_items_current = NULL, *l_net_items_tmp = NULL; - HASH_ITER(hh, s_net_items, l_net_items_current, l_net_items_tmp) { - if( (l_ret = s_net_load(l_net_items_current->chain_net)) ) { - log_it(L_ERROR, "Loading chains of net %s finished with (%d) error code.", l_net_items_current->name, l_ret); - } - } + HASH_ITER(hh, s_net_items, l_net_items_current, l_net_items_tmp) + dap_proc_thread_callback_add(NULL, s_net_load, l_net_items_current->chain_net); + while (s_net_loading_count) + pthread_cond_wait(&s_net_cond, &s_net_cond_lock); + pthread_mutex_unlock(&s_net_cond_lock); } dap_string_t* dap_cli_list_net() @@ -855,22 +842,6 @@ void s_set_reply_text_node_status(void **a_str_reply, dap_chain_net_t * a_net){ DAP_DELETE(l_sync_current_link_text_block); DAP_DELETE(l_node_address_text_block); } - -/** - * @brief get type of chain - * - * @param l_chain - * @return char* - */ -const char* dap_chain_net_get_type(dap_chain_t *l_chain) -{ - if (!l_chain){ - log_it(L_DEBUG, "dap_get_chain_type. Chain object is 0"); - return NULL; - } - return (const char*)DAP_CHAIN_PVT(l_chain)->cs_name; -} - /** * @brief reload ledger * command cellframe-node-cli net -net <network_name> ledger reload @@ -878,7 +849,7 @@ const char* dap_chain_net_get_type(dap_chain_t *l_chain) * @return true * @return false */ -static void s_chain_net_ledger_cache_reload(dap_chain_net_t *l_net) +void dap_chain_net_purge(dap_chain_net_t *l_net) { dap_ledger_purge(l_net->pub.ledger, false); dap_chain_net_srv_stake_purge(l_net); @@ -887,8 +858,8 @@ static void s_chain_net_ledger_cache_reload(dap_chain_net_t *l_net) DL_FOREACH(l_net->pub.chains, l_chain) { if (l_chain->callback_purge) l_chain->callback_purge(l_chain); - if (l_chain->callback_set_min_validators_count) - l_chain->callback_set_min_validators_count(l_chain, 0); + if (!dap_strcmp(dap_chain_get_cs_type(l_chain), "esbocs")) + dap_chain_esbocs_set_min_validators_count(l_chain, 0); l_net->pub.fee_value = uint256_0; l_net->pub.fee_addr = c_dap_chain_addr_blank; dap_chain_load_all(l_chain); @@ -1139,7 +1110,8 @@ static int s_cli_net(int argc, char **argv, void **reply) return 0; } - int l_ret = dap_chain_node_cli_cmd_values_parse_net_chain_for_json(&arg_index, argc, argv, NULL, &l_net); + int l_ret = dap_chain_node_cli_cmd_values_parse_net_chain_for_json(&arg_index, argc, argv, NULL, &l_net, + CHAIN_TYPE_INVALID); if ( l_net ) { const char *l_sync_str = NULL; @@ -1303,7 +1275,7 @@ static int s_cli_net(int argc, char **argv, void **reply) dap_json_rpc_error_add(DAP_CHAIN_NET_JSON_RPC_UNDEFINED_PARAMETER_COMMAND_STATS, "%s", "Subcommand 'stats' requires one of parameter: tx"); #endif - l_ret = DAP_CHAIN_NET_JSON_RPC_UNDEFINED_PARAMETER_COMMAND_STATS; + return DAP_CHAIN_NET_JSON_RPC_UNDEFINED_PARAMETER_COMMAND_STATS; } } else if ( l_go_str){ json_object *l_jobj_net = json_object_new_string(l_net->pub.name); @@ -1351,9 +1323,10 @@ static int s_cli_net(int argc, char **argv, void **reply) dap_chain_net_state_go_to(l_net, NET_STATE_SYNC_CHAINS); l_ret = DAP_CHAIN_NET_JSON_RPC_OK; } else { + json_object_put(l_jobj_return); dap_json_rpc_error_add(DAP_CHAIN_NET_JSON_RPC_UNDEFINED_PARAMETER_COMMAND_GO, "%s", "Subcommand 'go' requires one of parameters: online, offline, sync\n"); - l_ret = DAP_CHAIN_NET_JSON_RPC_UNDEFINED_PARAMETER_COMMAND_GO; + return DAP_CHAIN_NET_JSON_RPC_UNDEFINED_PARAMETER_COMMAND_GO; } } else if ( l_get_str){ if ( strcmp(l_get_str,"status") == 0 ) { @@ -1379,7 +1352,7 @@ static int s_cli_net(int argc, char **argv, void **reply) uint256_t l_network_fee = {}; dap_chain_addr_t l_network_fee_addr = {}; dap_chain_net_tx_get_fee(l_net->pub.id, &l_network_fee, &l_network_fee_addr); - char *l_network_fee_coins_str, *l_network_fee_balance_str = + const char *l_network_fee_coins_str, *l_network_fee_balance_str = dap_uint256_to_char(l_network_fee, &l_network_fee_coins_str); json_object *l_jobj_network = json_object_new_object(); json_object *l_jobj_fee_coins = json_object_new_string(l_network_fee_coins_str); @@ -1493,9 +1466,10 @@ static int s_cli_net(int argc, char **argv, void **reply) json_object_object_add(l_jobj_return, "message", l_jobj_ret); l_ret = DAP_CHAIN_NET_JSON_RPC_OK; }else { + json_object_put(l_jobj_return); dap_json_rpc_error_add(DAP_CHAIN_NET_JSON_RPC_UNDEFINED_PARAMETERS_COMMAND_LINK, "%s", "Subcommand 'link' requires one of parameters: list, add, del, info, disconnect_all"); - l_ret = DAP_CHAIN_NET_JSON_RPC_UNDEFINED_PARAMETERS_COMMAND_LINK; + return DAP_CHAIN_NET_JSON_RPC_UNDEFINED_PARAMETERS_COMMAND_LINK; } } else if( l_sync_str) { @@ -1676,7 +1650,7 @@ static int s_cli_net(int argc, char **argv, void **reply) } else if (l_ledger_str && !strcmp(l_ledger_str, "reload")) { int l_return_state = dap_chain_net_stop(l_net); sleep(1); // wait to net going offline - s_chain_net_ledger_cache_reload(l_net); + dap_chain_net_purge(l_net); if (l_return_state) dap_chain_net_start(l_net); } else if (l_list_str && !strcmp(l_list_str, "list")) { @@ -2106,20 +2080,21 @@ int s_net_init(const char *a_net_name, uint16_t a_acl_idx) return 0; } -int s_net_load(dap_chain_net_t *a_net) +bool s_net_load(void *a_arg) { - dap_chain_net_t *l_net = a_net; + dap_chain_net_t *l_net = a_arg; + int l_err_code = 0; - dap_config_t *l_cfg = NULL; - char *l_cfg_path = dap_strdup_printf("network/%s", a_net->pub.name); - l_cfg = dap_config_open ( l_cfg_path ); + char *l_cfg_path = dap_strdup_printf("network/%s", l_net->pub.name); + dap_config_t *l_cfg = dap_config_open(l_cfg_path); DAP_DELETE(l_cfg_path); if (!l_cfg) { log_it(L_ERROR,"Can't open default network config"); - return -1; + l_err_code = -1; + goto ret; } - dap_chain_net_pvt_t * l_net_pvt = PVT(l_net); + dap_chain_net_pvt_t *l_net_pvt = PVT(l_net); // reload ledger cache at once if (s_chain_net_reload_ledger_cache_once(l_net)) { @@ -2188,19 +2163,19 @@ int s_net_load(dap_chain_net_t *a_net) case NODE_ROLE_ROOT:{ // Set to process only zerochain dap_chain_id_t l_chain_id = {{0}}; - dap_chain_t * l_chain = dap_chain_find_by_id(l_net->pub.id,l_chain_id); - if (l_chain ) - l_chain->is_datum_pool_proc = true; + dap_chain_t *l_chain = dap_chain_find_by_id(l_net->pub.id, l_chain_id); + if (l_chain) + l_chain->is_datum_pool_proc = true; log_it(L_INFO,"Root node role established"); } break; case NODE_ROLE_CELL_MASTER: case NODE_ROLE_MASTER:{ uint16_t l_proc_chains_count=0; - char ** l_proc_chains = dap_config_get_array_str(l_cfg,"role-master" , "proc_chains", &l_proc_chains_count ); - for ( size_t i = 0; i< l_proc_chains_count ; i++) { + char **l_proc_chains = dap_config_get_array_str(l_cfg, "role-master", "proc_chains", &l_proc_chains_count); + for (size_t i = 0; i< l_proc_chains_count ; i++) { dap_chain_id_t l_chain_id = {}; if (dap_chain_id_parse(l_proc_chains[i], &l_chain_id) == 0) { - dap_chain_t * l_chain = dap_chain_find_by_id(l_net->pub.id, l_chain_id ); + dap_chain_t *l_chain = dap_chain_find_by_id(l_net->pub.id, l_chain_id ); if (l_chain) l_chain->is_datum_pool_proc = true; else @@ -2232,10 +2207,11 @@ int s_net_load(dap_chain_net_t *a_net) l_net->pub.name, dap_guuid_compose(l_net->pub.id.uint64, 0), l_gdb_groups_mask, DAP_CHAIN_NET_MEMPOOL_TTL, true, DAP_GDB_MEMBER_ROLE_USER, - DAP_CLUSTER_ROLE_EMBEDDED); + DAP_CLUSTER_TYPE_EMBEDDED); if (!l_cluster) { log_it(L_ERROR, "Can't initialize mempool cluster for network %s", l_net->pub.name); - return -1; + l_err_code = -2; + goto ret; } dap_chain_net_add_auth_nodes_to_cluster(l_net, l_cluster); DAP_DELETE(l_gdb_groups_mask); @@ -2248,10 +2224,10 @@ int s_net_load(dap_chain_net_t *a_net) l_net->pub.name, dap_guuid_compose(l_net->pub.id.uint64, 0), l_gdb_groups_mask, 0, true, DAP_GDB_MEMBER_ROLE_GUEST, - DAP_CLUSTER_ROLE_EMBEDDED); + DAP_CLUSTER_TYPE_EMBEDDED); if (!l_net_pvt->orders_cluster) { log_it(L_ERROR, "Can't initialize orders cluster for network %s", l_net->pub.name); - return -1; + goto ret; } dap_chain_net_add_auth_nodes_to_cluster(l_net, l_net_pvt->orders_cluster); DAP_DELETE(l_gdb_groups_mask); @@ -2262,7 +2238,7 @@ int s_net_load(dap_chain_net_t *a_net) l_net->pub.name, dap_guuid_compose(l_net->pub.id.uint64, 0), l_gdb_groups_mask, 0, true, DAP_GDB_MEMBER_ROLE_USER, - DAP_CLUSTER_ROLE_EMBEDDED); + DAP_CLUSTER_TYPE_EMBEDDED); DAP_DELETE(l_gdb_groups_mask); // Nodes and its aliases cluster l_net->pub.gdb_nodes = dap_strdup_printf("%s.nodes.list",l_net->pub.gdb_groups_prefix); @@ -2270,10 +2246,11 @@ int s_net_load(dap_chain_net_t *a_net) l_net->pub.name, dap_guuid_compose(l_net->pub.id.uint64, 0), l_net->pub.gdb_nodes, 0, true, DAP_GDB_MEMBER_ROLE_GUEST, - DAP_CLUSTER_ROLE_EMBEDDED); + DAP_CLUSTER_TYPE_EMBEDDED); if (!l_net_pvt->nodes_cluster) { log_it(L_ERROR, "Can't initialize nodes cluster for network %s", l_net->pub.name); - return -1; + l_err_code = -3; + goto ret; } dap_chain_net_add_auth_nodes_to_cluster(l_net, l_net_pvt->nodes_cluster); dap_chain_net_add_nodelist_notify_callback(l_net, s_nodelist_change_notify, l_net); @@ -2342,10 +2319,17 @@ int s_net_load(dap_chain_net_t *a_net) l_net_pvt->sync_context.sync_idle_time = dap_config_get_item_uint32_default(g_config, "chain", "sync_idle_time", 60); dap_proc_thread_timer_add(NULL, s_sync_timer_callback, l_net, 1000); - log_it(L_INFO, "Chain network \"%s\" initialized",l_net->pub.name); - dap_config_close(l_cfg); - - return 0; + log_it(L_INFO, "Chain network \"%s\" initialized", l_net->pub.name); +ret: + if (l_err_code) + log_it(L_ERROR, "Loading chains of net %s finished with (%d) error code.", l_net->pub.name, l_err_code); + if (l_cfg) + dap_config_close(l_cfg); + pthread_mutex_lock(&s_net_cond_lock); + s_net_loading_count--; + pthread_cond_signal(&s_net_cond); + pthread_mutex_unlock(&s_net_cond_lock); + return false; } static const uint64_t s_fork_sync_step = 20; // TODO get it from config @@ -2356,6 +2340,18 @@ static void s_ch_in_pkt_callback(dap_stream_ch_t *a_ch, uint8_t a_type, const vo a_type, a_data_size, NODE_ADDR_FP_ARGS_S(a_ch->stream->node)); dap_chain_net_t *l_net = a_arg; dap_chain_net_pvt_t *l_net_pvt = PVT(l_net); + + switch (a_type) { + case DAP_CHAIN_CH_PKT_TYPE_CHAIN_SUMMARY: + case DAP_CHAIN_CH_PKT_TYPE_CHAIN_MISS: + case DAP_CHAIN_CH_PKT_TYPE_CHAIN: + case DAP_CHAIN_CH_PKT_TYPE_SYNCED_CHAIN: + // TODO sync state & address checking + break; + default: + break; + } + switch (a_type) { case DAP_CHAIN_CH_PKT_TYPE_ERROR: l_net_pvt->sync_context.state = SYNC_STATE_ERROR; @@ -2373,11 +2369,11 @@ static void s_ch_in_pkt_callback(dap_stream_ch_t *a_ch, uint8_t a_type, const vo 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, + dap_stream_ch_write_error_unsafe(a_ch, l_net->pub.id, + l_net_pvt->sync_context.cur_chain->id, l_net_pvt->sync_context.cur_cell - ? l_net_pvt->sync_context.cur_cell->id.uint64 - : 0, + ? l_net_pvt->sync_context.cur_cell->id + : c_dap_chain_cell_id_null, DAP_CHAIN_CH_ERROR_INCORRECT_SYNC_SEQUENCE); return; } @@ -2388,12 +2384,12 @@ static void s_ch_in_pkt_callback(dap_stream_ch_t *a_ch, uint8_t a_type, const vo : c_dap_chain_cell_id_null, NULL, false); 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, + log_it(L_CRITICAL, "%s", g_error_memory_alloc); + dap_stream_ch_write_error_unsafe(a_ch, l_net->pub.id, + l_net_pvt->sync_context.cur_chain->id, l_net_pvt->sync_context.cur_cell - ? l_net_pvt->sync_context.cur_cell->id.uint64 - : 0, + ? l_net_pvt->sync_context.cur_cell->id + : c_dap_chain_cell_id_null, DAP_CHAIN_CH_ERROR_OUT_OF_MEMORY); return; } @@ -2419,13 +2415,14 @@ static void s_ch_in_pkt_callback(dap_stream_ch_t *a_ch, uint8_t a_type, const vo 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->pub.id, + l_net_pvt->sync_context.cur_chain->id, l_net_pvt->sync_context.cur_cell - ? l_net_pvt->sync_context.cur_cell->id.uint64 - : 0, + ? l_net_pvt->sync_context.cur_cell->id + : c_dap_chain_cell_id_null, &l_request, - sizeof(l_request)); + sizeof(l_request), + DAP_CHAIN_CH_PKT_VERSION_CURRENT); l_net_pvt->sync_context.requested_atom_hash = l_request.hash_from; l_net_pvt->sync_context.requested_atom_num = l_request.num_from; } @@ -2496,6 +2493,12 @@ static void s_sync_timer_callback(void *a_arg) } // TODO make correct working with cells assert(l_net_pvt->sync_context.cur_chain); + if (l_net_pvt->sync_context.cur_chain->callback_load_from_gdb) { + // This type of chain is GDB based and not synced by chains protocol + l_net_pvt->sync_context.cur_chain = l_net_pvt->sync_context.cur_chain->next; + l_net_pvt->sync_context.last_state = SYNC_STATE_SYNCED; + return; + } l_net_pvt->sync_context.cur_cell = l_net_pvt->sync_context.cur_chain->cells; l_net_pvt->sync_context.state = l_net_pvt->sync_context.last_state = SYNC_STATE_WAITING; dap_chain_ch_sync_request_t l_request = {}; @@ -2511,11 +2514,11 @@ static void s_sync_timer_callback(void *a_arg) 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_request, sizeof(l_request)); + dap_chain_ch_pkt_t *l_chain_pkt = dap_chain_ch_pkt_new(l_net->pub.id, l_net_pvt->sync_context.cur_chain->id, + l_net_pvt->sync_context.cur_cell ? l_net_pvt->sync_context.cur_cell->id : c_dap_chain_cell_id_null, + &l_request, sizeof(l_request), DAP_CHAIN_CH_PKT_VERSION_CURRENT); if (!l_chain_pkt) { - log_it(L_CRITICAL, g_error_memory_alloc); + log_it(L_CRITICAL, "%s", g_error_memory_alloc); return; } log_it(L_INFO, "Start synchronization process with " NODE_ADDR_FP_STR @@ -2963,7 +2966,7 @@ static bool s_net_check_acl(dap_chain_net_t *a_net, dap_chain_hash_fast_t *a_pke { const char l_path[] = "network/"; char l_cfg_path[strlen(a_net->pub.name) + strlen(l_path) + 1]; - dap_snprintf(l_cfg_path, sizeof(l_cfg_path), "%s%s", l_path, a_net->pub.name); + snprintf(l_cfg_path, sizeof(l_cfg_path), "%s%s", l_path, a_net->pub.name); dap_config_t *l_cfg = dap_config_open(l_cfg_path); const char *l_auth_type = dap_config_get_item_str(l_cfg, "auth", "type"); bool l_authorized = true; diff --git a/modules/net/dap_chain_net_anchor.c b/modules/net/dap_chain_net_anchor.c index 4012dda4c1840a201af448b5bb93cdd79f3b9fec..3fdea387b5362f1fdfb86ff053b42e26c1d49e54 100644 --- a/modules/net/dap_chain_net_anchor.c +++ b/modules/net/dap_chain_net_anchor.c @@ -25,7 +25,6 @@ #include <assert.h> #include "dap_common.h" #include "dap_sign.h" -#include "dap_cert.h" #include "dap_pkey.h" #include "dap_chain.h" #include "dap_chain_cell.h" @@ -33,6 +32,9 @@ #include "dap_chain_ledger.h" #include "dap_chain_datum_decree.h" #include "dap_chain_net_srv_stake_pos_delegate.h" +#include "dap_chain_net.h" +#include "dap_chain_net_decree.h" +#include "dap_chain_datum_anchor.h" #define LOG_TAG "chain_net_anchor" diff --git a/modules/net/dap_chain_net_balancer.c b/modules/net/dap_chain_net_balancer.c index 591778a033598775ac23700b6b1ed2aad8bbad78..1c0ed5b4ce56a3023ecdeb22c1f1f5e351f9a199 100644 --- a/modules/net/dap_chain_net_balancer.c +++ b/modules/net/dap_chain_net_balancer.c @@ -29,7 +29,9 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic #include "http_status_code.h" #include "dap_chain_node_client.h" #include "dap_chain_node_dns_client.h" -#include "rand/dap_rand.h" +#include "dap_net.h" +#include "dap_client_http.h" +#include "dap_enc_base64.h" #include "dap_notify_srv.h" #define LOG_TAG "dap_chain_net_balancer" @@ -153,7 +155,7 @@ static void s_balancer_link_prepare_error(dap_balancer_link_request_t *a_request { struct json_object *l_json = s_balancer_states_json_collect(a_request->net, a_host_addr, a_host_port); char l_err_str[512] = { '\0' }; - dap_snprintf(l_err_str, sizeof(l_err_str) + snprintf(l_err_str, sizeof(l_err_str) , "Link from balancer %s can't be prepared, errno %d" , a_host_addr, a_errno); log_it(L_WARNING, "%s", l_err_str); @@ -511,4 +513,4 @@ dap_string_t *dap_chain_net_balancer_get_node_str(dap_chain_net_t *a_net) dap_string_append(l_ret, "-----------------------------------------------------------------\n"); DAP_DEL_Z(l_links_info_list); return l_ret; -} \ No newline at end of file +} diff --git a/modules/net/dap_chain_net_decree.c b/modules/net/dap_chain_net_decree.c index 7069b07a373784216445536e8f3e115bc263a9c0..b805446d2a36bf5296659e9ebdb1001a7a30f65c 100644 --- a/modules/net/dap_chain_net_decree.c +++ b/modules/net/dap_chain_net_decree.c @@ -25,12 +25,11 @@ #include <assert.h> #include "dap_common.h" #include "dap_sign.h" -#include "dap_cert.h" #include "dap_pkey.h" #include "dap_chain_common.h" #include "dap_chain_net.h" #include "dap_chain_net_decree.h" -#include "dap_chain_net_srv.h" +#include "dap_chain_cs_esbocs.h" #include "dap_chain_net_tx.h" #include "dap_chain_net_srv_stake_pos_delegate.h" #include "dap_http_ban_list_client.h" @@ -198,7 +197,7 @@ static int s_decree_verify(dap_chain_net_t *a_net, dap_chain_datum_decree_t *a_d DAP_DELETE(l_unique_signs); if (l_signs_verify_counter < l_min_signs) { - log_it(L_WARNING,"Not enough valid signatures, get %hu from %hu", l_signs_verify_counter, l_min_signs); + log_it(L_WARNING, "Not enough valid signatures, get %hu from %hu", l_signs_verify_counter, l_min_signs); return -107; } @@ -367,12 +366,15 @@ static bool s_verify_pkey (dap_sign_t *a_sign, dap_chain_net_t *a_net) static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain_net_t *a_net, bool a_apply, bool a_load_mode) { - uint256_t l_uint256_buffer; - uint16_t l_uint16_buffer; - dap_chain_addr_t l_addr = {}; //???????? + uint256_t l_value; + uint32_t l_sign_type; + uint16_t l_owners_num; + uint8_t l_action; + dap_chain_addr_t l_addr = {}; dap_hash_fast_t l_hash = {}; dap_chain_node_addr_t l_node_addr = {}; dap_list_t *l_owners_list = NULL; + const char *l_ban_addr; dap_return_val_if_fail(a_decree && a_net, -112); @@ -386,17 +388,17 @@ static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain } else l_addr = a_net->pub.fee_addr; } - if (dap_chain_datum_decree_get_fee(a_decree, &l_uint256_buffer)) { + if (dap_chain_datum_decree_get_fee(a_decree, &l_value)) { log_it(L_WARNING,"Can't get fee value from decree."); return -103; } if (!a_apply) break; - if (!dap_chain_net_tx_set_fee(a_net->pub.id, l_uint256_buffer, l_addr)) + if (!dap_chain_net_tx_set_fee(a_net->pub.id, l_value, l_addr)) log_it(L_ERROR, "Can't set fee value for network %s", a_net->pub.name); break; case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_OWNERS: - l_owners_list = dap_chain_datum_decree_get_owners(a_decree, &l_uint16_buffer); + l_owners_list = dap_chain_datum_decree_get_owners(a_decree, &l_owners_num); if (!l_owners_list){ log_it(L_WARNING,"Can't get ownners from decree."); return -104; @@ -405,26 +407,30 @@ static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain if (!a_apply) break; - a_net->pub.decree->num_of_owners = l_uint16_buffer; + a_net->pub.decree->num_of_owners = l_owners_num; dap_list_free_full(a_net->pub.decree->pkeys, NULL); a_net->pub.decree->pkeys = l_owners_list; break; case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_OWNERS_MIN: - if (dap_chain_datum_decree_get_min_owners(a_decree, &l_uint16_buffer)){ - log_it(L_WARNING,"Can't get min number of ownners from decree."); + if (dap_chain_datum_decree_get_min_owners(a_decree, &l_value)) { + log_it(L_WARNING, "Can't get min number of ownners from decree."); return -105; } + if (IS_ZERO_256(l_value) || compare256(l_value, GET_256_FROM_64(UINT16_MAX)) == 1) { + log_it(L_WARNING, "Illegal min number of owners %s", dap_uint256_to_char(l_value, NULL)); + return -116; + } if (!a_apply) break; - a_net->pub.decree->min_num_of_owners = l_uint16_buffer; + a_net->pub.decree->min_num_of_owners = dap_uint256_to_uint64(l_value); break; case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_APPROVE: - if (dap_chain_datum_decree_get_stake_tx_hash(a_decree, &l_hash)){ + if (dap_chain_datum_decree_get_hash(a_decree, &l_hash)){ log_it(L_WARNING,"Can't get tx hash from decree."); return -105; } - if (dap_chain_datum_decree_get_stake_value(a_decree, &l_uint256_buffer)){ + if (dap_chain_datum_decree_get_stake_value(a_decree, &l_value)){ log_it(L_WARNING,"Can't get stake value from decree."); return -106; } @@ -446,7 +452,7 @@ static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain } if (!a_apply) break; - dap_chain_net_srv_stake_key_delegate(a_net, &l_addr, &l_hash, l_uint256_buffer, &l_node_addr); + dap_chain_net_srv_stake_key_delegate(a_net, &l_addr, &l_hash, l_value, &l_node_addr); break; case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_INVALIDATE: if (dap_chain_datum_decree_get_stake_signing_addr(a_decree, &l_addr)){ @@ -458,16 +464,16 @@ static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain dap_chain_net_srv_stake_key_invalidate(&l_addr); break; case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALUE: - if (dap_chain_datum_decree_get_stake_min_value(a_decree, &l_uint256_buffer)){ + if (dap_chain_datum_decree_get_stake_min_value(a_decree, &l_value)){ log_it(L_WARNING,"Can't get min stake value from decree."); return -105; } if (!a_apply) break; - dap_chain_net_srv_stake_set_allowed_min_value(l_uint256_buffer); + dap_chain_net_srv_stake_set_allowed_min_value(a_net->pub.id, l_value); break; case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALIDATORS_COUNT: - if (dap_chain_datum_decree_get_stake_min_signers_count(a_decree, &l_uint256_buffer)){ + if (dap_chain_datum_decree_get_stake_min_signers_count(a_decree, &l_value)){ log_it(L_WARNING,"Can't get min stake value from decree."); return -105; } @@ -476,72 +482,44 @@ static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain log_it(L_WARNING, "Specified chain not found"); return -106; } - if (!l_chain->callback_set_min_validators_count) { + if (dap_strcmp(dap_chain_get_cs_type(l_chain), "esbocs")) { log_it(L_WARNING, "Can't apply this decree to specified chain"); return -115; } if (!a_apply) break; - l_chain->callback_set_min_validators_count(l_chain, (uint16_t)dap_chain_uint256_to(l_uint256_buffer)); + dap_chain_esbocs_set_min_validators_count(l_chain, (uint16_t)dap_chain_uint256_to(l_value)); break; case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_BAN: { + if (dap_chain_datum_decree_get_ban_addr(a_decree, &l_ban_addr)) { + log_it(L_WARNING, "Can't get ban address from decree."); + return -114; + } + if (dap_http_ban_list_client_check(l_ban_addr, NULL, NULL)) { + log_it(L_ERROR, "Can't ban addr %s: already banlisted", l_ban_addr); + return -112; + } if (!a_apply) break; - size_t l_tsd_offset = 0, tsd_data_size = a_decree->header.data_size; - while(l_tsd_offset < tsd_data_size){ - dap_tsd_t *l_tsd = (dap_tsd_t *)(a_decree->data_n_signs + l_tsd_offset); - size_t l_tsd_size = dap_tsd_size(l_tsd); - if(l_tsd_size > tsd_data_size){ - log_it(L_WARNING,"TSD size is greater than all data size. It's possible corrupt data."); - return -2; - } - dap_hash_fast_t l_decree_hash = {0}; - dap_hash_fast(a_decree, dap_chain_datum_decree_get_size(a_decree), &l_decree_hash); - char *l_addr = dap_tsd_get_string(l_tsd); - switch (l_tsd->type) { - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST: - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR: - if ( dap_http_ban_list_client_add(l_addr, l_decree_hash, a_decree->header.ts_created) ) { - log_it(L_ERROR, "Can't ban addr %s: already banlisted", l_addr); - return -4; - } break; - default: - log_it(L_WARNING, "Invalid section TSD type for sub-decree datum of type " - "DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_BAN."); - return -3; - } - l_tsd_offset += l_tsd_size; - } + dap_hash_fast_t l_decree_hash = {0}; + dap_hash_fast(a_decree, dap_chain_datum_decree_get_size(a_decree), &l_decree_hash); + dap_http_ban_list_client_add(l_ban_addr, l_decree_hash, a_decree->header.ts_created); } break; case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_UNBAN: { + if (dap_chain_datum_decree_get_ban_addr(a_decree, &l_ban_addr)) { + log_it(L_WARNING, "Can't get ban address from decree."); + return -114; + } + if (!dap_http_ban_list_client_check(l_ban_addr, NULL, NULL)) { + log_it(L_ERROR, "Can't ban addr %s: already banlisted", l_ban_addr); + return -112; + } if (!a_apply) break; - size_t l_tsd_offset = 0, tsd_data_size = a_decree->header.data_size; - while(l_tsd_offset < tsd_data_size){ - dap_tsd_t *l_tsd = (dap_tsd_t *)(a_decree->data_n_signs + l_tsd_offset); - size_t l_tsd_size = dap_tsd_size(l_tsd); - if(l_tsd_size > tsd_data_size){ - log_it(L_WARNING,"TSD size is greater than all data size. It's possible corrupt data."); - return -2; - } - char *l_addr = dap_tsd_get_string(l_tsd); - switch (l_tsd->type) { - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST: - case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR: - if ( dap_http_ban_list_client_remove(l_addr) ) { - log_it(L_ERROR, "Can't unban addr %s: not banlisted", l_addr); - return -4; - } break; - default: - log_it(L_WARNING, "Invalid section TSD type for sub-decree datum of type " - "DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_BAN."); - return -3; - } - l_tsd_offset += l_tsd_size; - } + dap_http_ban_list_client_remove(l_ban_addr); } break; case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_REWARD: { - if (dap_chain_datum_decree_get_value(a_decree, &l_uint256_buffer)) { + if (dap_chain_datum_decree_get_value(a_decree, &l_value)) { log_it(L_WARNING,"Can't get value from decree."); return -103; } @@ -550,10 +528,80 @@ static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain log_it(L_WARNING, "Specified chain not found"); return -106; } + if (dap_strcmp(dap_chain_get_cs_type(l_chain), "esbocs")) { + log_it(L_WARNING, "Can't apply this decree to specified chain"); + return -115; + } if (!a_apply) break; uint64_t l_cur_block_num = l_chain->callback_count_atom(l_chain); - dap_chain_net_add_reward(a_net, l_uint256_buffer, l_cur_block_num); + dap_chain_net_add_reward(a_net, l_value, l_cur_block_num); + } break; + case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_MAX_WEIGHT: { + if (dap_chain_datum_decree_get_value(a_decree, &l_value)) { + log_it(L_WARNING,"Can't get value from decree."); + return -103; + } + dap_chain_t *l_chain = dap_chain_find_by_id(a_net->pub.id, a_decree->header.common_decree_params.chain_id); + if (!l_chain) { + log_it(L_WARNING, "Specified chain not found"); + return -106; + } + if (dap_strcmp(dap_chain_get_cs_type(l_chain), "esbocs")) { + log_it(L_WARNING, "Can't apply this decree to specified chain"); + return -115; + } + if (compare256(l_value, dap_chain_coins_to_balance("1.0")) >= 0) { + log_it(L_WARNING, "Percent must be lower than 100%%"); + return -116; + } + if (!a_apply) + break; + dap_chain_net_srv_stake_set_percent_max(a_net->pub.id, l_value); + } break; + case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_CHECK_SIGNS_STRUCTURE: { + if (dap_chain_datum_decree_get_action(a_decree, &l_action)) { + log_it(L_WARNING,"Can't get action from decree."); + return -103; + } + dap_chain_t *l_chain = dap_chain_find_by_id(a_net->pub.id, a_decree->header.common_decree_params.chain_id); + if (!l_chain) { + log_it(L_WARNING, "Specified chain not found"); + return -106; + } + if (dap_strcmp(dap_chain_get_cs_type(l_chain), "esbocs")) { + log_it(L_WARNING, "Can't apply this decree to specified chain"); + return -115; + } + if (!a_apply) + break; + dap_chain_esbocs_set_signs_struct_check(l_chain, l_action); + } break; + case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_EMERGENCY_VALIDATORS: { + if (dap_chain_datum_decree_get_action(a_decree, &l_action)) { + log_it(L_WARNING,"Can't get action from decree."); + return -103; + } + if (dap_chain_datum_decree_get_signature_type(a_decree, &l_sign_type)) { + log_it(L_WARNING,"Can't get signature type from decree."); + return -113; + } + if (dap_chain_datum_decree_get_hash(a_decree, &l_hash)){ + log_it(L_WARNING,"Can't get validator hash from decree."); + return -105; + } + dap_chain_t *l_chain = dap_chain_find_by_id(a_net->pub.id, a_decree->header.common_decree_params.chain_id); + if (!l_chain) { + log_it(L_WARNING, "Specified chain not found"); + return -106; + } + if (dap_strcmp(dap_chain_get_cs_type(l_chain), "esbocs")) { + log_it(L_WARNING, "Can't apply this decree to specified chain"); + return -115; + } + if (!a_apply) + break; + dap_chain_esbocs_set_emergency_validator(l_chain, l_action, l_sign_type, &l_hash); } break; default: return -1; diff --git a/modules/net/dap_chain_net_node_list.c b/modules/net/dap_chain_net_node_list.c index 45a95c880653240d85e7f1e6f5b7bc26dc24a0fb..205a5bf2193ce6215302ad42108e1230eeedc2e3 100644 --- a/modules/net/dap_chain_net_node_list.c +++ b/modules/net/dap_chain_net_node_list.c @@ -105,7 +105,7 @@ void dap_chain_net_node_check_http_issue_link(dap_http_simple_t *a_http_simple, *l_return_code = Http_Status_MethodNotAllowed; return; } - char *l_key = dap_stream_node_addr_to_str_static( (dap_chain_node_addr_t){.uint64 = addr} ); + const char *l_key = dap_stream_node_addr_to_str_static( (dap_chain_node_addr_t){.uint64 = addr} ); if (!l_key) { log_it(L_ERROR, "Bad node address %zu", addr); *l_return_code = Http_Status_BadRequest; diff --git a/modules/net/dap_chain_node.c b/modules/net/dap_chain_node.c index fdfae11a181d1ecaedf5c6db630ae1342201614e..1500729a435cf319413ba9fd8102926d90135957 100644 --- a/modules/net/dap_chain_node.c +++ b/modules/net/dap_chain_node.c @@ -39,13 +39,11 @@ #include <netinet/in.h> #endif -#include "utlist.h" #include "dap_hash.h" -#include "rand/dap_rand.h" #include "dap_chain_net.h" #include "dap_global_db.h" #include "dap_chain_node.h" -#include "dap_chain_cell.h" +#include "dap_chain_cs_esbocs.h" #include "dap_chain_ledger.h" #define LOG_TAG "dap_chain_node" @@ -89,14 +87,14 @@ static void s_update_node_states_info(UNUSED_ARG void *a_arg) memcpy(l_info->links_addrs, l_linked_node_addrs, (l_info->uplinks_count + l_info->downlinks_count) * sizeof(dap_chain_node_addr_t)); // DB write char *l_gdb_group = dap_strdup_printf("%s.nodes.states", l_net->pub.gdb_groups_prefix); - char *l_node_addr_str = dap_stream_node_addr_to_str_static(l_info->address); + const char *l_node_addr_str = dap_stream_node_addr_to_str_static(l_info->address); dap_global_db_set_sync(l_gdb_group, l_node_addr_str, l_info, l_info_size, false); DAP_DEL_MULTY(l_linked_node_addrs, l_info, l_gdb_group); } } } -static void s_states_info_to_str(dap_chain_net_t *a_net, char *a_node_addr_str, dap_string_t *l_info_str) +static void s_states_info_to_str(dap_chain_net_t *a_net, const char *a_node_addr_str, dap_string_t *l_info_str) { // sanity check dap_return_if_pass(!a_net || !a_node_addr_str || !l_info_str); @@ -137,7 +135,7 @@ static void s_states_info_to_str(dap_chain_net_t *a_net, char *a_node_addr_str, dap_string_t *dap_chain_node_states_info_read(dap_chain_net_t *a_net, dap_stream_node_addr_t a_addr) { dap_string_t *l_ret = dap_string_new(""); - char *l_node_addr_str = dap_stream_node_addr_to_str_static(a_addr.uint64 ? a_addr : g_node_addr); + const char *l_node_addr_str = dap_stream_node_addr_to_str_static(a_addr.uint64 ? a_addr : g_node_addr); if(!a_net) { for (dap_chain_net_t *l_net = dap_chain_net_iter_start(); l_net; l_net = dap_chain_net_iter_next(l_net)) { s_states_info_to_str(l_net, l_node_addr_str, l_ret); @@ -227,7 +225,7 @@ int dap_chain_node_info_del(dap_chain_net_t *a_net, dap_chain_node_info_t *a_nod */ dap_chain_node_info_t* dap_chain_node_info_read(dap_chain_net_t *a_net, dap_chain_node_addr_t *a_address) { - char *l_key = dap_stream_node_addr_to_str_static(*a_address); + const char *l_key = dap_stream_node_addr_to_str_static(*a_address); size_t l_node_info_size = 0; dap_chain_node_info_t *l_node_info = (dap_chain_node_info_t*)dap_global_db_get_sync(a_net->pub.gdb_nodes, l_key, &l_node_info_size, NULL, NULL); @@ -302,7 +300,7 @@ void dap_chain_node_mempool_process_all(dap_chain_t *a_chain, bool a_force) if (dap_chain_node_mempool_need_process(a_chain, l_datum)) { if (l_datum->header.type_id == DAP_CHAIN_DATUM_TX && - a_chain->callback_get_minimum_fee){ + !dap_strcmp(dap_chain_get_cs_type(a_chain), "esbocs")) { uint256_t l_tx_fee = {}; dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)l_datum->data; if (dap_chain_datum_tx_get_fee_value (l_tx, &l_tx_fee) || @@ -313,7 +311,7 @@ void dap_chain_node_mempool_process_all(dap_chain_t *a_chain, bool a_force) } else log_it(L_DEBUG, "Process service tx without fee"); } else { - uint256_t l_min_fee = a_chain->callback_get_minimum_fee(a_chain); + uint256_t l_min_fee = dap_chain_esbocs_get_fee(a_chain->net_id); if (compare256(l_tx_fee, l_min_fee) < 0) { char *l_tx_fee_str = dap_chain_balance_to_coins(l_tx_fee); char *l_min_fee_str = dap_chain_balance_to_coins(l_min_fee); diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index ee18fd50ca05fe7e50e01dee39e15ee9192e5894..68e8ce8e4cc3fbe1f9bd4f8891736d835a6d7da3 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -68,6 +68,7 @@ #include "dap_cert_file.h" #include "dap_file_utils.h" #include "dap_enc_base58.h" +#include "dap_enc_ks.h" #include "dap_chain_wallet.h" #include "dap_chain_wallet_internal.h" #include "dap_chain_node.h" @@ -76,17 +77,13 @@ #include "dap_chain_node_client.h" #include "dap_chain_node_cli_cmd.h" #include "dap_chain_node_cli_cmd_tx.h" -#include "dap_chain_node_ping.h" +#include "dap_net.h" #include "dap_chain_net_srv.h" #include "dap_chain_net_tx.h" #include "dap_chain_net_balancer.h" -#include "dap_chain_block.h" -#include "dap_chain_cs_blocks.h" - #include "dap_chain_cell.h" - #include "dap_enc_base64.h" -#include "json.h" + #ifdef DAP_OS_UNIX #include <dirent.h> #endif @@ -98,25 +95,19 @@ #include "dap_chain_ledger.h" #include "dap_chain_mempool.h" #include "dap_global_db.h" -#include "dap_global_db_cluster.h" #include "dap_global_db_pkt.h" - -#include "dap_stream_ch_chain_net.h" #include "dap_chain_ch.h" -#include "dap_stream_ch_chain_net_pkt.h" #include "dap_enc_base64.h" -#include "dap_chain_net_srv_stake_pos_delegate.h" #include "dap_chain_net_node_list.h" #include "dap_json_rpc_errors.h" -#include "dap_json_rpc_chain_datum.h" #include "dap_http_ban_list_client.h" #include "dap_chain_datum_tx_voting.h" +#include "dap_enc_ks.h" #define LOG_TAG "chain_node_cli_cmd" -static void s_dap_chain_net_purge(dap_chain_net_t *a_net); int _cmd_mempool_add_ca(dap_chain_net_t *a_net, dap_chain_t *a_chain, dap_cert_t *a_cert, void **a_str_reply); /** @@ -382,31 +373,6 @@ static int s_node_info_list_with_reply(dap_chain_net_t *a_net, dap_chain_node_ad return l_ret; } -/** - * @brief purge ledger, stake, decree, all chains and remove chain files - * @param a_net - */ -void s_dap_chain_net_purge(dap_chain_net_t * a_net) -{ - if (!a_net) - return; - dap_chain_t *l_chain = NULL; - dap_ledger_purge(a_net->pub.ledger, false); - dap_chain_net_srv_stake_purge(a_net); - dap_chain_net_decree_purge(a_net); - DL_FOREACH(a_net->pub.chains, l_chain) { - if (l_chain->callback_purge) - l_chain->callback_purge(l_chain); - if (l_chain->callback_set_min_validators_count) - l_chain->callback_set_min_validators_count(l_chain, 0); - const char *l_chains_rm_path = dap_chain_get_path(l_chain); - dap_rm_rf(l_chains_rm_path); - a_net->pub.fee_value = uint256_0; - a_net->pub.fee_addr = c_dap_chain_addr_blank; - dap_chain_load_all(l_chain); - } -} - /** * @brief com_global_db * global_db command @@ -455,7 +421,8 @@ int com_global_db(int a_argc, char ** a_argv, void **a_str_reply) dap_chain_t * l_chain = NULL; dap_chain_net_t * l_net = NULL; - if(dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, a_argc, a_argv, a_str_reply, &l_chain, &l_net) < 0) + if(dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, a_argc, a_argv, a_str_reply, &l_chain, &l_net, + CHAIN_TYPE_INVALID) < 0) return -11; const char *l_cell_str = NULL, *l_chain_str = NULL; @@ -813,7 +780,7 @@ int com_global_db(int a_argc, char ** a_argv, void **a_str_reply) size_t l_count = 0; for (dap_list_t *l_list = l_group_list; l_list; l_list = dap_list_next(l_list), ++l_count) { dap_string_append_printf(l_ret_str, "\t%-40s : %zu records\n", (char*)l_list->data, - dap_global_db_driver_count((char*)l_list->data, c_dap_global_db_driver_hash_blank)); + dap_global_db_driver_count((char*)l_list->data, c_dap_global_db_driver_hash_blank, false)); } dap_cli_server_cmd_set_reply_text(a_str_reply, "Group list:\n%sTotal count: %zu\n", l_ret_str->str, l_count); dap_string_free(l_ret_str, true); @@ -828,9 +795,13 @@ int com_global_db(int a_argc, char ** a_argv, void **a_str_reply) static dap_tsd_t* s_chain_node_cli_com_node_create_tsd_addr(char **a_argv, int a_arg_start, int a_arg_end, void **a_str_reply, const char *a_specified_decree) { const char *l_ban_addr_str = NULL; - if (dap_cli_server_cmd_find_option_val(a_argv, a_arg_start, a_arg_end, "-addr", &l_ban_addr_str)) - return dap_tsd_create_string(DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR, l_ban_addr_str); - else if (dap_cli_server_cmd_find_option_val(a_argv, a_arg_start, a_arg_end, "-host", &l_ban_addr_str)) + if (dap_cli_server_cmd_find_option_val(a_argv, a_arg_start, a_arg_end, "-addr", &l_ban_addr_str)) { + dap_chain_addr_t *l_format = dap_chain_addr_from_str(l_ban_addr_str); + if (!l_format) + return dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't convert the -addr option value to node address"), NULL; + DAP_DELETE(l_format); + return dap_tsd_create_string(DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STRING, l_ban_addr_str); + } else if (dap_cli_server_cmd_find_option_val(a_argv, a_arg_start, a_arg_end, "-host", &l_ban_addr_str)) return dap_tsd_create_string(DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST, l_ban_addr_str); else return dap_cli_server_cmd_set_reply_text(a_str_reply, "The -host or -addr option was not " @@ -891,7 +862,7 @@ int com_node(int a_argc, char ** a_argv, void **a_str_reply) // find net dap_chain_net_t *l_net = NULL; - if(dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, a_argc, a_argv, a_str_reply, NULL, &l_net) < 0) { + if(dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, a_argc, a_argv, a_str_reply, NULL, &l_net, CHAIN_TYPE_INVALID) < 0) { if (cmd_num != CMD_BANLIST && cmd_num != CMD_CONNECTIONS && cmd_num != CMD_DUMP) return -11; } @@ -1259,6 +1230,7 @@ int com_node(int a_argc, char ** a_argv, void **a_str_reply) } break; case CMD_CONNECTIONS: { + if (l_net) { dap_cluster_t *l_links_cluster = dap_cluster_by_mnemonim(l_net->pub.name); if (!l_links_cluster) { @@ -1271,8 +1243,14 @@ int com_node(int a_argc, char ** a_argv, void **a_str_reply) dap_cluster_t *l_cluster = NULL; dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-cluster", &l_guuid_str); if (l_guuid_str) { - dap_guuid_t l_guuid = dap_guuid_from_hex_str(l_guuid_str); + bool l_success = false; + dap_guuid_t l_guuid = dap_guuid_from_hex_str(l_guuid_str, &l_success); + if (!l_success) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't parse cluster guid %s", l_guuid_str); + break; + } l_cluster = dap_cluster_find(l_guuid); + if (!l_cluster) { dap_cli_server_cmd_set_reply_text(a_str_reply, "Not found cluster with ID %s", l_guuid_str); break; @@ -1285,7 +1263,8 @@ int com_node(int a_argc, char ** a_argv, void **a_str_reply) case CMD_BAN: { dap_chain_net_t *l_netl = NULL; dap_chain_t *l_chain = NULL; - if(dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, a_argc, a_argv, a_str_reply, &l_chain, &l_netl) < 0) + if(dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, a_argc, a_argv, a_str_reply, &l_chain, &l_netl, + CHAIN_TYPE_DECREE) < 0) return -11; const char * l_hash_out_type = NULL; dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-H", &l_hash_out_type); @@ -1347,7 +1326,8 @@ int com_node(int a_argc, char ** a_argv, void **a_str_reply) case CMD_UNBAN: { dap_chain_net_t *l_netl = NULL; dap_chain_t *l_chain = NULL; - if(dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, a_argc, a_argv, a_str_reply, &l_chain, &l_netl) < 0) + if(dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, a_argc, a_argv, a_str_reply, &l_chain, &l_net, + CHAIN_TYPE_DECREE) < 0) return -11; const char * l_hash_out_type = NULL; dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-H", &l_hash_out_type); @@ -1842,10 +1822,10 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE; if (l_wallet) { l_addr = l_net ? dap_chain_wallet_get_addr(l_wallet, l_net->pub.id) : NULL; - char *l_addr_str = dap_chain_addr_to_str(l_addr); + const char *l_addr_str = dap_chain_addr_to_str(l_addr); json_object_object_add(json_obj_wall, "Wallet", json_object_new_string(l_file_name)); if(l_wallet->flags & DAP_WALLET$M_FL_ACTIVE) - json_object_object_add(json_obj_wall, "status", json_object_new_string("Active")); + json_object_object_add(json_obj_wall, "status", json_object_new_string("active")); else json_object_object_add(json_obj_wall, "status", json_object_new_string("not active")); json_object_object_add(json_obj_wall, "sign_status", json_object_new_string( @@ -1914,7 +1894,7 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE; } } json_object * json_obj_wall = json_object_new_object(); - char *l_l_addr_str = dap_chain_addr_to_str((dap_chain_addr_t*) l_addr); + const char *l_l_addr_str = dap_chain_addr_to_str((dap_chain_addr_t*) l_addr); if(l_wallet) { json_object_object_add(json_obj_wall, "sign", json_object_new_string( @@ -1935,7 +1915,7 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE; if(l_l_addr_tokens[i]) { json_object * j_balance_data = json_object_new_object(); uint256_t l_balance = dap_ledger_calc_balance(l_ledger, l_addr, l_l_addr_tokens[i]); - char *l_balance_coins, *l_balance_datoshi = dap_uint256_to_char(l_balance, &l_balance_coins); + const char *l_balance_coins, *l_balance_datoshi = dap_uint256_to_char(l_balance, &l_balance_coins); json_object_object_add(j_balance_data, "balance", json_object_new_string("")); json_object_object_add(j_balance_data, "coins", json_object_new_string(l_balance_coins)); json_object_object_add(j_balance_data, "datoshi", json_object_new_string(l_balance_datoshi)); @@ -2160,7 +2140,7 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE; l_addr = l_net ? dap_chain_wallet_get_addr(l_wallet,l_net->pub.id ) : NULL; - char *l_addr_str = dap_chain_addr_to_str(l_addr); + const char *l_addr_str = dap_chain_addr_to_str(l_addr); json_object * json_obj_wall = json_object_new_object(); json_object_object_add(json_obj_wall, "Wallet name", json_object_new_string(l_wallet->name)); json_object_object_add(json_obj_wall, "Sign type", json_object_new_string(l_sign_type_str)); @@ -2193,11 +2173,13 @@ typedef enum dap_chain_node_cli_cmd_values_parse_net_chain_err_to_json { DAP_CHAIN_NODE_CLI_CMD_VALUES_PARSE_NET_CHAIN_ERR_CHAIN_STR_IS_NULL = 105, DAP_CHAIN_NODE_CLI_CMD_VALUES_PARSE_NET_CHAIN_ERR_CONFIG_DEFAULT_DATUM = 106, DAP_CHAIN_NODE_CLI_CMD_VALUE_PARSE_CONVERT_BASE58_TO_ADDR_WALLET = 107, - DAP_CHAIN_NODE_CLI_CMD_VALUE_PARSE_FAST_AND_BASE58_ADDR + DAP_CHAIN_NODE_CLI_CMD_VALUE_PARSE_FAST_AND_BASE58_ADDR, + DAP_CHAIN_NODE_CLI_CMD_VALUE_PARSE_CAN_NOT_FIND_DEFAULT_CHAIN_WITH_TYPE } dap_chain_node_cli_cmd_values_parse_net_chain_err_to_json; int dap_chain_node_cli_cmd_values_parse_net_chain_for_json(int *a_arg_index, int a_argc, char **a_argv, - dap_chain_t **a_chain, dap_chain_net_t **a_net) { + dap_chain_t **a_chain, dap_chain_net_t **a_net, + dap_chain_type_t a_default_chain_type) { const char * l_chain_str = NULL; const char * l_net_str = NULL; @@ -2250,13 +2232,15 @@ int dap_chain_node_cli_cmd_values_parse_net_chain_for_json(int *a_arg_index, int dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_CMD_VALUES_PARSE_NET_CHAIN_ERR_CHAIN_NOT_FOUND, l_str_to_reply); return DAP_CHAIN_NODE_CLI_CMD_VALUES_PARSE_NET_CHAIN_ERR_CHAIN_NOT_FOUND; } - } - else if (!strcmp(a_argv[0], "token_decl") || !strcmp(a_argv[0], "token_decl_sign")) { - if ( (*a_chain = dap_chain_net_get_default_chain_by_chain_type(*a_net, CHAIN_TYPE_TOKEN)) == NULL ) - { - dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_CMD_VALUES_PARSE_NET_CHAIN_ERR_CONFIG_DEFAULT_DATUM, "%s requires parameter '-chain' or set default datum " - "type in chain configuration file"); - return DAP_CHAIN_NODE_CLI_CMD_VALUES_PARSE_NET_CHAIN_ERR_CONFIG_DEFAULT_DATUM; + } else if (a_default_chain_type != CHAIN_TYPE_INVALID) { + if ((*a_chain = dap_chain_net_get_default_chain_by_chain_type(*a_net, a_default_chain_type)) != NULL) { + return 0; + } else { + dap_json_rpc_error_add( + DAP_CHAIN_NODE_CLI_CMD_VALUE_PARSE_CAN_NOT_FIND_DEFAULT_CHAIN_WITH_TYPE, + "Unable to get the default chain of type %s for the network.", dap_chain_type_to_str(a_default_chain_type)); + return DAP_CHAIN_NODE_CLI_CMD_VALUE_PARSE_CAN_NOT_FIND_DEFAULT_CHAIN_WITH_TYPE; + } } } @@ -2274,7 +2258,7 @@ int dap_chain_node_cli_cmd_values_parse_net_chain_for_json(int *a_arg_index, int * @return */ int dap_chain_node_cli_cmd_values_parse_net_chain(int *a_arg_index, int a_argc, char **a_argv, void **a_str_reply, - dap_chain_t **a_chain, dap_chain_net_t **a_net) + dap_chain_t **a_chain, dap_chain_net_t **a_net, dap_chain_type_t a_default_chain_type) { const char * l_chain_str = NULL; const char * l_net_str = NULL; @@ -2326,15 +2310,13 @@ int dap_chain_node_cli_cmd_values_parse_net_chain(int *a_arg_index, int a_argc, dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_to_reply); return -103; } - } - else if ( !strcmp(a_argv[0], "token_decl") - || !strcmp(a_argv[0], "token_decl_sign")) { - if ( (*a_chain = dap_chain_net_get_default_chain_by_chain_type(*a_net, CHAIN_TYPE_TOKEN)) == NULL ) - { - dap_cli_server_cmd_set_reply_text(a_str_reply, - "%s requires parameter '-chain' or set default datum type in chain configuration file", - a_argv[0]); - return -105; + } else if (a_default_chain_type != CHAIN_TYPE_INVALID) { + if ((*a_chain = dap_chain_net_get_default_chain_by_chain_type(*a_net, a_default_chain_type)) != NULL) { + return 0; + } else { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Unable to get the default chain of type %s for the network.", + dap_chain_type_to_str(a_default_chain_type)); + return -104; } } else { dap_cli_server_cmd_set_reply_text(a_str_reply, "%s requires parameter '-chain'", a_argv[0]); @@ -2426,7 +2408,8 @@ int com_token_decl_sign(int a_argc, char **a_argv, void **a_str_reply) dap_chain_t * l_chain = NULL; dap_chain_net_t * l_net = NULL; - dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, a_argc, a_argv, a_str_reply, &l_chain, &l_net); + dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, a_argc, a_argv, a_str_reply, &l_chain, &l_net, + CHAIN_TYPE_TOKEN); if(!l_net) return -1; else { @@ -2488,7 +2471,7 @@ int com_token_decl_sign(int a_argc, char **a_argv, void **a_str_reply) l_datum_token->signs_total = 0; for (i = 1; i <= l_tmp_signs_total; i++){ dap_sign_t *l_sign = (dap_sign_t *)(l_datum_token->data_n_tsd + l_tsd_size + l_signs_size); - if( dap_sign_verify(l_sign, l_datum_token, sizeof(*l_datum_token) + l_tsd_size) != 1) { + if( dap_sign_verify(l_sign, l_datum_token, sizeof(*l_datum_token) + l_tsd_size) ) { log_it(L_WARNING, "Wrong signature %zu for datum_token with key %s in mempool!", i, l_datum_hash_out_str); dap_cli_server_cmd_set_reply_text(a_str_reply, "Datum %s with datum token has wrong signature %zu, break process and exit", @@ -2623,7 +2606,7 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a size_t l_objs_count = 0; dap_global_db_obj_t * l_objs = dap_global_db_get_all_sync(l_gdb_group_mempool, &l_objs_count); json_object *l_jobj_datums; - size_t l_offset = a_limit * a_offset; + size_t l_offset = a_offset; if (l_objs_count == 0 || l_objs_count < l_offset) { l_jobj_datums = json_object_new_null(); } else { @@ -2741,7 +2724,7 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *) l_datum->data; int l_ledger_rc = DAP_LEDGER_TX_CHECK_NULL_TX; - const char *l_main_ticker = dap_ledger_tx_get_main_ticker(a_net->pub.ledger, l_tx, + const char *l_main_ticker = dap_ledger_tx_calculate_main_ticker(a_net->pub.ledger, l_tx, &l_ledger_rc); char *l_ledger_rc_str = dap_ledger_tx_check_err_str(l_ledger_rc); @@ -2928,7 +2911,7 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a dap_json_rpc_allocation_error; return; } - char *l_value_coins_str, *l_value_str = dap_uint256_to_char(l_value, &l_value_coins_str); + const char *l_value_coins_str, *l_value_str = dap_uint256_to_char(l_value, &l_value_coins_str); json_object_object_add(l_jobj_money, "value", json_object_new_string(l_value_str)); json_object_object_add(l_jobj_money, "coins", json_object_new_string(l_value_coins_str)); if (l_dist_token) { @@ -3090,11 +3073,11 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a if (l_wallet_addr && l_emi && dap_chain_addr_compare(l_wallet_addr, &l_emi->hdr.address)) datum_is_accepted_addr = true; DAP_DELETE(l_emi); - json_object_object_add(l_jobj_datum, "data", dap_chain_datum_data_to_json(l_datum)); + dap_chain_datum_dump_json(l_jobj_datum,l_datum,a_hash_out_type,a_net->pub.id); } break; default: - json_object_object_add(l_jobj_datum, "data", dap_chain_datum_data_to_json(l_datum)); + dap_chain_datum_dump_json(l_jobj_datum,l_datum,a_hash_out_type,a_net->pub.id); } } if (l_wallet_addr) { @@ -3340,8 +3323,10 @@ int _cmd_mempool_check(dap_chain_net_t *a_net, dap_chain_t *a_chain, const char json_object_object_add(l_obj_atom, "hash", l_jobj_atom_hash); json_object_object_add(l_obj_atom, "ledger_response_code", l_jobj_atom_err); json_object_object_add(l_jobj_datum, "atom", l_obj_atom); - } - json_object *l_datum_obj_inf = dap_chain_datum_to_json(l_datum); + } + + json_object *l_datum_obj_inf = json_object_new_object(); + dap_chain_datum_dump_json(l_datum_obj_inf, l_datum, a_hash_out_type, a_net->pub.id); if (!l_datum_obj_inf) { if (!l_found_in_chains) DAP_DELETE(l_datum); @@ -3350,6 +3335,7 @@ int _cmd_mempool_check(dap_chain_net_t *a_net, dap_chain_t *a_chain, const char "Failed to serialize datum to JSON."); return DAP_JSON_RPC_ERR_CODE_SERIALIZATION_DATUM_TO_JSON; } + json_object_object_add(l_jobj_datum, "datum", l_datum_obj_inf); if (!l_found_in_chains) DAP_DELETE(l_datum); json_object_array_add(*a_json_reply, l_jobj_datum); @@ -3638,15 +3624,12 @@ int _cmd_mempool_dump_from_group(dap_chain_net_id_t a_net_id, const char *a_grou return COM_DUMP_ERROR_LIST_CORRUPTED_SIZE; } if (!l_datum) { - char *l_msg_str = dap_strdup_printf("Error! Can't find datum %s in %s", a_datum_hash, a_group_gdb); - if (!l_msg_str) { - dap_json_rpc_allocation_error; - return -1; - } - json_object *l_jobj_message = json_object_new_string(l_msg_str); + dap_json_rpc_error_add(COM_DUMP_ERROR_LIST_CORRUPTED_SIZE, "Error! Can't find datum %s in %s", a_datum_hash, a_group_gdb); return COM_DUMP_ERROR_CAN_NOT_FIND_DATUM; } - json_object *l_jobj_datum = dap_chain_datum_to_json(l_datum); + + json_object *l_jobj_datum = json_object_new_object(); + dap_chain_datum_dump_json(l_jobj_datum, l_datum, a_hash_out_type, a_net_id); json_object_array_add(*a_json_reply, l_jobj_datum); return 0; } @@ -3683,7 +3666,8 @@ int com_mempool(int a_argc, char **a_argv, void **a_str_reply) int arg_index = 1; dap_chain_net_t *l_net = NULL; dap_chain_t *l_chain = NULL; - enum _subcmd {SUBCMD_LIST, SUBCMD_PROC, SUBCMD_PROC_ALL, SUBCMD_DELETE, SUBCMD_ADD_CA, SUBCMD_CHECK, SUBCMD_DUMP}; + enum _subcmd {SUBCMD_LIST, SUBCMD_PROC, SUBCMD_PROC_ALL, SUBCMD_DELETE, SUBCMD_ADD_CA, SUBCMD_CHECK, SUBCMD_DUMP, + SUBCMD_COUNT}; enum _subcmd l_cmd = 0; if (a_argv[1]) { if (!dap_strcmp(a_argv[1], "list")) { @@ -3700,8 +3684,10 @@ int com_mempool(int a_argc, char **a_argv, void **a_str_reply) l_cmd = SUBCMD_DUMP; } else if (!dap_strcmp(a_argv[1], "check")) { l_cmd = SUBCMD_CHECK; + } else if (!dap_strcmp(a_argv[1], "count")) { + l_cmd = SUBCMD_COUNT; } else { - char *l_str_err = dap_strdup_printf("Invalid sub command specified. Ыub command %s " + char *l_str_err = dap_strdup_printf("Invalid sub command specified. Sub command %s " "is not supported.", a_argv[1]); if (!l_str_err) { dap_json_rpc_allocation_error; @@ -3717,7 +3703,7 @@ int com_mempool(int a_argc, char **a_argv, void **a_str_reply) return -2; } } - dap_chain_node_cli_cmd_values_parse_net_chain_for_json(&arg_index, a_argc, a_argv, &l_chain, &l_net); + dap_chain_node_cli_cmd_values_parse_net_chain_for_json(&arg_index, a_argc, a_argv, &l_chain, &l_net, CHAIN_TYPE_INVALID); const char *l_hash_out_type = "hex"; dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-H", &l_hash_out_type); const char *l_datum_hash_in = NULL; @@ -3771,7 +3757,7 @@ int com_mempool(int a_argc, char **a_argv, void **a_str_reply) const char *l_limit_str = NULL, *l_offset_str = NULL; dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-limit", &l_limit_str); dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-offset", &l_offset_str); - l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 0; + l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 1000; l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0; if(l_chain) { s_com_mempool_list_print_for_chain(l_net, l_chain, l_wallet_addr, l_jobj_chains, l_hash_out_type, l_fast, l_limit, l_offset); @@ -3823,6 +3809,72 @@ int com_mempool(int a_argc, char **a_argv, void **a_str_reply) case SUBCMD_DUMP: { ret = _cmd_mempool_dump(l_net, l_chain, l_datum_hash, l_hash_out_type, a_json_reply); } break; + case SUBCMD_COUNT: { + char *l_mempool_group; + json_object *obj_ret = json_object_new_object(); + json_object *obj_net = json_object_new_string(l_net->pub.name); + if (!obj_ret || !obj_net) { + json_object_put(obj_ret); + json_object_put(obj_net); + dap_json_rpc_allocation_error; + return DAP_JSON_RPC_ERR_CODE_MEMORY_ALLOCATED; + } + json_object_object_add(obj_ret, "net", obj_net); + json_object *l_jobj_chains = json_object_new_array(); + if (!l_jobj_chains) { + json_object_put(obj_ret); + dap_json_rpc_allocation_error; + return DAP_JSON_RPC_ERR_CODE_MEMORY_ALLOCATED; + } + if(l_chain) { + l_mempool_group = dap_chain_net_get_gdb_group_mempool_new(l_chain); + size_t l_objs_count = 0; + dap_global_db_obj_t *l_objs = dap_global_db_get_all_sync(l_mempool_group, &l_objs_count); + dap_global_db_objs_delete(l_objs, l_objs_count); + DAP_DELETE(l_mempool_group); + json_object *l_jobj_chain = json_object_new_object(); + json_object *l_jobj_chain_name = json_object_new_string(l_chain->name); + json_object *l_jobj_count = json_object_new_uint64(l_objs_count); + if (!l_jobj_chain || !l_jobj_chain_name || !l_jobj_count) { + json_object_put(l_jobj_chains); + json_object_put(l_jobj_chain); + json_object_put(l_jobj_chain_name); + json_object_put(l_jobj_count); + json_object_put(obj_ret); + dap_json_rpc_allocation_error; + return DAP_JSON_RPC_ERR_CODE_MEMORY_ALLOCATED; + } + json_object_object_add(l_jobj_chain, "name", l_jobj_chain_name); + json_object_object_add(l_jobj_chain, "count", l_jobj_count); + json_object_array_add(l_jobj_chains, l_jobj_chain); + } else { + DL_FOREACH(l_net->pub.chains, l_chain) { + l_mempool_group = dap_chain_net_get_gdb_group_mempool_new(l_chain); + size_t l_objs_count = 0; + dap_global_db_obj_t *l_objs = dap_global_db_get_all_sync(l_mempool_group, &l_objs_count); + dap_global_db_objs_delete(l_objs, l_objs_count); + DAP_DELETE(l_mempool_group); + json_object *l_jobj_chain = json_object_new_object(); + json_object *l_jobj_chain_name = json_object_new_string(l_chain->name); + json_object *l_jobj_count = json_object_new_uint64(l_objs_count); + if (!l_jobj_chain || !l_jobj_chain_name || !l_jobj_count) { + json_object_put(l_jobj_chains); + json_object_put(l_jobj_chain); + json_object_put(l_jobj_chain_name); + json_object_put(l_jobj_count); + json_object_put(obj_ret); + dap_json_rpc_allocation_error; + return DAP_JSON_RPC_ERR_CODE_MEMORY_ALLOCATED; + } + json_object_object_add(l_jobj_chain, "name", l_jobj_chain_name); + json_object_object_add(l_jobj_chain, "count", l_jobj_count); + json_object_array_add(l_jobj_chains, l_jobj_chain); + } + } + json_object_object_add(obj_ret, "chains", l_jobj_chains); + json_object_array_add(*a_json_reply, obj_ret); + ret = 0; + } break; } DAP_DEL_Z(l_datum_hash); return ret; @@ -3914,7 +3966,8 @@ static int s_parse_common_token_decl_arg(int a_argc, char ** a_argv, void **a_st } int l_arg_index = 0; - int l_res = dap_chain_node_cli_cmd_values_parse_net_chain(&l_arg_index, a_argc, a_argv, a_str_reply, &a_params->chain, &a_params->net); + int l_res = dap_chain_node_cli_cmd_values_parse_net_chain(&l_arg_index, a_argc, a_argv, a_str_reply, + &a_params->chain, &a_params->net, CHAIN_TYPE_TOKEN); if(!a_params->net || !a_params->chain) return l_res; @@ -4096,8 +4149,7 @@ static int s_parse_additional_token_decl_arg(int a_argc, char ** a_argv, void ** DAP_DEL_Z(l_new_certs); } if (l_description_token) { - dap_tsd_t *l_desc_token = dap_tsd_create(DAP_CHAIN_DATUM_TOKEN_TSD_TOKEN_DESCRIPTION, l_description_token, - dap_strlen(l_description_token));//dap_tsd_create_string(DAP_CHAIN_DATUM_TOKEN_TSD_TOKEN_DESCRIPTION, l_description_token); + dap_tsd_t *l_desc_token = dap_tsd_create_string(DAP_CHAIN_DATUM_TOKEN_TSD_TOKEN_DESCRIPTION, l_description_token); l_tsd_list = dap_list_append(l_tsd_list, l_desc_token); l_tsd_total_size += dap_tsd_size(l_desc_token); a_params->ext.parsed_tsd_size += dap_tsd_size(l_desc_token); @@ -4301,6 +4353,12 @@ int com_token_decl(int a_argc, char ** a_argv, void **a_str_reply) DAP_DEL_Z(l_params); return -91; } + if (!dap_strcmp(l_ticker, l_params->ext.delegated_token_from)) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Delegated token ticker cannot match the original ticker"); + DAP_DEL_Z(l_params); + return -92; + } + dap_chain_datum_token_tsd_delegate_from_stake_lock_t l_tsd_section; strcpy((char *)l_tsd_section.ticker_token_from, l_params->ext.delegated_token_from); // l_tsd_section.token_from = dap_hash_fast(); @@ -4754,7 +4812,7 @@ int com_token_emit(int a_argc, char **a_argv, void **a_str_reply) return -1; } - dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index,a_argc,a_argv,a_str_reply,NULL, &l_net); + dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index,a_argc,a_argv,a_str_reply,NULL, &l_net, CHAIN_TYPE_INVALID); if( ! l_net) { // Can't find such network return -43; } @@ -5725,7 +5783,7 @@ int com_chain_ca_pub( int a_argc, char ** a_argv, void **a_str_reply) dap_chain_t * l_chain = NULL; dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-ca_name", &l_ca_name); - dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index,a_argc, a_argv, a_str_reply, &l_chain, &l_net); + dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index,a_argc, a_argv, a_str_reply, &l_chain, &l_net, CHAIN_TYPE_CA); dap_cert_t * l_cert = dap_cert_find_by_name( l_ca_name ); if( l_cert == NULL ){ @@ -6018,7 +6076,6 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **reply) } l_tx->header.ts_created = time(NULL); size_t l_items_ready = 0; - size_t l_receipt_count = 0; dap_list_t *l_sign_list = NULL;// list 'sing' items dap_list_t *l_in_list = NULL;// list 'in' items dap_list_t *l_tsd_list = NULL;// list tsd sections @@ -6316,9 +6373,7 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **reply) size_t l_params_size = dap_strlen(l_params_str); dap_chain_datum_tx_receipt_t *l_receipt = dap_chain_datum_tx_receipt_create(l_srv_uid, l_price_unit, l_units, l_value, l_params_str, l_params_size); l_item = (const uint8_t*) l_receipt; - if(l_item) - l_receipt_count++; - else { + if (!l_item) { char *l_str_err = dap_strdup_printf("Unable to create receipt out for transaction " "described by item %zu.", i); json_object *l_jobj_err = json_object_new_string(l_str_err); @@ -6828,10 +6883,21 @@ int com_tx_create(int a_argc, char **a_argv, void **reply) 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_DELETE(l_addr_to); + dap_chain_wallet_close(l_wallet); + dap_enc_key_delete(l_priv_key); 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 (addr_from && dap_chain_addr_compare(l_addr_to, addr_from)) { + DAP_DELETE(l_addr_to); + dap_chain_wallet_close(l_wallet); + dap_enc_key_delete(l_priv_key); + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_CREATE_EQ_SOURCE_DESTINATION_ADDRESS, "The transaction cannot be directed to the same address as the source."); + return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_EQ_SOURCE_DESTINATION_ADDRESS; + } + if (l_addr_to->net_id.uint64 != l_net->pub.id.uint64 && !dap_chain_addr_is_blank(l_addr_to)) { bool l_found = false; for (dap_list_t *it = l_net->pub.bridged_networks; it; it = it->next) { @@ -6911,7 +6977,8 @@ int com_tx_verify(int a_argc, char **a_argv, void **reply) 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_for_json(&l_arg_index, a_argc, a_argv, &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, + CHAIN_TYPE_INVALID); if (!l_net || !l_chain) { return DAP_CHAIN_NODE_CLI_COM_TX_VERIFY_NET_CHAIN_UNDEFINED; } @@ -6986,6 +7053,8 @@ int com_tx_history(int a_argc, char ** a_argv, void **a_str_reply) const char *l_net_str = NULL; const char *l_chain_str = NULL; const char *l_tx_hash_str = NULL; + const char *l_tx_srv_str = NULL; + const char *l_tx_act_str = NULL; const char *l_limit_str = NULL; const char *l_offset_str = NULL; @@ -7008,6 +7077,18 @@ int com_tx_history(int a_argc, char ** a_argv, void **a_str_reply) dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-net", &l_net_str); dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-chain", &l_chain_str); dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-tx", &l_tx_hash_str); + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-srv", &l_tx_srv_str); + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-act", &l_tx_act_str); + + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-limit", &l_limit_str); + dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-offset", &l_offset_str); + size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 1000; + size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0; + + //default is ALL/ANY + dap_chain_tx_tag_action_type_t l_action = dap_ledger_tx_action_str_to_action_t(l_tx_act_str); + + bool l_brief = (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "-brief") != -1) ? true : false; bool l_is_tx_all = dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-all", NULL); @@ -7053,7 +7134,15 @@ int com_tx_history(int a_argc, char ** a_argv, void **a_str_reply) "Wallet address not recognized"); return DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_WALLET_ADDR_ERR; } - l_net = dap_chain_net_by_id(l_addr->net_id); + if (l_net) { + if (l_net->pub.id.uint64 != l_addr->net_id.uint64) { + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_ID_NET_ADDR_DIF_ERR, + "Network ID with '-net' param and network ID with '-addr' param are different"); + DAP_DELETE(l_addr); + return DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_ID_NET_ADDR_DIF_ERR; + } + } else + l_net = dap_chain_net_by_id(l_addr->net_id); } if (l_wallet_name) { const char *c_wallets_path = dap_chain_wallet_get_path(g_config); @@ -7110,35 +7199,29 @@ int com_tx_history(int a_argc, char ** a_argv, void **a_str_reply) } } else if (l_addr) { // history addr and wallet - dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-limit", &l_limit_str); - dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-offset", &l_offset_str); - size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 0; - size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0; - json_obj_out = dap_db_history_addr(l_addr, l_chain, l_hash_out_type, dap_chain_addr_to_str(l_addr), l_limit, l_offset); + json_object * json_obj_summary = json_object_new_object(); + if (!json_obj_summary) { + return DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_MEMORY_ERR; + } + json_obj_out = dap_db_history_addr(l_addr, l_chain, l_hash_out_type, dap_chain_addr_to_str(l_addr), json_obj_summary, l_limit, l_offset, l_brief, l_tx_srv_str, l_action); if (!json_obj_out) { dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_DAP_DB_HISTORY_ADDR_ERR, "something went wrong in tx_history"); + json_object_put(json_obj_summary); return DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_DAP_DB_HISTORY_ADDR_ERR; - } - + } + json_object_array_add(*json_arr_reply, json_obj_out); + json_object_array_add(*json_arr_reply, json_obj_summary); + return DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_OK; } else if (l_is_tx_all) { // history all - const char * l_brief_type = NULL; - bool l_brief_out = false; - if (dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-brief", &l_brief_type)) - l_brief_out = true; - - json_object * json_obj_summary = json_object_new_object(); if (!json_obj_summary) { return DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_MEMORY_ERR; } - dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-limit", &l_limit_str); - dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-offset", &l_offset_str); - size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 0; - size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0; + json_object* json_arr_history_all = dap_db_history_tx_all(l_chain, l_net, l_hash_out_type, json_obj_summary, - l_limit, l_offset, l_brief_out); + l_limit, l_offset, l_brief, l_tx_srv_str, l_action); if (!json_arr_history_all) { dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_DAP_DB_HISTORY_ALL_ERR, "something went wrong in tx_history"); @@ -7609,7 +7692,7 @@ int cmd_remove(int a_argc, char **a_argv, void **a_str_reply) if (NULL == l_gdb_path) l_net_returns = s_go_all_nets_offline(); for (dap_chain_net_t *it = dap_chain_net_iter_start(); it; it = dap_chain_net_iter_next(it)) { - s_dap_chain_net_purge(it); + dap_chain_net_purge(it); } if (!error) successful |= REMOVED_CHAINS; @@ -7620,7 +7703,7 @@ int cmd_remove(int a_argc, char **a_argv, void **a_str_reply) } else { error |= NET_NOT_VALID; } - s_dap_chain_net_purge(l_net); + dap_chain_net_purge(l_net); if (!error) successful |= REMOVED_CHAINS; @@ -8066,7 +8149,6 @@ static int s_sign_file(const char *a_filename, dap_sign_signer_file_t a_flags, c { uint32_t l_shift = 1; int l_count_meta = 0; - int l_index_meta = 0; char *l_buffer = NULL; if (a_flags == SIGNER_ALL_FLAGS) { @@ -8095,7 +8177,6 @@ static int s_sign_file(const char *a_filename, dap_sign_signer_file_t a_flags, c dap_tsd_t *l_item = s_alloc_metadata(a_filename, l_shift & a_flags); if (l_item) { l_std_list = dap_list_append(l_std_list, l_item); - l_index_meta++; } } l_shift <<= 1; diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c index 99fb3090a1118e6d809f778d4673ae649433a5c6..d90d2f12e96fd334d4b8b49a4a678cfa766bdbbb 100644 --- a/modules/net/dap_chain_node_cli_cmd_tx.c +++ b/modules/net/dap_chain_node_cli_cmd_tx.c @@ -26,7 +26,7 @@ #include <stddef.h> #include <pthread.h> -#include "dap_chain_wallet.h" +#include "dap_cli_server.h" #include "dap_common.h" #include "dap_enc_base58.h" #include "dap_strfuncs.h" @@ -40,14 +40,14 @@ #include "dap_chain_datum_token.h" #include "dap_chain_datum_decree.h" #include "dap_chain_datum_tx_items.h" -#include "dap_chain_node_cli.h" +#include "dap_chain_datum_anchor.h" #include "dap_chain_node_cli_cmd_tx.h" #include "dap_chain_net_tx.h" +#include "dap_chain_net_decree.h" #include "dap_chain_mempool.h" #include "dap_math_convert.h" #include "dap_json_rpc_errors.h" -#include "dap_json_rpc_chain_datum_tx.h" #define LOG_TAG "chain_node_cli_cmd_tx" @@ -92,7 +92,7 @@ void s_dap_chain_tx_hash_processed_ht_free(dap_chain_tx_hash_processed_ht_t **l_ * @param l_tx_num */ -static bool s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, +bool s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, dap_ledger_t *a_ledger, json_object * json_obj_out, const char *a_hash_out_type, @@ -106,13 +106,16 @@ static bool s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, : NULL; if (!l_ticker) return false; + const char *l_description = dap_ledger_get_description_by_ticker(a_ledger, l_ticker); dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, l_ts_create); dap_chain_hash_fast_to_str(a_tx_hash,l_tx_hash_str,sizeof(l_tx_hash_str)); json_object_object_add(json_obj_out, "Datum_tx_hash", json_object_new_string(l_tx_hash_str)); json_object_object_add(json_obj_out, "TS_Created", json_object_new_string(l_tmp_buf)); json_object_object_add(json_obj_out, "Token_ticker", json_object_new_string(l_ticker)); - json_object* datum_tx = dap_chain_datum_tx_to_json(a_datum,&a_ledger->net->pub.id); - json_object_object_add(json_obj_out, "Datum_tx", datum_tx); + json_object_object_add(json_obj_out, "Token_description", l_description ? json_object_new_string(l_description) + : json_object_new_null()); + dap_chain_datum_dump_tx_json(a_datum, l_ticker, json_obj_out, a_hash_out_type, a_tx_hash, a_ledger->net->pub.id); + dap_list_t *l_out_items = dap_chain_datum_tx_items_get(a_datum, TX_ITEM_TYPE_OUT_ALL, NULL); int l_out_idx = 0; json_object* json_arr_items = json_object_new_array(); @@ -156,6 +159,7 @@ json_object * dap_db_tx_history_to_json(dap_chain_hash_fast_t* a_tx_hash, bool brief_out) { const char *l_tx_token_ticker = NULL; + const char *l_tx_token_description = NULL; json_object* json_obj_datum = json_object_new_object(); if (!json_obj_datum) { return NULL; @@ -165,6 +169,7 @@ json_object * dap_db_tx_history_to_json(dap_chain_hash_fast_t* a_tx_hash, l_tx_token_ticker = dap_ledger_tx_get_token_ticker_by_hash(l_ledger, a_tx_hash); if (l_tx_token_ticker) { json_object_object_add(json_obj_datum, "status", json_object_new_string("ACCEPTED")); + l_tx_token_description = dap_ledger_get_description_by_ticker(l_ledger, l_tx_token_ticker); *accepted_tx = true; } else { json_object_object_add(json_obj_datum, "status", json_object_new_string("DECLINED")); @@ -185,10 +190,27 @@ json_object * dap_db_tx_history_to_json(dap_chain_hash_fast_t* a_tx_hash, json_object_object_add(json_obj_datum, "token_ticker", l_tx_token_ticker ? json_object_new_string(l_tx_token_ticker) : json_object_new_null()); + json_object_object_add(json_obj_datum, "token_description", l_tx_token_description ? json_object_new_string(l_tx_token_description) + : json_object_new_null()); json_object_object_add(json_obj_datum, "ret_code", json_object_new_int(l_ret_code)); json_object_object_add(json_obj_datum, "ret_code_str", json_object_new_string(dap_ledger_tx_check_err_str(l_ret_code))); + dap_chain_net_srv_uid_t uid; + char *service_name; + dap_chain_tx_tag_action_type_t action; + + if (dap_ledger_tx_service_info(l_ledger, a_tx_hash, &uid, &service_name, &action)) + { + json_object_object_add(json_obj_datum, "service", json_object_new_string(service_name)); + json_object_object_add(json_obj_datum, "action", json_object_new_string(dap_ledger_tx_action_str(action))); + } + else + { + json_object_object_add(json_obj_datum, "service", json_object_new_string("UNKNOWN")); + json_object_object_add(json_obj_datum, "action", json_object_new_string("UNKNOWN")); + } + char l_time_str[DAP_TIME_STR_SIZE]; if (l_tx->header.ts_created) { dap_time_to_str_rfc822(l_time_str, DAP_TIME_STR_SIZE, l_tx->header.ts_created);/* Convert ts to "Sat May 17 01:17:08 2014\n" */ @@ -198,9 +220,8 @@ json_object * dap_db_tx_history_to_json(dap_chain_hash_fast_t* a_tx_hash, json_object_object_add(json_obj_datum, "tx_created", l_obj_ts_created); if(!brief_out) - { - json_object* datum_tx = dap_chain_datum_tx_to_json(l_tx,&a_chain->net_id); - json_object_object_add(json_obj_datum, "items", datum_tx); + { + dap_chain_datum_dump_tx_json(l_tx,NULL,json_obj_datum,a_hash_out_type,a_tx_hash,a_chain->net_id); } return json_obj_datum; @@ -277,6 +298,23 @@ static void s_tx_header_print(json_object* json_obj_datum, dap_chain_tx_hash_pro json_object_object_add(json_obj_datum, "atom_hash", json_object_new_string(l_atom_hash_str)); json_object_object_add(json_obj_datum, "ret_code", json_object_new_int(a_ret_code)); json_object_object_add(json_obj_datum, "ret_code_str", json_object_new_string(dap_ledger_tx_check_err_str(a_ret_code))); + + + dap_chain_net_srv_uid_t uid; + char *service_name; + dap_chain_tx_tag_action_type_t action; + + if (dap_ledger_tx_service_info(a_ledger, a_tx_hash, &uid, &service_name, &action)) + { + json_object_object_add(json_obj_datum, "service", json_object_new_string(service_name)); + json_object_object_add(json_obj_datum, "action", json_object_new_string(dap_ledger_tx_action_str(action))); + } + else + { + json_object_object_add(json_obj_datum, "service", json_object_new_string("UNKNOWN")); + json_object_object_add(json_obj_datum, "action", json_object_new_string("UNKNOWN")); + } + json_object_object_add(json_obj_datum, "tx_created", json_object_new_string(l_time_str)); DAP_DELETE(l_tx_hash_str); @@ -295,7 +333,8 @@ static void s_tx_header_print(json_object* json_obj_datum, dap_chain_tx_hash_pro * @return char* */ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain, - const char *a_hash_out_type, const char * l_addr_str, size_t a_limit, size_t a_offset) + const char *a_hash_out_type, const char * l_addr_str, json_object *json_obj_summary, + size_t a_limit, size_t a_offset, bool a_brief, const char *a_srv, dap_chain_tx_tag_action_type_t a_action) { json_object* json_obj_datum = json_object_new_array(); if (!json_obj_datum){ @@ -329,29 +368,48 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain, dap_chain_addr_t l_net_fee_addr = {}; bool l_net_fee_used = dap_chain_net_tx_get_fee(l_net->pub.id, NULL, &l_net_fee_addr); bool l_is_need_correction = false; - uint256_t l_corr_value = {}, l_unstake_value = {}; - json_object *l_corr_object = NULL; - - size_t - l_count = 0, - l_count_tx = 0; + uint256_t l_corr_value = {}, l_unstake_value = {}; + bool look_for_unknown_service = (a_srv && strcmp(a_srv,"unknown") == 0); + + json_object* json_obj_lim = json_object_new_object(); + size_t l_arr_start = 0; + if (a_offset){ + l_arr_start = a_offset; + json_object_object_add(json_obj_lim, "offset", json_object_new_int(l_arr_start)); + } + size_t l_arr_end = a_chain->callback_count_atom(a_chain); + if (a_limit) { + json_object_object_add(json_obj_lim, "limit", json_object_new_int(a_limit)); + l_arr_end = l_arr_start + a_limit; + size_t l_length = a_chain->callback_count_atom(a_chain); + if (l_arr_end > l_length) + l_arr_end = l_length; + } + json_object_array_add(json_obj_datum, json_obj_lim); + size_t i_tmp = 0; // load transactions dap_chain_datum_iter_t *l_datum_iter = a_chain->callback_datum_iter_create(a_chain); for (dap_chain_datum_t *l_datum = a_chain->callback_datum_iter_get_first(l_datum_iter); - l_datum && (a_limit ? l_count_tx < a_limit : true); + l_datum; l_datum = a_chain->callback_datum_iter_get_next(l_datum_iter)) { + json_object *l_corr_object = NULL; if (l_datum->header.type_id != DAP_CHAIN_DATUM_TX) // go to next datum - continue; - // it's a transaction + continue; + // it's a transaction bool l_is_unstake = false; dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)l_datum->data; dap_list_t *l_list_in_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_IN_ALL, NULL); if (!l_list_in_items) // a bad tx continue; // all in items should be from the same address + if (i_tmp >= l_arr_end || i_tmp < l_arr_start) { + i_tmp++; + continue; + } + i_tmp++; dap_chain_addr_t *l_src_addr = NULL; bool l_base_tx = false, l_reward_collect = false; const char *l_noaddr_token = NULL; @@ -421,7 +479,8 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain, } if (l_src_addr && !dap_chain_addr_compare(l_src_addr, a_addr)) break; //it's not our addr - } + + } dap_list_free(l_list_in_items); // find OUT items @@ -432,6 +491,8 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain, json_object * j_obj_tx = json_object_new_object(); if (!j_obj_tx || !j_arr_data) { dap_json_rpc_allocation_error; + json_object_put(j_obj_tx); + json_object_put(j_arr_data); return NULL; } if (!l_src_addr) { @@ -454,9 +515,14 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain, } } if (!l_dst_addr_present) + { + json_object_put(j_arr_data); + json_object_put(j_obj_tx); + dap_list_free(l_list_out_items); continue; + } } - bool l_count_bool = false; + for (dap_list_t *it = l_list_out_items; it; it = it->next) { dap_chain_addr_t *l_dst_addr = NULL; uint8_t l_type = *(uint8_t *)it->data; @@ -491,32 +557,55 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain, if (l_dst_addr && l_net_fee_used && dap_chain_addr_compare(&l_net_fee_addr, l_dst_addr)) SUM_256_256(l_fee_sum, l_value, &l_fee_sum); + + //tag + char *service_name = NULL; + dap_chain_tx_tag_action_type_t l_action; + bool srv_found = dap_ledger_tx_service_info(l_ledger, &l_tx_hash, NULL, &service_name, &l_action); + if (!(l_action & a_action)) + continue; + + if (a_srv) + { + + //skip if looking for UNKNOWN + it is known + if (look_for_unknown_service && srv_found) { + continue; + } + + //skip if search condition provided, it not UNKNOWN and found name not match + if (!look_for_unknown_service && (!srv_found || strcmp(service_name, a_srv) != 0)) + { + continue; + } + } + if (l_dst_addr && dap_chain_addr_compare(l_dst_addr, a_addr)) { - if (l_count++ < a_offset) - break; if (!l_header_printed) { s_tx_header_print(j_obj_tx, &l_tx_data_ht, l_tx, l_datum_iter->cur_atom_hash, a_hash_out_type, l_ledger, &l_tx_hash, l_datum_iter->ret_code); l_header_printed = true; } - char *l_src_str = NULL; + const char *l_src_str = NULL; if (l_base_tx) l_src_str = l_reward_collect ? "reward collecting" : "emission"; else if (l_src_addr && dap_strcmp(l_dst_token, l_noaddr_token)) l_src_str = dap_chain_addr_to_str(l_src_addr); else - l_src_str = (char*)dap_chain_tx_out_cond_subtype_to_str(l_src_subtype); + l_src_str = dap_chain_tx_out_cond_subtype_to_str(l_src_subtype); if (l_is_unstake) l_value = l_unstake_value; else if (!dap_strcmp(l_native_ticker, l_noaddr_token)) { l_is_need_correction = true; l_corr_value = l_value; } - char *l_coins_str, *l_value_str = dap_uint256_to_char(l_value, &l_coins_str); + const char *l_coins_str, *l_value_str = dap_uint256_to_char(l_value, &l_coins_str); + json_object *j_obj_data = json_object_new_object(); if (!j_obj_data) { dap_json_rpc_allocation_error; json_object_put(j_obj_tx); + json_object_put(j_arr_data); return NULL; } json_object_object_add(j_obj_data, "tx_type", json_object_new_string("recv")); @@ -529,14 +618,12 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain, l_corr_object = j_obj_data; else json_object_array_add(j_arr_data, j_obj_data); - l_count_bool = true; + } else if (!l_src_addr || dap_chain_addr_compare(l_src_addr, a_addr)) { if (!l_dst_addr && ((dap_chain_tx_out_cond_t *)it->data)->header.subtype == l_src_subtype && l_src_subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE) continue; if (!l_src_addr && l_dst_addr && !dap_chain_addr_compare(l_dst_addr, &l_net_fee_addr)) - continue; - if (l_count++ < a_offset) - break; + continue; if (!l_header_printed) { s_tx_header_print(j_obj_tx, &l_tx_data_ht, l_tx, l_datum_iter->cur_atom_hash, a_hash_out_type, l_ledger, &l_tx_hash, l_datum_iter->ret_code); @@ -546,11 +633,12 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain, const char *l_dst_addr_str = l_dst_addr ? dap_chain_addr_to_str(l_dst_addr) : dap_chain_tx_out_cond_subtype_to_str( ((dap_chain_tx_out_cond_t *)it->data)->header.subtype); - char *l_coins_str, *l_value_str = dap_uint256_to_char(l_value, &l_coins_str); + const char *l_coins_str, *l_value_str = dap_uint256_to_char(l_value, &l_coins_str); json_object * j_obj_data = json_object_new_object(); if (!j_obj_data) { dap_json_rpc_allocation_error; json_object_put(j_obj_tx); + json_object_put(j_arr_data); return NULL; } json_object_object_add(j_obj_data, "tx_type", json_object_new_string("send")); @@ -559,8 +647,7 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain, json_object_object_add(j_obj_data, "token", l_dst_token ? json_object_new_string(l_dst_token) : json_object_new_string("UNKNOWN")); json_object_object_add(j_obj_data, "destination_address", json_object_new_string(l_dst_addr_str)); - json_object_array_add(j_arr_data, j_obj_data); - l_count_bool = true; + json_object_array_add(j_arr_data, j_obj_data); } } if (json_object_array_length(j_arr_data) > 0) { @@ -568,9 +655,9 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain, json_object_array_add(json_obj_datum, j_obj_tx); } dap_list_free(l_list_out_items); - if (l_is_need_correction) { + if (l_is_need_correction && l_corr_object) { SUM_256_256(l_corr_value, l_fee_sum, &l_corr_value); - char *l_coins_str, *l_value_str = dap_uint256_to_char(l_corr_value, &l_coins_str); + const char *l_coins_str, *l_value_str = dap_uint256_to_char(l_corr_value, &l_coins_str); json_object_object_add(l_corr_object, "recv_coins", json_object_new_string(l_coins_str)); json_object_object_add(l_corr_object, "recv_datoshi", json_object_new_string(l_value_str)); if (!j_arr_data) { @@ -579,11 +666,11 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain, json_object_array_add(j_arr_data, l_corr_object); l_is_need_correction = false; } - l_count_tx += l_count_bool; } a_chain->callback_datum_iter_delete(l_datum_iter); // delete hashes s_dap_chain_tx_hash_processed_ht_free(&l_tx_data_ht); + // if no history if (json_object_array_length(json_obj_datum) == 1) { json_object * json_empty_tx = json_object_new_object(); @@ -592,15 +679,20 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain, json_object_put(json_obj_datum); return NULL; } - json_object_object_add(json_empty_tx, "status", json_object_new_string("empty")); + json_object_object_add(json_empty_tx, "status", json_object_new_string("empty")); json_object_array_add(json_obj_datum, json_empty_tx); - } + } + json_object_object_add(json_obj_summary, "network", json_object_new_string(l_net->pub.name)); + json_object_object_add(json_obj_summary, "chain", json_object_new_string(a_chain->name)); + json_object_object_add(json_obj_summary, "tx_sum", json_object_new_int(i_tmp)); return json_obj_datum; } json_object *dap_db_history_tx_all(dap_chain_t *l_chain, dap_chain_net_t *l_net, const char *l_hash_out_type, json_object *json_obj_summary, - size_t a_limit, size_t a_offset, bool out_brief) + size_t a_limit, size_t a_offset, bool out_brief, + const char *a_srv, + dap_chain_tx_tag_action_type_t a_action) { log_it(L_DEBUG, "Start getting tx from chain"); size_t @@ -613,23 +705,65 @@ json_object *dap_db_history_tx_all(dap_chain_t *l_chain, dap_chain_net_t *l_net, *l_cell_tmp = NULL; dap_chain_atom_iter_t *l_iter = NULL; json_object * json_arr_out = json_object_new_array(); + json_object* json_obj_lim = json_object_new_object(); + size_t l_arr_start = 0; + if (a_offset) { + l_arr_start = a_offset; + json_object_object_add(json_obj_lim, "offset", json_object_new_int(l_arr_start)); + } + size_t l_arr_end = l_chain->callback_count_atom(l_chain); + l_arr_end = a_limit ? l_arr_start + a_limit : l_arr_start + 1000; + json_object_object_add(json_obj_lim, "limit", json_object_new_int(l_arr_end - l_arr_start)); + json_object_array_add(json_arr_out, json_obj_lim); + if (l_arr_end > l_chain->callback_count_atom(l_chain)) { + l_arr_end = l_chain->callback_count_atom(l_chain); + } + + bool look_for_unknown_service = (a_srv && strcmp(a_srv,"unknown") == 0); + HASH_ITER(hh, l_chain->cells, l_cell, l_cell_tmp) { - if (a_limit && l_count_tx >= a_limit) + if (l_count_tx >= l_arr_end) break; l_iter = l_chain->callback_atom_iter_create(l_chain, l_cell->id, NULL, false); size_t l_atom_size = 0; dap_chain_atom_ptr_t l_ptr = l_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_FIRST, &l_atom_size); - while (l_ptr && l_atom_size && (a_limit ? l_count_tx < a_limit : true)) { + while (l_ptr && l_atom_size && (l_count_tx < l_arr_end)) { size_t l_datums_count = 0; dap_chain_datum_t **l_datums = l_cell->chain->callback_atom_get_datums(l_ptr, l_atom_size, &l_datums_count); - for (size_t i = 0; i < l_datums_count && (a_limit ? l_count_tx < a_limit : true); i++) { + for (size_t i = 0; i < l_datums_count && (l_count_tx < l_arr_end); i++) { if (l_datums[i]->header.type_id == DAP_CHAIN_DATUM_TX) { - if (l_count++ < a_offset) { + if (l_count_tx < l_arr_start) { + l_count_tx++; continue; } dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*)l_datums[i]->data; dap_hash_fast_t l_ttx_hash = {0}; dap_hash_fast(l_tx, l_datums[i]->header.data_size, &l_ttx_hash); + + char *service_name = NULL; + dap_chain_tx_tag_action_type_t l_action; + dap_ledger_t *l_ledger = l_net->pub.ledger; + bool srv_found = dap_ledger_tx_service_info(l_ledger, &l_ttx_hash, NULL, &service_name, &l_action); + + if (!(l_action & a_action)) + continue; + + if (a_srv) + { + char *service_name = NULL; + bool srv_found = dap_ledger_tx_service_info(l_ledger, &l_ttx_hash, NULL, &service_name, NULL); + //skip if looking for UNKNOWN + it is known + if (look_for_unknown_service && srv_found) { + continue; + } + + //skip if search condition provided, it not UNKNOWN and found name not match + if (!look_for_unknown_service && (!srv_found || strcmp(service_name, a_srv) != 0)) + { + continue; + } + } + bool accepted_tx; json_object* json_obj_datum = dap_db_tx_history_to_json(&l_ttx_hash, NULL, l_tx, l_chain, l_hash_out_type, l_net, 0, &accepted_tx, out_brief); if (!json_obj_datum) { @@ -642,8 +776,9 @@ json_object *dap_db_history_tx_all(dap_chain_t *l_chain, dap_chain_net_t *l_net, ++l_tx_ledger_rejected; } json_object_array_add(json_arr_out, json_obj_datum); - const char * debug_json_string = json_object_to_json_string(json_obj_datum); + //const char * debug_json_string = json_object_to_json_string(json_obj_datum); ++l_count_tx; + l_count++; } } DAP_DEL_Z(l_datums); @@ -655,7 +790,7 @@ json_object *dap_db_history_tx_all(dap_chain_t *l_chain, dap_chain_net_t *l_net, json_object_object_add(json_obj_summary, "network", json_object_new_string(l_net->pub.name)); json_object_object_add(json_obj_summary, "chain", json_object_new_string(l_chain->name)); - json_object_object_add(json_obj_summary, "tx_sum", json_object_new_int(l_count_tx)); + json_object_object_add(json_obj_summary, "tx_sum", json_object_new_int(l_count)); json_object_object_add(json_obj_summary, "accepted_tx", json_object_new_int(l_tx_ledger_accepted)); json_object_object_add(json_obj_summary, "rejected_tx", json_object_new_int(l_tx_ledger_rejected)); return json_arr_out; @@ -967,7 +1102,7 @@ int com_ledger(int a_argc, char ** a_argv, void **reply) 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, arg_index, a_argc, "-limit", &l_limit_str); dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-offset", &l_offset_str); - size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 0; + size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 1000; size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0; if (l_net_str == NULL){ dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_LEDGER_NET_PARAM_ERR, "Command 'list' requires key -net"); diff --git a/modules/net/dap_chain_node_client.c b/modules/net/dap_chain_node_client.c index f83c08f57d84a831a9e33140696f064eb687b022..08fcc563b419df58372f26aafd4a3c438b3cdcc1 100644 --- a/modules/net/dap_chain_node_client.c +++ b/modules/net/dap_chain_node_client.c @@ -75,12 +75,6 @@ static void s_stage_connected_callback(dap_client_t *a_client, void *a_arg); static bool s_timer_update_states_callback(void *a_arg); static int s_node_client_set_notify_callbacks(dap_client_t *a_client, uint8_t a_ch_id); -static void s_ch_chain_callback_notify_packet_out(dap_chain_ch_t*, uint8_t a_pkt_type, - dap_chain_ch_pkt_t *a_pkt, size_t a_pkt_data_size, - void * a_arg); -static void s_ch_chain_callback_notify_packet_in(dap_chain_ch_t* a_ch_chain, uint8_t a_pkt_type, - dap_chain_ch_pkt_t *a_pkt, size_t a_pkt_data_size, - void * a_arg); /** * @brief dap_chain_node_client_init @@ -349,7 +343,7 @@ void dap_chain_node_client_close_unsafe(dap_chain_node_client_t *a_node_client) DAP_DELETE(a_node_client); } -void s_close_on_worker_callback(dap_worker_t UNUSED_ARG *a_worker, void *a_arg) +void s_close_on_worker_callback(void *a_arg) { assert(a_arg); dap_chain_node_client_close_unsafe(a_arg); diff --git a/modules/net/include/dap_chain_ledger.h b/modules/net/include/dap_chain_ledger.h index e9aca94a6d0314377b6f9d255622f66b6bfc360e..f39bee757e3a0be0ab49769d084d9b8c848bed22 100644 --- a/modules/net/include/dap_chain_ledger.h +++ b/modules/net/include/dap_chain_ledger.h @@ -37,6 +37,9 @@ #include "dap_chain_datum_tx_items.h" #include "dap_chain_net.h" +#define DAP_CHAIN_NET_SRV_TRANSFER_ID 0x07 +#define DAP_CHAIN_NET_SRV_BLOCK_REWARD_ID 0x08 + typedef struct dap_ledger { dap_chain_net_t *net; void *_internal; @@ -118,6 +121,27 @@ typedef enum dap_chan_ledger_notify_opcodes{ DAP_LEDGER_NOTIFY_OPCODE_ADDED = 'a', // 0x61 DAP_LEDGER_NOTIFY_OPCODE_DELETED = 'd', // 0x64 } dap_chan_ledger_notify_opcodes_t; +typedef enum dap_chain_tx_tag_action_type { + + //subtags, till 32 + DAP_CHAIN_TX_TAG_ACTION_UNKNOWN = 1 << 1, + + DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REGULAR = 1 << 2, + DAP_CHAIN_TX_TAG_ACTION_TRANSFER_COMISSION = 1 << 3, + DAP_CHAIN_TX_TAG_ACTION_TRANSFER_CROSSCHAIN = 1 << 4, + DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REWARD = 1 << 5, + + DAP_CHAIN_TX_TAG_ACTION_OPEN = 1 << 6, + DAP_CHAIN_TX_TAG_ACTION_USE = 1 << 7, + DAP_CHAIN_TX_TAG_ACTION_EXTEND = 1 << 8, + DAP_CHAIN_TX_TAG_ACTION_CHANGE = 1 << 9, + DAP_CHAIN_TX_TAG_ACTION_CLOSE = 1 << 10, + + + DAP_CHAIN_TX_TAG_ACTION_ALL = ~0, +} dap_chain_tx_tag_action_type_t; + + typedef struct dap_ledger_datum_iter { dap_chain_net_t *net; dap_chain_datum_tx_t *cur; @@ -131,10 +155,12 @@ typedef bool (*dap_ledger_verificator_callback_t)(dap_ledger_t *a_ledger, dap_ch typedef void (*dap_ledger_updater_callback_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_tx_out_cond_t *a_prev_cond); typedef void (* dap_ledger_tx_add_notify_t)(void *a_arg, dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chan_ledger_notify_opcodes_t a_opcode); typedef void (* dap_ledger_bridged_tx_notify_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, void *a_arg, dap_chan_ledger_notify_opcodes_t a_opcode); -typedef bool (*dap_ledger_cache_tx_check_callback_t)(dap_hash_fast_t *a_tx_hash); +typedef bool (*dap_ledger_cache_tx_check_callback_t)(dap_ledger_t *a_ledger, dap_hash_fast_t *a_tx_hash); typedef struct dap_chain_net dap_chain_net_t; typedef bool (*dap_chain_ledger_voting_callback_t)(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_type, dap_chain_datum_tx_t *a_tx, bool a_apply); typedef bool (*dap_chain_ledger_voting_delete_callback_t)(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_type, dap_chain_datum_tx_t *a_tx); +typedef bool (*dap_ledger_tag_check_callback_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_datum_tx_item_groups_t *a_items_grp, dap_chain_tx_tag_action_type_t *a_action); + //Change this UUID to automatically reload ledger cache on next node startup #define DAP_LEDGER_CACHE_RELOAD_ONCE_UUID "0c92b759-a565-448f-b8bd-99103dacf7fc" @@ -272,13 +298,34 @@ void dap_ledger_addr_get_token_ticker_all_depricated(dap_ledger_t *a_ledger, dap void dap_ledger_addr_get_token_ticker_all(dap_ledger_t *a_ledger, dap_chain_addr_t * a_addr, char *** a_tickers, size_t * a_tickers_size); +const char *dap_ledger_get_description_by_ticker(dap_ledger_t *a_ledger, const char *a_token_ticker); + bool dap_ledger_tx_poa_signed(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx); -// Checking a new transaction before adding to the cache -int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, - bool a_from_threshold, dap_list_t **a_list_bound_items, dap_list_t **a_list_tx_out, char **a_main_ticker, bool a_check_for_removing); +//TX service-tags +bool dap_ledger_deduct_tx_tag(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_net_srv_uid_t *uid, dap_chain_tx_tag_action_type_t *action); +const char *dap_ledger_tx_action_str(dap_chain_tx_tag_action_type_t a_tag); +dap_chain_tx_tag_action_type_t dap_ledger_tx_action_str_to_action_t(const char *a_str); -const char *dap_ledger_tx_get_main_ticker(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, int *a_ledger_rc); +bool dap_ledger_tx_service_info(dap_ledger_t *a_ledger, dap_hash_fast_t *a_tx_hash, + dap_chain_net_srv_uid_t *a_uid, char **a_service_name, dap_chain_tx_tag_action_type_t *a_action); + + +int dap_ledger_service_add(dap_chain_net_srv_uid_t a_uid, char *tag_str, dap_ledger_tag_check_callback_t a_callback); + + +// Checking a new transaction before adding to the cache +int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, + dap_chain_datum_tx_t *a_tx, + dap_hash_fast_t *a_tx_hash, + bool a_from_threshold, + dap_list_t **a_list_bound_items, + dap_list_t **a_list_tx_out, + char **a_main_ticker, + dap_chain_net_srv_uid_t *a_tag, + dap_chain_tx_tag_action_type_t *a_action, bool a_check_for_removing); + +const char *dap_ledger_tx_calculate_main_ticker(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, int *a_ledger_rc); /** * Delete all transactions from the cache @@ -379,3 +426,4 @@ void dap_ledger_bridged_tx_notify_add(dap_ledger_t *a_ledger, dap_ledger_bridged bool dap_ledger_cache_enabled(dap_ledger_t *a_ledger); void dap_ledger_set_cache_tx_check_callback(dap_ledger_t *a_ledger, dap_ledger_cache_tx_check_callback_t a_callback); +dap_chain_tx_out_cond_t* dap_chain_ledger_get_tx_out_cond_linked_to_tx_in_cond(dap_ledger_t *a_ledger, dap_chain_tx_in_cond_t *a_in_cond); diff --git a/modules/net/include/dap_chain_net.h b/modules/net/include/dap_chain_net.h index f2c77d3522bc61c9d9ef5966f7522ca2c8aca553..5c669c06e9484d2936ff31db25a8e62b688d2959 100644 --- a/modules/net/include/dap_chain_net.h +++ b/modules/net/include/dap_chain_net.h @@ -27,32 +27,24 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic #include <stdint.h> #include <string.h> -#include "dap_net.h" -#include "dap_time.h" #include "dap_math_ops.h" -#include "dap_stream_ch.h" #include "dap_strfuncs.h" #include "dap_string.h" #include "dap_list.h" #include "dap_chain_common.h" #include "dap_chain.h" #include "dap_chain_node.h" -#include "dap_chain_net_decree.h" -#include "dap_chain_net_tx.h" -#include "dap_chain_datum_decree.h" -#include "dap_chain_datum_anchor.h" -#include "dap_chain_datum_tx.h" -#include "uthash.h" -#include "dap_json_rpc.h" +#include "dap_global_db_cluster.h" +#include "dap_json_rpc_errors.h" #define DAP_CHAIN_NET_NAME_MAX 32 #define DAP_CHAIN_NET_MEMPOOL_TTL 48 // Hours -struct dap_chain_node_info; typedef struct dap_chain_node_client dap_chain_node_client_t; typedef struct dap_ledger dap_ledger_t; +typedef struct dap_chain_net_decree dap_chain_net_decree_t; -typedef enum dap_chain_net_state{ +typedef enum dap_chain_net_state { NET_STATE_OFFLINE = 0, NET_STATE_LINKS_PREPARE, NET_STATE_LINKS_CONNECTING, @@ -140,7 +132,6 @@ dap_chain_t *dap_chain_net_get_chain_by_id(dap_chain_net_t *l_net, dap_chain_id_ uint64_t dap_chain_net_get_cur_addr_int(dap_chain_net_t * l_net); dap_chain_cell_id_t * dap_chain_net_get_cur_cell( dap_chain_net_t * l_net); -const char* dap_chain_net_get_type(dap_chain_t *l_chain); // Get inintial authorized nodes pointed by config dap_chain_node_role_t dap_chain_net_get_role(dap_chain_net_t * a_net); @@ -158,6 +149,8 @@ void dap_chain_net_remove_last_reward(dap_chain_net_t *a_net); uint256_t dap_chain_net_get_reward(dap_chain_net_t *a_net, uint64_t a_block_num); int dap_chain_net_link_add(dap_chain_net_t *a_net, dap_stream_node_addr_t *a_addr, const char *a_host, uint16_t a_port); +void dap_chain_net_purge(dap_chain_net_t *l_net); + /** * @brief dap_chain_net_get_gdb_group_mempool * @param l_chain diff --git a/modules/net/include/dap_chain_net_decree.h b/modules/net/include/dap_chain_net_decree.h index 6628794128d91b4bbb9e0208fceafc633334346a..95b035c5650e961a774ba519e5672cf793716442 100644 --- a/modules/net/include/dap_chain_net_decree.h +++ b/modules/net/include/dap_chain_net_decree.h @@ -25,7 +25,7 @@ #include "dap_list.h" #include "dap_chain_net.h" -typedef struct decree_params { +typedef struct dap_chain_net_decree { dap_list_t *pkeys; uint16_t num_of_owners; uint16_t min_num_of_owners; diff --git a/modules/net/include/dap_chain_node.h b/modules/net/include/dap_chain_node.h index 2ee68992d839a99a6e19553f689722505feafa11..6426048417ebf5ea4846130fd009f5b48f9eaea9 100644 --- a/modules/net/include/dap_chain_node.h +++ b/modules/net/include/dap_chain_node.h @@ -24,11 +24,7 @@ #include <limits.h> #include "dap_common.h" #include "dap_list.h" -#include "dap_worker.h" -#include "dap_events_socket.h" -#include "dap_stream.h" #include "dap_chain_common.h" -#include "dap_global_db.h" #include "dap_chain.h" #include "dap_client.h" @@ -92,4 +88,4 @@ void dap_chain_node_mempool_process_all(dap_chain_t *a_chain, bool a_force); bool dap_chain_node_mempool_autoproc_init(); inline static void dap_chain_node_mempool_autoproc_deinit() {} dap_list_t *dap_chain_node_get_states_list_sort(dap_chain_net_t *a_net, dap_chain_node_addr_t *a_ignored, size_t a_ignored_count); -dap_string_t *dap_chain_node_states_info_read(dap_chain_net_t *a_net, dap_stream_node_addr_t a_addr); \ No newline at end of file +dap_string_t *dap_chain_node_states_info_read(dap_chain_net_t *a_net, dap_stream_node_addr_t a_addr); diff --git a/modules/net/include/dap_chain_node_cli_cmd.h b/modules/net/include/dap_chain_node_cli_cmd.h index a20814b648b5d3162caf984e0b69cce16eb58862..f3a2400fa28d45ae7b0f230ffe25f95bb8a336ae 100644 --- a/modules/net/include/dap_chain_node_cli_cmd.h +++ b/modules/net/include/dap_chain_node_cli_cmd.h @@ -33,11 +33,24 @@ int dap_chain_node_cli_cmd_values_parse_net_chain_for_json(int *a_arg_index, int a_argc, char **a_argv, - dap_chain_t **a_chain, dap_chain_net_t **a_net); + dap_chain_t **a_chain, dap_chain_net_t **a_net, + dap_chain_type_t a_default_chain_type); int dap_chain_node_cli_cmd_values_parse_net_chain(int *a_arg_index, int a_argc, char **a_argv, void **a_str_reply, - dap_chain_t ** a_chain, dap_chain_net_t ** a_net); + dap_chain_t ** a_chain, dap_chain_net_t ** a_net, dap_chain_type_t a_default_chain_type); + +typedef enum s_com_parse_net_chain_err{ + DAP_CHAIN_NODE_CLI_COM_PARSE_NET_NET_STR_ERR = 100, + DAP_CHAIN_NODE_CLI_COM_PARSE_NET_NET_PARAM_ERR, + DAP_CHAIN_NODE_CLI_COM_PARSE_NET_NOT_FOUND_ERR, + DAP_CHAIN_NODE_CLI_COM_PARSE_NET_CHAIN_PARAM_ERR, + + /* add custom codes here */ + + DAP_CHAIN_NODE_CLI_COM_PARSE_NET_UNKNOWN /* MAX */ +} s_com_parse_net_chain_err_t; + /** * global_db command @@ -159,7 +172,8 @@ typedef enum s_com_tx_create_err{ 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 + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_CAN_NOT_CREATE_TRANSACTION, + DAP_CHAIN_NODE_CLI_COM_TX_CREATE_EQ_SOURCE_DESTINATION_ADDRESS }s_com_tx_create_err_t; int com_tx_create(int a_argc, char **a_argv, void **a_str_reply); typedef enum s_com_tx_create_json_err { @@ -314,4 +328,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); \ No newline at end of file +int cmd_remove(int a_argc, char **a_argv, void **a_str_reply); diff --git a/modules/net/include/dap_chain_node_cli_cmd_tx.h b/modules/net/include/dap_chain_node_cli_cmd_tx.h index 54d784bd94952f9fd1e6581d87e7dce4c978c813..6bc3dd7582425a6c7628085b5c75da5c700a2f1a 100644 --- a/modules/net/include/dap_chain_node_cli_cmd_tx.h +++ b/modules/net/include/dap_chain_node_cli_cmd_tx.h @@ -25,8 +25,9 @@ #pragma once #include "dap_chain.h" +#include "dap_chain_ledger.h" #include "dap_chain_common.h" -#include "json.h" +#include "dap_chain_net.h" typedef struct dap_chain_tx_hash_processed_ht{ dap_chain_hash_fast_t hash; @@ -40,7 +41,10 @@ void s_dap_chain_tx_hash_processed_ht_free(dap_chain_tx_hash_processed_ht_t **l_ * return history json */ json_object * dap_db_history_tx(dap_chain_hash_fast_t* a_tx_hash, dap_chain_t * a_chain, const char *a_hash_out_type, dap_chain_net_t * l_net); -json_object * dap_db_history_addr(dap_chain_addr_t * a_addr, dap_chain_t * a_chain, const char *a_hash_out_type, const char * l_addr_str, size_t a_limit, size_t a_offset); +json_object * dap_db_history_addr(dap_chain_addr_t * a_addr, dap_chain_t * a_chain, const char *a_hash_out_type, const char * l_addr_str, json_object *json_obj_summary, size_t a_limit, size_t a_offset, +bool a_brief, +const char *a_srv, +dap_chain_tx_tag_action_type_t a_action); json_object * dap_db_tx_history_to_json(dap_chain_hash_fast_t* a_tx_hash, dap_hash_fast_t * l_atom_hash, dap_chain_datum_tx_t * l_tx, @@ -52,8 +56,17 @@ json_object * dap_db_tx_history_to_json(dap_chain_hash_fast_t* a_tx_hash, bool out_brief); json_object *dap_db_history_tx_all(dap_chain_t *l_chain, dap_chain_net_t *l_net, - const char *l_hash_out_type, json_object *json_obj_summary, - size_t a_limit, size_t a_offset, bool out_brief); + const char *l_hash_out_type, json_object *json_obj_summary, + size_t a_limit, size_t a_offset, bool out_brief, + const char *a_srv, + dap_chain_tx_tag_action_type_t a_action); + +bool s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, + dap_ledger_t *a_ledger, + json_object * json_obj_out, + const char *a_hash_out_type, + dap_chain_hash_fast_t *a_tx_hash); + /** * ledger command * diff --git a/modules/net/srv/dap_chain_net_srv.c b/modules/net/srv/dap_chain_net_srv.c index 8eb2b1fe5d1832f78c4ab271e77c7eb7e09bbdd1..cae9fe12202b1dddd1ef0ac74157ef4d06d239d8 100644 --- a/modules/net/srv/dap_chain_net_srv.c +++ b/modules/net/srv/dap_chain_net_srv.c @@ -129,7 +129,7 @@ void s_load_all() continue; // don't search in directories char l_full_path[MAX_PATH + 1] = {0}; - dap_snprintf(l_full_path, sizeof(l_full_path), "%s/%s", l_net_dir_str, l_dir_entry->d_name); + snprintf(l_full_path, sizeof(l_full_path), "%s/%s", l_net_dir_str, l_dir_entry->d_name); if(dap_dir_test(l_full_path)) { continue; } @@ -203,7 +203,8 @@ static int s_cli_net_srv( int argc, char **argv, void **a_str_reply) return 0; } - int l_ret = dap_chain_node_cli_cmd_values_parse_net_chain( &arg_index, argc, argv, a_str_reply, NULL, &l_net ); + int l_ret = dap_chain_node_cli_cmd_values_parse_net_chain( &arg_index, argc, argv, a_str_reply, NULL, &l_net, + CHAIN_TYPE_INVALID); if ( l_net ) { //char * l_orders_group = dap_chain_net_srv_order_get_gdb_group( l_net ); @@ -287,124 +288,118 @@ static int s_cli_net_srv( int argc, char **argv, void **a_str_reply) dap_string_append_printf(l_string_ret, "%s\n", l_string_err->str); dap_string_free(l_string_err, true); l_ret = -1; - } - // Update order - else if(!dap_strcmp(l_order_str, "update")) { - - if(!l_order_hash_str) { - l_ret = -1; - dap_string_append(l_string_ret, "Can't find option '-hash'\n"); - } - else { - dap_chain_net_srv_order_t * l_order = dap_chain_net_srv_order_find_by_hash_str(l_net, l_order_hash_hex_str); - if(!l_order) { - l_ret = -2; - if(!dap_strcmp(l_hash_out_type,"hex")) - dap_string_append_printf(l_string_ret, "Can't find order with hash %s\n", l_order_hash_hex_str); - else - dap_string_append_printf(l_string_ret, "Can't find order with hash %s\n", l_order_hash_base58_str); - } - else { - if(l_ext) { - l_order->ext_size = strlen(l_ext) + 1; - l_order = DAP_REALLOC(l_order, sizeof(dap_chain_net_srv_order_t) + l_order->ext_size); - memcpy(l_order->ext_n_sign, l_ext, l_order->ext_size); - } - else - dap_chain_net_srv_order_set_continent_region(&l_order, l_continent_num, l_region_str); - /*if(l_region_str) { - strncpy(l_order->region, l_region_str, dap_min(sizeof(l_order->region) - 1, strlen(l_region_str) + 1)); + } else if(!dap_strcmp(l_order_str, "update")) { + if (!l_order_hash_str) { + l_ret = -1; + dap_string_append(l_string_ret, "Can't find option '-hash'\n"); + } else { + dap_chain_net_srv_order_t * l_order = dap_chain_net_srv_order_find_by_hash_str(l_net, l_order_hash_hex_str); + if(!l_order) { + l_ret = -2; + if(!dap_strcmp(l_hash_out_type,"hex")) + dap_string_append_printf(l_string_ret, "Can't find order with hash %s\n", l_order_hash_hex_str); + else + dap_string_append_printf(l_string_ret, "Can't find order with hash %s\n", l_order_hash_base58_str); + } else { + if (l_ext) { + l_order->ext_size = strlen(l_ext) + 1; + l_order = DAP_REALLOC(l_order, sizeof(dap_chain_net_srv_order_t) + l_order->ext_size); + memcpy(l_order->ext_n_sign, l_ext, l_order->ext_size); + } else + dap_chain_net_srv_order_set_continent_region(&l_order, l_continent_num, l_region_str); + /*if(l_region_str) { + strncpy(l_order->region, l_region_str, dap_min(sizeof(l_order->region) - 1, strlen(l_region_str) + 1)); + } + if(l_continent_num>=0) + l_order->continent = l_continent_num;*/ + char *l_new_order_hash_str = dap_chain_net_srv_order_save(l_net, l_order, false); + if (l_new_order_hash_str) { + // delete prev order + if(dap_strcmp(l_new_order_hash_str, l_order_hash_hex_str)) + dap_chain_net_srv_order_delete_by_hash_str_sync(l_net, l_order_hash_hex_str); + DAP_DELETE(l_new_order_hash_str); + dap_string_append_printf(l_string_ret, "order updated\n"); + } else + dap_string_append_printf(l_string_ret, "Order did not updated\n"); + DAP_DELETE(l_order); } - if(l_continent_num>=0) - l_order->continent = l_continent_num;*/ - char *l_new_order_hash_str = dap_chain_net_srv_order_save(l_net, l_order, false); - if (l_new_order_hash_str) { - // delete prev order - if(dap_strcmp(l_new_order_hash_str, l_order_hash_hex_str)) - dap_chain_net_srv_order_delete_by_hash_str_sync(l_net, l_order_hash_hex_str); - DAP_DELETE(l_new_order_hash_str); - dap_string_append_printf(l_string_ret, "order updated\n"); - } else - dap_string_append_printf(l_string_ret, "Order did not updated\n"); - DAP_DELETE(l_order); } - } - - } - else if (!dap_strcmp( l_order_str, "find" )) { - + } else if (!dap_strcmp( l_order_str, "find" )) { // Order direction - const char *l_direction_str = NULL; - dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-direction", &l_direction_str); + const char *l_direction_str = NULL; + dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-direction", &l_direction_str); // Select with specified service uid - const char *l_srv_uid_str = NULL; - dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-srv_uid", &l_srv_uid_str); - + const char *l_srv_uid_str = NULL; + dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-srv_uid", &l_srv_uid_str); // Select with specified price units - const char* l_price_unit_str = NULL; - dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-price_unit", &l_price_unit_str); + const char* l_price_unit_str = NULL; + dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-price_unit", &l_price_unit_str); // Token ticker - const char* l_price_token_str = NULL; - dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-price_token", &l_price_token_str); + const char* l_price_token_str = NULL; + dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-price_token", &l_price_token_str); // Select with price not more than price_min - const char* l_price_min_str = NULL; - dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-price_min", &l_price_min_str); + const char* l_price_min_str = NULL; + dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-price_min", &l_price_min_str); // Select with price not more than price_max - const char* l_price_max_str = NULL; - dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-price_max", &l_price_max_str); - - dap_chain_net_srv_order_direction_t l_direction = SERV_DIR_UNDEFINED; - dap_chain_net_srv_uid_t l_srv_uid={{0}}; - uint256_t l_price_min = {}; - uint256_t l_price_max = {}; - dap_chain_net_srv_price_unit_uid_t l_price_unit={{0}}; - - if ( l_direction_str ){ - if (!strcmp(l_direction_str, "sell")) - l_direction = SERV_DIR_SELL; - else if (!strcmp(l_direction_str, "buy")) - l_direction = SERV_DIR_BUY; - else { - dap_string_free(l_string_ret, true); - dap_cli_server_cmd_set_reply_text(a_str_reply, "Wrong direction of the token was " - "specified, possible directions: buy, sell."); - return -18; + const char* l_price_max_str = NULL; + dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-price_max", &l_price_max_str); + + dap_chain_net_srv_order_direction_t l_direction = SERV_DIR_UNDEFINED; + dap_chain_net_srv_uid_t l_srv_uid={{0}}; + uint256_t l_price_min = {}; + uint256_t l_price_max = {}; + dap_chain_net_srv_price_unit_uid_t l_price_unit={{0}}; + + if ( l_direction_str ) { + if (!strcmp(l_direction_str, "sell")) + l_direction = SERV_DIR_SELL; + else if (!strcmp(l_direction_str, "buy")) + l_direction = SERV_DIR_BUY; + else { + dap_string_free(l_string_ret, true); + dap_cli_server_cmd_set_reply_text(a_str_reply, "Wrong direction of the token was " + "specified, possible directions: buy, sell."); + return -18; + } } - } - if (l_srv_uid_str && dap_id_uint64_parse(l_srv_uid_str ,&l_srv_uid.uint64)) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't recognize '%s' string as 64-bit id, hex or dec.", l_srv_uid_str); - return -21; - } - - if ( l_price_min_str ) - l_price_min = dap_chain_balance_scan(l_price_min_str); - - if ( l_price_max_str ) - l_price_max = dap_chain_balance_scan(l_price_max_str); - - l_price_unit.uint32 = dap_chain_srv_str_to_unit_enum(l_price_unit_str); + if (l_srv_uid_str && dap_id_uint64_parse(l_srv_uid_str ,&l_srv_uid.uint64)) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't recognize '%s' string as 64-bit id, hex or dec.", l_srv_uid_str); + return -21; + } - dap_list_t * l_orders; - size_t l_orders_num = 0; - if( dap_chain_net_srv_order_find_all_by( l_net, l_direction,l_srv_uid,l_price_unit,l_price_token_str,l_price_min, l_price_max,&l_orders,&l_orders_num) == 0 ){ - dap_string_append_printf(l_string_ret, "Found %zu orders:\n", l_orders_num); - for (dap_list_t *l_temp = l_orders;l_temp; l_temp = l_orders->next){ - dap_chain_net_srv_order_t *l_order =(dap_chain_net_srv_order_t *) l_temp->data; - dap_chain_net_srv_order_dump_to_string(l_order, l_string_ret, l_hash_out_type, l_net->pub.native_ticker); - dap_string_append(l_string_ret,"\n"); + if ( l_price_min_str ) + l_price_min = dap_chain_balance_scan(l_price_min_str); + + if ( l_price_max_str ) + l_price_max = dap_chain_balance_scan(l_price_max_str); + + l_price_unit.uint32 = dap_chain_srv_str_to_unit_enum(l_price_unit_str); + + dap_list_t *l_orders; + size_t l_orders_num = 0; + if( !dap_chain_net_srv_order_find_all_by(l_net, l_direction, l_srv_uid, + l_price_unit, l_price_token_str, + l_price_min, l_price_max, + &l_orders, &l_orders_num) ) + { + dap_string_append_printf(l_string_ret, "Found %zu orders:\n", l_orders_num); + for (dap_list_t *l_temp = l_orders; l_temp; l_temp = l_temp->next){ + dap_chain_net_srv_order_t *l_order = (dap_chain_net_srv_order_t*)l_temp->data; + dap_chain_net_srv_order_dump_to_string(l_order, l_string_ret, l_hash_out_type, l_net->pub.native_ticker); + dap_string_append(l_string_ret,"\n"); + } + l_ret = 0; + dap_list_free_full(l_orders, NULL); + } else { + l_ret = -5 ; + dap_string_append(l_string_ret,"Can't get orders: some internal error or wrong params\n"); } - l_ret = 0; - dap_list_free_full(l_orders, NULL); - }else{ - l_ret = -5 ; - dap_string_append(l_string_ret,"Can't get orders: some internal error or wrong params\n"); - } } else if(!dap_strcmp( l_order_str, "dump" )) { // Select with specified service uid if ( l_order_hash_str ){ @@ -558,31 +553,30 @@ static int s_cli_net_srv( int argc, char **argv, void **a_str_reply) dap_string_free(l_string_ret, true); return -19; } - } else { - dap_cli_server_cmd_set_reply_text(a_str_reply, "The certificate name was not " - "specified. Since version 5.2 it is not possible to " - "create unsigned orders."); - dap_string_free(l_string_ret, true); - return -20; - } + } else { + dap_cli_server_cmd_set_reply_text(a_str_reply, "The certificate name was not " + "specified. Since version 5.2 it is not possible to " + "create unsigned orders."); + dap_string_free(l_string_ret, true); + return -20; + } // create order - char * l_order_new_hash_str = dap_chain_net_srv_order_create( - l_net,l_direction, l_srv_uid, l_node_addr,l_tx_cond_hash, &l_price, l_price_unit, - l_price_token, l_expires, (uint8_t *)l_ext, l_ext_len, l_units, l_region_str, l_continent_num, l_key); - if(l_cert) - dap_cert_delete(l_cert); - if (l_order_new_hash_str) - dap_string_append_printf( l_string_ret, "Created order %s\n", l_order_new_hash_str); - else{ - dap_string_append_printf( l_string_ret, "Error! Can't created order\n"); - l_ret = -4; + char * l_order_new_hash_str = dap_chain_net_srv_order_create( + l_net,l_direction, l_srv_uid, l_node_addr,l_tx_cond_hash, &l_price, l_price_unit, + l_price_token, l_expires, (uint8_t *)l_ext, l_ext_len, l_units, l_region_str, l_continent_num, l_key); + if(l_cert) + dap_cert_delete(l_cert); + if (l_order_new_hash_str) + dap_string_append_printf( l_string_ret, "Created order %s\n", l_order_new_hash_str); + else { + dap_string_append_printf( l_string_ret, "Error! Can't created order\n"); + l_ret = -4; + } + } else { + dap_string_append_printf( l_string_ret, "Missed some required params\n"); + l_ret=-5; } - } else { - dap_string_append_printf( l_string_ret, "Missed some required params\n"); - l_ret=-5; - } - } - else if (l_order_str) { + } else if (l_order_str) { dap_string_append_printf(l_string_ret, "Unrecognized subcommand '%s'", l_order_str); l_ret = -14; } @@ -645,10 +639,7 @@ static int s_cli_net_srv( int argc, char **argv, void **a_str_reply) dap_string_free(l_string_ret, true); return -17; } - } - - return l_ret; } diff --git a/modules/net/srv/dap_chain_net_srv_order.c b/modules/net/srv/dap_chain_net_srv_order.c index bd072bd1cac5dfbeea1589ddade6bbf2dc77b077..e81bda4bd2797581d256366b80df284d4adbac97 100644 --- a/modules/net/srv/dap_chain_net_srv_order.c +++ b/modules/net/srv/dap_chain_net_srv_order.c @@ -558,7 +558,7 @@ void dap_chain_net_srv_order_dump_to_string(dap_chain_net_srv_order_t *a_order,d 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 ); - char *l_balance_coins, *l_balance = dap_uint256_to_char(a_order->price, &l_balance_coins); + const char *l_balance_coins, *l_balance = dap_uint256_to_char(a_order->price, &l_balance_coins); dap_string_append_printf(a_str_out, " price: %s (%s)\n", l_balance_coins, l_balance); dap_string_append_printf(a_str_out, " price_token: %s\n", (*a_order->price_ticker) ? a_order->price_ticker: a_native_ticker); dap_string_append_printf(a_str_out, " units: %zu\n", a_order->units); diff --git a/modules/net/srv/include/dap_chain_net_srv.h b/modules/net/srv/include/dap_chain_net_srv.h index 938efa969a2a03a43213839dff6d53dbc8685ded..c524cb3a91872d44780ed1e4f799d845fe01f0a1 100755 --- a/modules/net/srv/include/dap_chain_net_srv.h +++ b/modules/net/srv/include/dap_chain_net_srv.h @@ -27,9 +27,8 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic #include "dap_chain_net.h" #include "dap_chain_common.h" #include "dap_chain_datum_decree.h" -#include "dap_chain_wallet.h" +#include "dap_chain_datum_tx_receipt.h" #include "dap_common.h" -#include "dap_config.h" #include "dap_stream_ch.h" #include "dap_time.h" diff --git a/modules/net/srv/include/dap_chain_net_srv_order.h b/modules/net/srv/include/dap_chain_net_srv_order.h index 29906fce088c362056f327d459453de63cbaae6b..fe1c8031d5193d47fac54fdb987c87466813debd 100644 --- a/modules/net/srv/include/dap_chain_net_srv_order.h +++ b/modules/net/srv/include/dap_chain_net_srv_order.h @@ -106,7 +106,7 @@ int dap_chain_net_srv_order_find_all_by( dap_list_t** a_output_orders, size_t* a_output_orders_count); -int dap_chain_net_srv_order_delete_by_hash_str_sync( dap_chain_net_t * a_net,const char * a_hash_str ); +int dap_chain_net_srv_order_delete_by_hash_str_sync(dap_chain_net_t *a_net, const char *a_hash_str); /** * @brief dap_chain_net_srv_order_delete_by_hash diff --git a/modules/service/bridge/CMakeLists.txt b/modules/service/bridge/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..6c68b74fa5d2bc04e8b5506da10ed5ed7c7dcafb --- /dev/null +++ b/modules/service/bridge/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 3.10) +project (dap_chain_net_srv_bridge) + +file(GLOB DAP_SRV_BRG_SRCS *.c) + +file(GLOB DAP_SRV_BRG_HEADERS include/*.h) + +add_library(${PROJECT_NAME} STATIC ${DAP_SRV_BRG_SRCS} ${DAP_SRV_BRG_HEADERS}) + +target_include_directories(${PROJECT_NAME} INTERFACE .) +target_include_directories(${PROJECT_NAME} PUBLIC include) +target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_chain dap_chain_net dap_chain_net_srv) +target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../../dap-sdk/3rdparty/json-c) + +if (INSTALL_SDK) +set_target_properties(${PROJECT_NAME} PROPERTIES PUBLIC_HEADER "${DAP_SRV_BRG_HEADERS}") +INSTALL(TARGETS ${PROJECT_NAME} + LIBRARY DESTINATION lib/modules/service/bridge/ + ARCHIVE DESTINATION lib/modules/service/bridge/ + PUBLIC_HEADER DESTINATION include/modules/service/bridge/ +) +endif() \ No newline at end of file diff --git a/modules/service/bridge/dap_chain_net_srv_bridge.c b/modules/service/bridge/dap_chain_net_srv_bridge.c new file mode 100644 index 0000000000000000000000000000000000000000..439d0556d046e6b02be8511127dc2a2944e1a82c --- /dev/null +++ b/modules/service/bridge/dap_chain_net_srv_bridge.c @@ -0,0 +1,161 @@ +/* + * Authors: + * Roman Khlopkov <roman.khlopkov@demlabs.net> + * DeM Labs Inc. https://demlabs.net + * DeM Labs Open source community https://gitlab.demlabs.net + * Copyright (c) 2017-2020 + * All rights reserved. + + This file is part of DAP (Deus Applications Prototypes) the open source project + + DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + DAP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <math.h> +#include <pthread.h> +#include <stdbool.h> +#include "dap_chain_net.h" +#include "dap_chain_datum_tx.h" +#include "dap_chain_datum_tx_out_cond.h" +#include "dap_chain_datum_tx_sig.h" +#include "dap_list.h" +#include "dap_sign.h" +#include "dap_time.h" +#include "dap_chain_net_srv.h" +#include "dap_chain_ledger.h" +#include "dap_chain_node_cli.h" +#include "dap_common.h" +#include "dap_hash.h" +#include "dap_math_ops.h" +#include "dap_string.h" +#include "dap_chain_common.h" +#include "dap_chain_mempool.h" +#include "dap_chain_datum_decree.h" +#include "dap_tsd.h" +#include "dap_chain_net_tx.h" +#include "dap_chain_net_srv.h" +#include "dap_chain_net_srv_bridge.h" +#include "uthash.h" + +#define LOG_TAG "dap_chain_net_srv_bridge" + + +static inline int s_tsd_str_cmp(const byte_t *a_tsdata, size_t a_tsdsize, const char *str ) { + size_t l_strlen = (size_t)strlen(str); + if (l_strlen != a_tsdsize) return -1; + return memcmp(a_tsdata, str, l_strlen); +} + +//emission tags +//inherits from emission tsd section for engine-produced auth emissions +bool s_get_ems_bridge_action(dap_chain_datum_token_emission_t *a_ems, dap_chain_tx_tag_action_type_t *a_action) +{ + if (!a_ems || !a_action) + return false; + + if (a_action) + *a_action = DAP_CHAIN_TX_TAG_ACTION_UNKNOWN; + + size_t src_tsd_size = 0; + + src_tsd_size = 0; + size_t subsrc_tsd_size = 0; + + byte_t *ems_src = dap_chain_emission_get_tsd(a_ems, DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_SOURCE, &src_tsd_size); + byte_t *ems_subsrc = dap_chain_emission_get_tsd(a_ems, DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_SOURCE_SUBTYPE, &subsrc_tsd_size); + + if (ems_src && src_tsd_size) + { + //old bridge ems + if (s_tsd_str_cmp(ems_src, src_tsd_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_BRIDGE_COMMISSION_OLD) == 0) + { + *a_action = DAP_CHAIN_TX_TAG_ACTION_TRANSFER_COMISSION; + return true; + } + + //not bridge + if (s_tsd_str_cmp(ems_src, src_tsd_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_BRIDGE) != 0) + return false; + } + else + { + //special case for old bridge datums + //no SOURCE, but have all this + //if emission has 5, 8, 6 section (it's enough) -> this is old bridge tx + if (dap_chain_emission_get_tsd(a_ems, DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_NET_ID, &src_tsd_size) && + dap_chain_emission_get_tsd(a_ems, DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_BLOCK_NUM, &src_tsd_size) && + dap_chain_emission_get_tsd(a_ems, DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_OUTER_TX_HASH, &src_tsd_size)) + { + *a_action = DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REGULAR; + return true; + } + } + + if (ems_subsrc && subsrc_tsd_size) + { + if (s_tsd_str_cmp(ems_subsrc, subsrc_tsd_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_BRIDGE_COMMISSION)==0) + { + *a_action = DAP_CHAIN_TX_TAG_ACTION_TRANSFER_COMISSION; + return true; + } + + if (s_tsd_str_cmp(ems_subsrc, subsrc_tsd_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_BRIDGE_TRANSFER)==0) + { + *a_action = DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REGULAR; + return true; + } + + if (s_tsd_str_cmp(ems_subsrc, subsrc_tsd_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_BRIDGE_CROSSCHAIN)==0) + { + *a_action = DAP_CHAIN_TX_TAG_ACTION_TRANSFER_CROSSCHAIN; + return true; + } + } + return false; +} + + +static bool s_tag_check_bridge(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_datum_tx_item_groups_t *a_items_grp, dap_chain_tx_tag_action_type_t *a_action) +{ + //bridged native transfer: destination addr netid differs from net we get datum + //such tx are marked by TRANSFER service as CROSSCHAIN_TRANSFER + //bridge txs are only received one + + + //crosschain bridge AUTH emissions + + if (!a_items_grp->items_in_ems) + return false; + + dap_chain_tx_in_ems_t *l_tx_in_ems = a_items_grp->items_in_ems->data; + dap_hash_fast_t ems_hash = l_tx_in_ems->header.token_emission_hash; + dap_chain_datum_token_emission_t *l_emission = dap_ledger_token_emission_find(a_ledger, &ems_hash); + if(l_emission) + return s_get_ems_bridge_action(l_emission, a_action); + + return false; +} + +int dap_chain_net_srv_bridge_init() +{ + dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_BRIDGE_ID }; + dap_ledger_service_add(l_uid, "bridge", s_tag_check_bridge); + return 0; +} + +void dap_chain_net_srv_bridge_deinit() +{ + +} + diff --git a/modules/service/bridge/include/dap_chain_net_srv_bridge.h b/modules/service/bridge/include/dap_chain_net_srv_bridge.h new file mode 100644 index 0000000000000000000000000000000000000000..c5d9cb013f5577cef83c8a5c9ad24b0f70922195 --- /dev/null +++ b/modules/service/bridge/include/dap_chain_net_srv_bridge.h @@ -0,0 +1,5 @@ +#define DAP_CHAIN_NET_SRV_BRIDGE_ID 0x04 + +int dap_chain_net_srv_bridge_init(); + +void dap_chain_net_srv_bridge_deinit(); diff --git a/modules/service/datum/dap_chain_net_srv_datum.c b/modules/service/datum/dap_chain_net_srv_datum.c index 0132dbef97913fa24cbc0d380ee65d6546054dbd..83cb89b1ec6ac1fe10a797f5819b3ec22f1cd65f 100644 --- a/modules/service/datum/dap_chain_net_srv_datum.c +++ b/modules/service/datum/dap_chain_net_srv_datum.c @@ -38,6 +38,12 @@ static int s_srv_datum_cli(int argc, char ** argv, void **a_str_reply); void s_order_notficator(dap_store_obj_t *a_obj, void *a_arg); +static bool s_tag_check_datum(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_datum_tx_item_groups_t *a_items_grp, dap_chain_tx_tag_action_type_t *a_action) +{ + //datum service do not produce transactions for now. + return false; +} + int dap_chain_net_srv_datum_init() { dap_cli_server_cmd_add("srv_datum", s_srv_datum_cli, "Service Datum commands", @@ -51,6 +57,10 @@ int dap_chain_net_srv_datum_init() return -1; } s_srv_datum->uid.uint64 = DAP_CHAIN_NET_SRV_DATUM_ID; + + dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_DATUM_ID }; + dap_ledger_service_add(l_uid, "datum", s_tag_check_datum); + return 0; } @@ -100,7 +110,7 @@ static int s_srv_datum_cli(int argc, char ** argv, void **a_str_reply) dap_chain_net_t * l_chain_net = NULL; dap_chain_t * l_chain = NULL; - if (dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index,argc,argv,a_str_reply,&l_chain,&l_chain_net)) { + if (dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index,argc,argv,a_str_reply,&l_chain,&l_chain_net, CHAIN_TYPE_INVALID)) { return -3; } diff --git a/modules/service/stake/dap_chain_net_srv_stake_lock.c b/modules/service/stake/dap_chain_net_srv_stake_lock.c index a2ca43f5b781dd711543ab48668881520d9e9274..47f2127497a39564490e96e82f2ac9e4919232f7 100644 --- a/modules/service/stake/dap_chain_net_srv_stake_lock.c +++ b/modules/service/stake/dap_chain_net_srv_stake_lock.c @@ -27,10 +27,11 @@ #include "dap_time.h" #include "dap_chain_ledger.h" #include "dap_chain_net_srv_stake_lock.h" -#include "dap_chain_node_cli.h" +#include "dap_chain_net_tx.h" #include "dap_chain_wallet.h" #include "dap_chain_mempool.h" #include "dap_chain_net_srv.h" +#include "dap_cli_server.h" static bool s_debug_more = false; @@ -108,6 +109,140 @@ dap_chain_datum_t *s_stake_unlock_datum_create(dap_chain_net_t *a_net, dap_enc_k // Callbacks static void s_stake_lock_callback_updater(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_tx_out_cond_t *a_prev_out_item); static bool s_stake_lock_callback_verificator(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx_in, bool a_owner); + +static inline int s_tsd_str_cmp(const byte_t *a_tsdata, size_t a_tsdsize, const char *str ) { + size_t l_strlen = (size_t)strlen(str); + if (l_strlen != a_tsdsize) return -1; + return memcmp(a_tsdata, str, l_strlen); +} + +//emission tags +//inherits from emission tsd section for engine-produced auth emissions +bool s_get_ems_staking_action(dap_chain_datum_token_emission_t *a_ems, dap_chain_tx_tag_action_type_t *a_action) +{ + if (!a_ems || !a_action) + return false; + + *a_action = DAP_CHAIN_TX_TAG_ACTION_UNKNOWN; + + + size_t src_tsd_size = 0; + size_t subsrc_tsd_size = 0; + + byte_t *ems_src = dap_chain_emission_get_tsd(a_ems, DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_SOURCE, &src_tsd_size); + byte_t *ems_subsrc = dap_chain_emission_get_tsd(a_ems, DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_SOURCE_SUBTYPE, &subsrc_tsd_size); + + if (ems_src && src_tsd_size) + { + if (s_tsd_str_cmp(ems_src, src_tsd_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_STAKING) != 0) + return false; + } + + //special processing for old stakes: they have only STAKING in tsd 9 and no subtype. it is opening stakes + if (ems_src && !ems_subsrc) + { + *a_action = DAP_CHAIN_TX_TAG_ACTION_OPEN; + return true; + } + + if (ems_subsrc && subsrc_tsd_size) + { + if (s_tsd_str_cmp(ems_subsrc, subsrc_tsd_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_STAKE_CROSSCHAIN)==0) + *a_action = DAP_CHAIN_TX_TAG_ACTION_OPEN; + + if (s_tsd_str_cmp(ems_subsrc, subsrc_tsd_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_STAKE_CROSSCHAINV2)==0) + *a_action = DAP_CHAIN_TX_TAG_ACTION_OPEN; + + if (s_tsd_str_cmp(ems_subsrc, subsrc_tsd_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_HARVEST)==0) + *a_action = DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REWARD; + + if (s_tsd_str_cmp(ems_subsrc, subsrc_tsd_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_ADDLIQ)==0) + *a_action = DAP_CHAIN_TX_TAG_ACTION_EXTEND; + + if (s_tsd_str_cmp(ems_subsrc, subsrc_tsd_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_EMSFIX)==0) + *a_action = DAP_CHAIN_TX_TAG_ACTION_CHANGE; + + if (s_tsd_str_cmp(ems_subsrc, subsrc_tsd_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_BONUS)==0) + *a_action = DAP_CHAIN_TX_TAG_ACTION_CHANGE; + + + if (s_tsd_str_cmp(ems_subsrc, subsrc_tsd_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_UNSTAKE_FINALIZATION)==0) + *a_action = DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REWARD; + + if (*a_action == DAP_CHAIN_TX_TAG_ACTION_UNKNOWN) + { + log_it(L_WARNING, "Unknown action for staking: %s", ems_subsrc); + } + return true; + } + + return false; +} + +static bool s_tag_check_staking(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_datum_tx_item_groups_t *a_items_grp, dap_chain_tx_tag_action_type_t *a_action) +{ + //staking native open: have SRV_STAKE_LOCK out + + if (a_items_grp->items_out_cond_srv_stake_lock) { + *a_action = DAP_CHAIN_TX_TAG_ACTION_OPEN; + return true; + } + + //staking native close: have IN_COND linked with SRV_STAKE_LOCK out + if (a_items_grp->items_in_cond) + { + for (dap_list_t *it = a_items_grp->items_in_cond; it; it = it->next) { + dap_chain_tx_in_cond_t *l_tx_in = it->data; + dap_chain_tx_out_cond_t *l_tx_out_cond = dap_chain_ledger_get_tx_out_cond_linked_to_tx_in_cond(a_ledger, l_tx_in); + + if (l_tx_out_cond && l_tx_out_cond->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_LOCK) { + if (a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_CLOSE; + return true; + } + } + } + + //m-token burn: have TSD-items with "STAKING type UNSTAKE subtype" + + if (a_items_grp->items_tsd) { + + bool src_staking = false; + bool subtype_unstake = false; + for (dap_list_t *it = a_items_grp->items_tsd; it; it = it->next) { + dap_chain_tx_tsd_t *l_tx_tsd = it->data; + int l_type; + size_t l_size; + byte_t *l_data = dap_chain_datum_tx_item_get_data(l_tx_tsd, &l_type, &l_size); + + + if (l_type == DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_SOURCE && s_tsd_str_cmp(l_data, l_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_STAKING) == 0) + src_staking = true; + + if (l_type == DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_SOURCE_SUBTYPE && s_tsd_str_cmp(l_data, l_size, DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_UNSTAKE_FINALIZATION) == 0) + subtype_unstake = true; + } + if (subtype_unstake && src_staking) + { + if(a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_CLOSE; + return true; + } + } + + //crosschain staking AUTH emissions + if (!a_items_grp->items_in_ems) + return false; + + dap_chain_tx_in_ems_t *l_tx_in_ems = a_items_grp->items_in_ems->data; + dap_hash_fast_t ems_hash = l_tx_in_ems->header.token_emission_hash; + dap_chain_datum_token_emission_t *l_emission = dap_ledger_token_emission_find(a_ledger, &ems_hash); + if(l_emission) { + bool success = s_get_ems_staking_action(l_emission, a_action); + return success; + } + + return false; +} + /** * @brief dap_chain_net_srv_external_stake_init * @return @@ -131,6 +266,10 @@ int dap_chain_net_srv_stake_lock_init() "-chain <chain>\n" ); s_debug_more = dap_config_get_item_bool_default(g_config, "ledger", "debug_more", false); + + dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_STAKE_LOCK_ID }; + dap_ledger_service_add(l_uid, "staking", s_tag_check_staking); + return 0; } 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 0263288f64d748658c2d155bff1a9a9a9ddd3896..5ad85b61bf1798d2835a33b1aafe163b256674ff 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 @@ -23,13 +23,14 @@ */ #include <math.h> -#include "dap_chain_node_cli.h" +#include "dap_chain_wallet.h" #include "dap_config.h" #include "dap_string.h" #include "dap_list.h" #include "dap_enc_base58.h" #include "dap_chain_common.h" #include "dap_chain_mempool.h" +#include "dap_chain_net_decree.h" #include "dap_chain_net_tx.h" #include "dap_chain_net_srv.h" #include "dap_chain_net_srv_stake_pos_delegate.h" @@ -37,8 +38,9 @@ #include "rand/dap_rand.h" #include "dap_chain_node_client.h" #include "dap_stream_ch_chain_net_pkt.h" -#include "dap_chain_node_cli_cmd.h" #include "json_object.h" +#include "dap_cli_server.h" +#include "dap_chain_net_srv_order.h" #define LOG_TAG "dap_chain_net_srv_stake_pos_delegate" @@ -55,11 +57,33 @@ static void s_stake_deleted_callback(dap_ledger_t *a_ledger, dap_chain_datum_tx_ static void s_cache_data(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_addr_t *a_signing_addr); static void s_uncache_data(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_addr_t *a_signing_addr); -static void s_stake_clear(); +static dap_list_t *s_srv_stake_list = NULL; -static void s_stake_net_clear(dap_chain_net_t *a_net); +static bool s_tag_check_key_delegation(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_datum_tx_item_groups_t *a_items_grp, dap_chain_tx_tag_action_type_t *a_action) +{ + // keydelegation open: have STAK_POS_DELEGATE out + + if (a_items_grp->items_out_cond_srv_stake_pos_delegate) { + if (a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_OPEN; + return true; + } + + //key delegation invalidation (close): have IN_COND linked with STAKE_POS_DELEGATE out + if (a_items_grp->items_in_cond) + { + for (dap_list_t *it = a_items_grp->items_in_cond; it; it = it->next) { + dap_chain_tx_in_cond_t *l_tx_in = it->data; + dap_chain_tx_out_cond_t *l_tx_out_cond = dap_chain_ledger_get_tx_out_cond_linked_to_tx_in_cond(a_ledger, l_tx_in); + + if (l_tx_out_cond && l_tx_out_cond->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE) { + if (a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_CLOSE; + return true; + } + } + } -static dap_chain_net_srv_stake_t *s_srv_stake = NULL; + return false; +} /** * @brief dap_stream_ch_vpn_init Init actions for VPN stream channel @@ -100,70 +124,84 @@ int dap_chain_net_srv_stake_pos_delegate_init() "\tShow the list of active stake keys (optional delegated with specified cert).\n" "srv_stake list tx -net <net_name> \n" "\tShow the list of key delegation transactions.\n" - "srv_stake min_value -net <net_name> -cert <cert_name> -value <value>" + "srv_stake min_value -net <net_name> [-chain <chain_name>] -poa_cert <poa_cert_name> -value <value>\n" "\tSets the minimum stake value\n" + "srv_stake max_weight -net <net_name> [-chain <chain_name>] -poa_cert <poa_cert_name> -percent <value>\n" + "\tSets maximum validator related weight (in percent)\n" "srv_stake check -net <net_name> -tx <tx_hash>" "\tCheck remote validator" ); - s_srv_stake = DAP_NEW_Z(dap_chain_net_srv_stake_t); - if (!s_srv_stake) { - log_it(L_CRITICAL, "%s", g_error_memory_alloc); - return -1; + dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_ID }; + dap_ledger_service_add(l_uid, "pos_delegate", s_tag_check_key_delegation); + return 0; +} + +static dap_chain_net_srv_stake_t *s_srv_stake_by_net_id(dap_chain_net_id_t a_net_id) +{ + for (dap_list_t *it = s_srv_stake_list; it; it = it->next) { + dap_chain_net_srv_stake_t *l_srv_stake = it->data; + if (l_srv_stake->net_id.uint64 == a_net_id.uint64) + return l_srv_stake; } - s_srv_stake->delegate_allowed_min = dap_chain_coins_to_balance("1.0"); + return NULL; +} +int dap_chain_net_srv_stake_net_add(dap_chain_net_id_t a_net_id) +{ + dap_chain_net_srv_stake_t *l_srv_stake; + DAP_NEW_Z_RET_VAL(l_srv_stake, dap_chain_net_srv_stake_t, -1, NULL); + l_srv_stake->net_id = a_net_id; + l_srv_stake->delegate_allowed_min = dap_chain_coins_to_balance("1.0"); + dap_list_t *l_list_new = dap_list_append(s_srv_stake_list, l_srv_stake); + if (dap_list_last(l_list_new) == dap_list_last(s_srv_stake_list)) { + log_it(L_ERROR, "Can't add net %" DAP_UINT64_FORMAT_x "to stake service net list", a_net_id.uint64); + DAP_DELETE(l_srv_stake); + return -2; + } + s_srv_stake_list = l_list_new; + log_it(L_NOTICE, "Successfully added net ID 0x%016" DAP_UINT64_FORMAT_x, a_net_id.uint64); return 0; } /** * @brief delete ht and hh concretic net from s_srv_stake */ -void s_stake_net_clear(dap_chain_net_t *a_net) +static void s_stake_net_clear(dap_chain_net_t *a_net) { + dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_net->pub.id); + dap_return_if_fail(l_srv_stake); dap_chain_net_srv_stake_item_t *l_stake = NULL, *l_tmp = NULL; - HASH_ITER(ht, s_srv_stake->tx_itemlist, l_stake, l_tmp) { + HASH_ITER(ht, l_srv_stake->tx_itemlist, l_stake, l_tmp) { // Clang bug at this, l_stake should change at every loop cycle - if (l_stake->net->pub.id.uint64 == a_net->pub.id.uint64) - HASH_DELETE(ht, s_srv_stake->tx_itemlist, l_stake); + HASH_DELETE(ht, l_srv_stake->tx_itemlist, l_stake); } - HASH_ITER(hh, s_srv_stake->itemlist, l_stake, l_tmp) { + HASH_ITER(hh, l_srv_stake->itemlist, l_stake, l_tmp) { // Clang bug at this, l_stake should change at every loop cycle - if (l_stake->net->pub.id.uint64 == a_net->pub.id.uint64) { - HASH_DEL(s_srv_stake->itemlist, l_stake); - DAP_DELETE(l_stake); - } + HASH_DEL(l_srv_stake->itemlist, l_stake); + DAP_DELETE(l_stake); } dap_chain_net_srv_stake_cache_item_t *l_cache_item = NULL, *l_cache_tmp = NULL; - HASH_ITER(hh, s_srv_stake->cache, l_cache_item, l_cache_tmp) { + HASH_ITER(hh, l_srv_stake->cache, l_cache_item, l_cache_tmp) { // Clang bug at this, l_stake should change at every loop cycle - if (l_cache_item->signing_addr.net_id.uint64 == a_net->pub.id.uint64) { - HASH_DEL(s_srv_stake->cache, l_cache_item); - DAP_DELETE(l_cache_item); - } - } -} - -/** - * @brief delete all nets ht and hh from s_srv_stake - */ -void s_stake_clear() -{ - for (dap_chain_net_t *it = dap_chain_net_iter_start(); it; it = dap_chain_net_iter_next(it)) { - s_stake_net_clear(it); + HASH_DEL(l_srv_stake->cache, l_cache_item); + DAP_DELETE(l_cache_item); } } void dap_chain_net_srv_stake_pos_delegate_deinit() { - s_stake_clear(); - DAP_DEL_Z(s_srv_stake); + for (dap_chain_net_t *it = dap_chain_net_iter_start(); it; it = dap_chain_net_iter_next(it)) + s_stake_net_clear(it); + dap_list_free_full(s_srv_stake_list, NULL); + s_srv_stake_list = NULL; } -static bool s_stake_verificator_callback(dap_ledger_t UNUSED_ARG *a_ledger, dap_chain_tx_out_cond_t *a_cond, +static bool s_stake_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx_in, bool a_owner) { - assert(s_srv_stake); + dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_ledger->net->pub.id); + dap_return_val_if_fail(l_srv_stake, false); // It's a order conditional TX if (dap_chain_addr_is_blank(&a_cond->subtype.srv_stake_pos_delegate.signing_addr) || a_cond->subtype.srv_stake_pos_delegate.signer_node_addr.uint64 == 0) { @@ -178,7 +216,7 @@ static bool s_stake_verificator_callback(dap_ledger_t UNUSED_ARG *a_ledger, dap_ if (compare256(l_tx_out_cond->header.value, a_cond->header.value)) { char *l_in_value = dap_chain_balance_to_coins(l_tx_out_cond->header.value); char *l_out_value = dap_chain_balance_to_coins(a_cond->header.value); - log_it(L_WARNING, "In value %s is not eqal to out value %s", l_in_value, l_out_value); + log_it(L_WARNING, "In value %s is not equal to out value %s", l_in_value, l_out_value); DAP_DELETE(l_in_value); DAP_DELETE(l_out_value); return false; @@ -237,7 +275,7 @@ static bool s_stake_verificator_callback(dap_ledger_t UNUSED_ARG *a_ledger, dap_ if (a_tx_in->header.ts_created < 1706227200) // Jan 26 2024 00:00:00 GMT, old policy rules return true; dap_chain_net_srv_stake_item_t *l_stake; - HASH_FIND(ht, s_srv_stake->tx_itemlist, l_prev_hash, sizeof(dap_hash_t), l_stake); + HASH_FIND(ht, l_srv_stake->tx_itemlist, l_prev_hash, sizeof(dap_hash_t), l_stake); if (l_stake) { log_it(L_WARNING, "Key is active with delegation decree, need to revoke it first"); return false; @@ -247,7 +285,8 @@ static bool s_stake_verificator_callback(dap_ledger_t UNUSED_ARG *a_ledger, dap_ static void s_stake_updater_callback(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_tx_out_cond_t *a_cond) { - assert(s_srv_stake); + dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_ledger->net->pub.id); + dap_return_if_fail(l_srv_stake); if (!a_cond) return; dap_chain_addr_t *l_signing_addr = &a_cond->subtype.srv_stake_pos_delegate.signing_addr; @@ -278,31 +317,80 @@ static bool s_srv_stake_is_poa_cert(dap_chain_net_t *a_net, dap_enc_key_t *a_key return l_is_poa_cert; } +#define LIMIT_DELTA UINT64_C(1000000000000) // 1.0e-6 +static bool s_weights_truncate(dap_chain_net_srv_stake_t *l_srv_stake, const uint256_t a_limit) +{ + uint256_t l_sum = uint256_0; + for (dap_chain_net_srv_stake_item_t *it = l_srv_stake->itemlist; it; it = it->hh.next) + SUM_256_256(l_sum, it->value, &l_sum); + uint256_t l_weight_max; + MULT_256_COIN(l_sum, a_limit, &l_weight_max); + size_t l_exceeds_count = 0; + uint256_t l_sum_others = l_sum; + for (dap_chain_net_srv_stake_item_t *it = l_srv_stake->itemlist; it; it = it->hh.next) { + uint256_t l_weight_with_delta; + SUBTRACT_256_256(it->value, GET_256_FROM_64(LIMIT_DELTA), &l_weight_with_delta); + if (compare256(l_weight_with_delta, l_weight_max) == 1) { + SUBTRACT_256_256(l_sum_others, it->value, &l_sum_others); + it->value = uint256_0; + l_exceeds_count++; + } + } + if (l_exceeds_count) { + uint256_t delta = dap_uint256_decimal_from_uint64(l_exceeds_count); + uint256_t kappa; + DIV_256_COIN(dap_uint256_decimal_from_uint64(1), a_limit, &kappa); + SUBTRACT_256_256(kappa, delta, &kappa); + DIV_256_COIN(l_sum_others, kappa, &kappa); + for (dap_chain_net_srv_stake_item_t *it = l_srv_stake->itemlist; it; it = it->hh.next) + if (IS_ZERO_256(it->value)) + it->value = kappa; + } + return l_exceeds_count; +} + +static void s_stake_recalculate_weights(dap_chain_net_id_t a_net_id) +{ + dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_net_id); + dap_return_if_fail(l_srv_stake); + if (IS_ZERO_256(l_srv_stake->delegate_percent_max)) + return; + size_t l_validators_count = HASH_COUNT(l_srv_stake->itemlist); + uint256_t l_limit_min; + DIV_256(dap_uint256_decimal_from_uint64(1), GET_256_FROM_64(l_validators_count), &l_limit_min); + if (compare256(l_srv_stake->delegate_percent_max, l_limit_min) == 1) + l_limit_min = l_srv_stake->delegate_percent_max; + for (dap_chain_net_srv_stake_item_t *it = l_srv_stake->itemlist; it; it = it->hh.next) + it->value = it->locked_value; // restore original locked values + while (s_weights_truncate(l_srv_stake, l_limit_min)); +} + void dap_chain_net_srv_stake_key_delegate(dap_chain_net_t *a_net, dap_chain_addr_t *a_signing_addr, dap_hash_fast_t *a_stake_tx_hash, uint256_t a_value, dap_chain_node_addr_t *a_node_addr) { - assert(s_srv_stake); dap_return_if_fail(a_net && a_signing_addr && a_node_addr && a_stake_tx_hash); + dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_net->pub.id); + dap_return_if_fail(l_srv_stake); dap_chain_net_srv_stake_item_t *l_stake = NULL; bool l_found = false; - HASH_FIND(hh, s_srv_stake->itemlist, a_signing_addr, sizeof(dap_chain_addr_t), l_stake); + HASH_FIND(hh, l_srv_stake->itemlist, &a_signing_addr->data.hash_fast, sizeof(dap_hash_fast_t), l_stake); if (!l_stake) l_stake = DAP_NEW_Z(dap_chain_net_srv_stake_item_t); else { l_found = true; - HASH_DELETE(ht, s_srv_stake->tx_itemlist, l_stake); + HASH_DELETE(ht, l_srv_stake->tx_itemlist, l_stake); } l_stake->net = a_net; l_stake->node_addr = *a_node_addr; l_stake->signing_addr = *a_signing_addr; - l_stake->value = a_value; + l_stake->value = l_stake->locked_value = a_value; l_stake->tx_hash = *a_stake_tx_hash; l_stake->is_active = true; if (!l_found) - HASH_ADD(hh, s_srv_stake->itemlist, signing_addr, sizeof(dap_chain_addr_t), l_stake); + HASH_ADD(hh, l_srv_stake->itemlist, signing_addr.data.hash_fast, sizeof(dap_hash_fast_t), l_stake); if (!dap_hash_fast_is_blank(a_stake_tx_hash)) { - HASH_ADD(ht, s_srv_stake->tx_itemlist, tx_hash, sizeof(dap_chain_hash_fast_t), l_stake); + HASH_ADD(ht, l_srv_stake->tx_itemlist, tx_hash, sizeof(dap_hash_fast_t), l_stake); dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_hash(a_net->pub.ledger, a_stake_tx_hash); if (l_tx) { dap_chain_tx_out_cond_t *l_cond = dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE, NULL); @@ -320,80 +408,126 @@ void dap_chain_net_srv_stake_key_delegate(dap_chain_net_t *a_net, dap_chain_addr char l_key_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; dap_chain_hash_fast_to_str(&a_signing_addr->data.hash_fast, l_key_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE); - char *l_value_str; dap_uint256_to_char(a_value, &l_value_str); - log_it(L_NOTICE, "Added key with fingerprint %s and value %s for node "NODE_ADDR_FP_STR, + const char *l_value_str; dap_uint256_to_char(a_value, &l_value_str); + log_it(L_NOTICE, "Added key with fingerprint %s and locked value %s for node "NODE_ADDR_FP_STR, l_key_hash_str, l_value_str, NODE_ADDR_FP_ARGS(a_node_addr)); + s_stake_recalculate_weights(a_signing_addr->net_id); } void dap_chain_net_srv_stake_key_invalidate(dap_chain_addr_t *a_signing_addr) { - assert(s_srv_stake); if (!a_signing_addr) return; + dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_signing_addr->net_id); + dap_return_if_fail(l_srv_stake); dap_chain_net_srv_stake_item_t *l_stake = NULL; - HASH_FIND(hh, s_srv_stake->itemlist, a_signing_addr, sizeof(dap_chain_addr_t), l_stake); + HASH_FIND(hh, l_srv_stake->itemlist, &a_signing_addr->data.hash_fast, sizeof(dap_hash_fast_t), l_stake); if (l_stake) { dap_chain_esbocs_remove_validator_from_clusters(l_stake->signing_addr.net_id, &l_stake->node_addr); - HASH_DEL(s_srv_stake->itemlist, l_stake); - HASH_DELETE(ht, s_srv_stake->tx_itemlist, l_stake); + HASH_DEL(l_srv_stake->itemlist, l_stake); + HASH_DELETE(ht, l_srv_stake->tx_itemlist, l_stake); char l_key_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; dap_chain_hash_fast_to_str(&a_signing_addr->data.hash_fast, l_key_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE); - char *l_value_str; dap_uint256_to_char(l_stake->value, &l_value_str); - log_it(L_NOTICE, "Removed key with fingerprint %s and value %s for node "NODE_ADDR_FP_STR, + const char *l_value_str; dap_uint256_to_char(l_stake->locked_value, &l_value_str); + log_it(L_NOTICE, "Removed key with fingerprint %s and locked value %s for node "NODE_ADDR_FP_STR, l_key_hash_str, l_value_str, NODE_ADDR_FP_ARGS_S(l_stake->node_addr)); DAP_DELETE(l_stake); } + s_stake_recalculate_weights(a_signing_addr->net_id); } -void dap_chain_net_srv_stake_set_allowed_min_value(uint256_t a_value) +void dap_chain_net_srv_stake_set_allowed_min_value(dap_chain_net_id_t a_net_id, uint256_t a_value) { - assert(s_srv_stake); - s_srv_stake->delegate_allowed_min = a_value; - for (dap_chain_net_srv_stake_item_t *it = s_srv_stake->itemlist; it; it = it->hh.next) + dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_net_id); + dap_return_if_fail(l_srv_stake); + l_srv_stake->delegate_allowed_min = a_value; + for (dap_chain_net_srv_stake_item_t *it = l_srv_stake->itemlist; it; it = it->hh.next) if (dap_hash_fast_is_blank(&it->tx_hash)) it->value = a_value; } -uint256_t dap_chain_net_srv_stake_get_allowed_min_value() +void dap_chain_net_srv_stake_set_percent_max(dap_chain_net_id_t a_net_id, uint256_t a_value) { - assert(s_srv_stake); - return s_srv_stake->delegate_allowed_min; + dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_net_id); + dap_return_if_fail(l_srv_stake); + l_srv_stake->delegate_percent_max = a_value; + s_stake_recalculate_weights(a_net_id); } -int dap_chain_net_srv_stake_key_delegated(dap_chain_addr_t *a_signing_addr) +uint256_t dap_chain_net_srv_stake_get_allowed_min_value(dap_chain_net_id_t a_net_id) { - assert(s_srv_stake); - if (!a_signing_addr) - return 0; + dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_net_id); + dap_return_val_if_fail(l_srv_stake, uint256_0); + return l_srv_stake->delegate_allowed_min; +} +uint256_t dap_chain_net_srv_stake_get_percent_max(dap_chain_net_id_t a_net_id) +{ + dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_net_id); + dap_return_val_if_fail(l_srv_stake, uint256_0); + return l_srv_stake->delegate_percent_max; +} + +int dap_chain_net_srv_stake_key_delegated(dap_chain_addr_t *a_signing_addr) +{ + dap_return_val_if_fail(a_signing_addr, 0); + dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_signing_addr->net_id); + dap_return_val_if_fail(l_srv_stake, 0); dap_chain_net_srv_stake_item_t *l_stake = NULL; - HASH_FIND(hh, s_srv_stake->itemlist, a_signing_addr, sizeof(dap_chain_addr_t), l_stake); + HASH_FIND(hh, l_srv_stake->itemlist, &a_signing_addr->data.hash_fast, sizeof(dap_hash_fast_t), l_stake); if (l_stake) // public key delegated for this network return l_stake->is_active ? 1 : -1; return 0; } -dap_list_t *dap_chain_net_srv_stake_get_validators(dap_chain_net_id_t a_net_id, bool a_only_active) +dap_list_t *dap_chain_net_srv_stake_get_validators(dap_chain_net_id_t a_net_id, bool a_only_active, uint16_t **a_excluded_list) { + dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_net_id); + dap_return_val_if_fail(l_srv_stake, NULL); + if (!l_srv_stake->itemlist) + return NULL; dap_list_t *l_ret = NULL; - if (!s_srv_stake || !s_srv_stake->itemlist) - return l_ret; - for (dap_chain_net_srv_stake_item_t *l_stake = s_srv_stake->itemlist; l_stake; l_stake = l_stake->hh.next) - if (a_net_id.uint64 == l_stake->signing_addr.net_id.uint64 && - a_only_active ? l_stake->is_active : true) - l_ret = dap_list_append(l_ret, DAP_DUP(l_stake)); + const uint16_t l_arr_resize_step = 64; + size_t l_arr_size = l_arr_resize_step, l_arr_idx = 1, l_list_idx = 0; + if (a_excluded_list) + DAP_NEW_Z_COUNT_RET_VAL(*a_excluded_list, uint16_t, l_arr_size, NULL, NULL); + for (dap_chain_net_srv_stake_item_t *l_stake = l_srv_stake->itemlist; l_stake; l_stake = l_stake->hh.next) { + if (l_stake->is_active || !a_only_active) { + void *l_data = DAP_DUP(l_stake); + if (!l_data) + goto fail_ret; + l_ret = dap_list_append(l_ret, l_data); + } + if (!l_stake->is_active && a_excluded_list) { + *a_excluded_list[l_arr_idx++] = l_list_idx; + if (l_arr_idx == l_arr_size) { + l_arr_size += l_arr_resize_step; + void *l_new_arr = DAP_REALLOC(*a_excluded_list, l_arr_size * sizeof(uint16_t)); + if (l_new_arr) + goto fail_ret; + else + *a_excluded_list = l_new_arr; + } + } + l_list_idx++; + } return l_ret; +fail_ret: + log_it(L_CRITICAL, "%s", g_error_memory_alloc); + dap_list_free_full(l_ret, NULL); + if (a_excluded_list) + DAP_DELETE(*a_excluded_list); + return NULL; } int dap_chain_net_srv_stake_mark_validator_active(dap_chain_addr_t *a_signing_addr, bool a_on_off) { - assert(s_srv_stake); - if (!a_signing_addr) - return -1; - + dap_return_val_if_fail(a_signing_addr, -1); + dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_signing_addr->net_id); + dap_return_val_if_fail(l_srv_stake, -3); dap_chain_net_srv_stake_item_t *l_stake = NULL; - HASH_FIND(hh, s_srv_stake->itemlist, a_signing_addr, sizeof(dap_chain_addr_t), l_stake); + HASH_FIND(hh, l_srv_stake->itemlist, &a_signing_addr->data.hash_fast, sizeof(dap_hash_fast_t), l_stake); if (l_stake) { // public key delegated for this network l_stake->is_active = a_on_off; return 0; @@ -403,11 +537,9 @@ int dap_chain_net_srv_stake_mark_validator_active(dap_chain_addr_t *a_signing_ad int dap_chain_net_srv_stake_verify_key_and_node(dap_chain_addr_t *a_signing_addr, dap_chain_node_addr_t *a_node_addr) { - assert(s_srv_stake); - if (!a_signing_addr || !a_node_addr){ - log_it(L_WARNING, "Bad srv_stake_verify arguments"); - return -100; - } + dap_return_val_if_fail(a_signing_addr && a_node_addr, -100); + dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_signing_addr->net_id); + dap_return_val_if_fail(l_srv_stake, -104); if (dap_chain_addr_is_blank(a_signing_addr) || a_node_addr->uint64 == 0) { log_it(L_WARNING, "Trying to approve bad delegating TX. Node or key addr is blank"); @@ -415,7 +547,7 @@ int dap_chain_net_srv_stake_verify_key_and_node(dap_chain_addr_t *a_signing_addr } dap_chain_net_srv_stake_item_t *l_stake = NULL, *l_tmp = NULL; - HASH_ITER(hh, s_srv_stake->itemlist, l_stake, l_tmp){ + HASH_ITER(hh, l_srv_stake->itemlist, l_stake, l_tmp){ //check key not activated for other node if(dap_chain_addr_compare(a_signing_addr, &l_stake->signing_addr)){ char l_key_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; @@ -440,10 +572,12 @@ int dap_chain_net_srv_stake_verify_key_and_node(dap_chain_addr_t *a_signing_addr return 0; } -static bool s_stake_cache_check_tx(dap_hash_fast_t *a_tx_hash) +static bool s_stake_cache_check_tx(dap_ledger_t *a_ledger, dap_hash_fast_t *a_tx_hash) { + dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_ledger->net->pub.id); + dap_return_val_if_fail(l_srv_stake, false); dap_chain_net_srv_stake_cache_item_t *l_stake; - HASH_FIND(hh, s_srv_stake->cache, a_tx_hash, sizeof(*a_tx_hash), l_stake); + HASH_FIND(hh, l_srv_stake->cache, a_tx_hash, sizeof(*a_tx_hash), l_stake); if (l_stake) { dap_chain_net_srv_stake_key_invalidate(&l_stake->signing_addr); return true; @@ -470,6 +604,9 @@ int dap_chain_net_srv_stake_load_cache(dap_chain_net_t *a_net) log_it(L_DEBUG, "Stake cache data not found"); return -2; } + dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_net->pub.id); + dap_return_val_if_fail(l_srv_stake, -4); + for (size_t i = 0; i < l_objs_count; i++){ dap_chain_net_srv_stake_cache_data_t *l_cache_data = (dap_chain_net_srv_stake_cache_data_t *)l_objs[i].value; @@ -480,7 +617,7 @@ int dap_chain_net_srv_stake_load_cache(dap_chain_net_t *a_net) } l_cache->signing_addr = l_cache_data->signing_addr; l_cache->tx_hash = l_cache_data->tx_hash; - HASH_ADD(hh, s_srv_stake->cache, tx_hash, sizeof(dap_hash_fast_t), l_cache); + HASH_ADD(hh, l_srv_stake->cache, tx_hash, sizeof(dap_hash_fast_t), l_cache); } dap_global_db_objs_delete(l_objs, l_objs_count); dap_ledger_set_cache_tx_check_callback(l_ledger, s_stake_cache_check_tx); @@ -679,7 +816,7 @@ dap_chain_datum_decree_t *dap_chain_net_srv_stake_decree_approve(dap_chain_net_t log_it(L_WARNING, "Requested conditional transaction have another ticker (not %s)", l_delegated_ticker); return NULL; } - if (compare256(l_tx_out_cond->header.value, s_srv_stake->delegate_allowed_min) == -1) { + if (compare256(l_tx_out_cond->header.value, dap_chain_net_srv_stake_get_allowed_min_value(a_net->pub.id)) == -1) { log_it(L_WARNING, "Requested conditional transaction have not enough funds"); return NULL; } @@ -701,7 +838,7 @@ dap_chain_datum_decree_t *dap_chain_net_srv_stake_decree_approve(dap_chain_net_t log_it(L_CRITICAL, "%s", g_error_memory_alloc); return NULL; } - l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_TX_HASH; + l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HASH; l_tsd->size = sizeof(dap_hash_fast_t); *(dap_hash_fast_t*)(l_tsd->data) = *a_stake_tx_hash; l_tsd_list = dap_list_append(l_tsd_list, l_tsd); @@ -737,7 +874,7 @@ dap_chain_datum_decree_t *dap_chain_net_srv_stake_decree_approve(dap_chain_net_t dap_list_free_full(l_tsd_list, NULL); return NULL; } - l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_SIGNER_NODE_ADDR; + l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR; l_tsd->size = sizeof(dap_chain_node_addr_t); *(dap_chain_node_addr_t*)(l_tsd->data) = l_tx_out_cond->subtype.srv_stake_pos_delegate.signer_node_addr; l_tsd_list = dap_list_append(l_tsd_list, l_tsd); @@ -1032,85 +1169,31 @@ static dap_chain_datum_decree_t *s_stake_decree_invalidate(dap_chain_net_t *a_ne return l_decree; } -static dap_chain_datum_decree_t *s_stake_decree_set_min_stake(dap_chain_net_t *a_net, uint256_t a_value, dap_cert_t *a_cert) +static dap_chain_datum_decree_t *s_stake_decree_set_max_weight(dap_chain_net_t *a_net, dap_chain_t *a_chain, + uint256_t a_value, dap_cert_t *a_cert) { - size_t l_total_tsd_size = 0; - dap_chain_datum_decree_t *l_decree = NULL; - dap_list_t *l_tsd_list = NULL; - dap_tsd_t *l_tsd = NULL; - - l_total_tsd_size += sizeof(dap_tsd_t) + sizeof(uint256_t); - l_tsd = DAP_NEW_Z_SIZE(dap_tsd_t, l_total_tsd_size); - if (!l_tsd) { - log_it(L_CRITICAL, "%s", g_error_memory_alloc); + size_t l_total_tsd_size = sizeof(dap_tsd_t) + sizeof(uint256_t); + dap_chain_datum_decree_t *l_decree = dap_chain_datum_decree_new(a_net->pub.id, a_chain->id, + *dap_chain_net_get_cur_cell(a_net), l_total_tsd_size); + if (!l_decree) return NULL; - } - l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE; - l_tsd->size = sizeof(uint256_t); - *(uint256_t*)(l_tsd->data) = a_value; - l_tsd_list = dap_list_append(l_tsd_list, l_tsd); - - l_decree = DAP_NEW_Z_SIZE(dap_chain_datum_decree_t, sizeof(dap_chain_datum_decree_t) + l_total_tsd_size); - if (!l_decree) { - log_it(L_CRITICAL, "%s", g_error_memory_alloc); - dap_list_free_full(l_tsd_list, NULL); - return NULL; - } - l_decree->decree_version = DAP_CHAIN_DATUM_DECREE_VERSION; - l_decree->header.ts_created = dap_time_now(); - l_decree->header.type = DAP_CHAIN_DATUM_DECREE_TYPE_COMMON; - l_decree->header.common_decree_params.net_id = a_net->pub.id; - dap_chain_t *l_chain = dap_chain_net_get_default_chain_by_chain_type(a_net, CHAIN_TYPE_ANCHOR); - if (!l_chain) - l_chain = dap_chain_net_get_chain_by_chain_type(a_net, CHAIN_TYPE_ANCHOR); - if (!l_chain) { - log_it(L_ERROR, "No chain supported anchor datum type"); - DAP_DEL_Z(l_decree); - dap_list_free_full(l_tsd_list, NULL); - return NULL; - } - l_decree->header.common_decree_params.chain_id = l_chain->id; - l_decree->header.common_decree_params.cell_id = *dap_chain_net_get_cur_cell(a_net); - l_decree->header.sub_type = DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALUE; - l_decree->header.data_size = l_total_tsd_size; - l_decree->header.signs_size = 0; - - size_t l_data_tsd_offset = 0; - for ( dap_list_t* l_iter=dap_list_first(l_tsd_list); l_iter; l_iter=l_iter->next){ - dap_tsd_t * l_b_tsd = (dap_tsd_t *) l_iter->data; - size_t l_tsd_size = dap_tsd_size(l_b_tsd); - memcpy((byte_t*)l_decree->data_n_signs + l_data_tsd_offset, l_b_tsd, l_tsd_size); - l_data_tsd_offset += l_tsd_size; - } - dap_list_free_full(l_tsd_list, NULL); + l_decree->header.sub_type = DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_MAX_WEIGHT; + dap_tsd_write(l_decree->data_n_signs, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE, &a_value, sizeof(uint256_t)); + return dap_chain_datum_decree_sign_in_cycle(&a_cert, l_decree, 1, NULL); +} - size_t l_cur_sign_offset = l_decree->header.data_size + l_decree->header.signs_size; - size_t l_total_signs_size = l_decree->header.signs_size; - dap_sign_t * l_sign = dap_cert_sign(a_cert, l_decree, - sizeof(dap_chain_datum_decree_t) + l_decree->header.data_size, 0); - - if (l_sign) { - size_t l_sign_size = dap_sign_get_size(l_sign); - l_decree = DAP_REALLOC(l_decree, sizeof(dap_chain_datum_decree_t) + l_cur_sign_offset + l_sign_size); - if (!l_decree) { - log_it(L_CRITICAL, "%s", g_error_memory_alloc); - DAP_DELETE(l_sign); - return NULL; - } - memcpy((byte_t*)l_decree->data_n_signs + l_cur_sign_offset, l_sign, l_sign_size); - l_total_signs_size += l_sign_size; - l_cur_sign_offset += l_sign_size; - l_decree->header.signs_size = l_total_signs_size; - DAP_DELETE(l_sign); - log_it(L_DEBUG,"<-- Signed with '%s'", a_cert->name); - }else{ - log_it(L_ERROR, "Decree signing failed"); - DAP_DELETE(l_decree); +static dap_chain_datum_decree_t *s_stake_decree_set_min_stake(dap_chain_net_t *a_net, dap_chain_t *a_chain, + uint256_t a_value, dap_cert_t *a_cert) +{ + size_t l_total_tsd_size = sizeof(dap_tsd_t) + sizeof(uint256_t); + dap_chain_datum_decree_t *l_decree = dap_chain_datum_decree_new(a_net->pub.id, a_chain->id, + *dap_chain_net_get_cur_cell(a_net), l_total_tsd_size); + if (!l_decree) return NULL; - } - - return l_decree; + l_decree->header.sub_type = DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALUE; + dap_tsd_write(l_decree->data_n_signs, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_MIN_VALUE, &a_value, sizeof(uint256_t)); + return dap_chain_datum_decree_sign_in_cycle(&a_cert, l_decree, 1, NULL); } char *s_fee_order_create(dap_chain_net_t *a_net, uint256_t *a_fee, dap_enc_key_t *a_key, const char *a_hash_out_type) @@ -1286,7 +1369,7 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, voi uint256_t l_tax = dap_chain_coins_to_balance(l_tax_str); if (compare256(l_tax, dap_chain_coins_to_balance("100.0")) == 1 || compare256(l_tax, GET_256_FROM_64(100)) == -1) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Tax must be lower or eqal than 100%% and higher or eqal than 1.0e-16%%"); + dap_cli_server_cmd_set_reply_text(a_str_reply, "Tax must be lower or equal than 100%% and higher or equal than 1.0e-16%%"); return -10; } const char *l_cert_str = NULL; @@ -1361,7 +1444,7 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, voi uint256_t l_tax = dap_chain_coins_to_balance(l_tax_str); if (compare256(l_tax, dap_chain_coins_to_balance("100.0")) == 1 || compare256(l_tax, GET_256_FROM_64(100)) == -1) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Tax must be lower or eqal than 100%% and higher or eqal than 1.0e-16%%"); + dap_cli_server_cmd_set_reply_text(a_str_reply, "Tax must be lower or equal than 100%% and higher or equal than 1.0e-16%%"); return -10; } dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-w", &l_wallet_str); @@ -1526,7 +1609,7 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, voi dap_string_append(l_reply_str, "Value in this order type means minimum value of m-tokens for validator acceptable for key delegation with supplied tax\n" "Order external params:\n"); struct validator_odrer_ext *l_ext = (struct validator_odrer_ext *)l_order->ext_n_sign; - char *l_coins_str; + const char *l_coins_str; dap_uint256_to_char(l_ext->tax, &l_coins_str); dap_string_append_printf(l_reply_str, " tax: %s%%\n", l_coins_str); dap_uint256_to_char(l_ext->value_max, &l_coins_str); @@ -1550,7 +1633,7 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, voi } } if (!l_error) { - char *l_tax_str; dap_uint256_to_char(l_tax, &l_tax_str); + const char *l_tax_str; dap_uint256_to_char(l_tax, &l_tax_str); dap_string_append_printf(l_reply_str, " sovereign_tax: %s%%\n sovereign_addr: %s\n", l_tax_str, dap_chain_addr_to_str(&l_addr)); } else @@ -1764,7 +1847,7 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index, struct validator_odrer_ext *l_ext = (struct validator_odrer_ext *)l_order->ext_n_sign; l_sovereign_tax = l_ext->tax; if (l_order_hash_str && compare256(l_value, l_order->price) == -1) { - char *l_coin_min_str, *l_value_min_str = + const char *l_coin_min_str, *l_value_min_str = dap_uint256_to_char(l_order->price, &l_coin_min_str); dap_cli_server_cmd_set_reply_text(a_str_reply, "Number in '-value' param %s is lower than order minimum allowed value %s(%s)", l_value_str, l_coin_min_str, l_value_min_str); @@ -1772,7 +1855,7 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index, return -13; } if (l_order_hash_str && compare256(l_value, l_ext->value_max) == 1) { - char *l_coin_max_str, *l_value_max_str = + const char *l_coin_max_str, *l_value_max_str = dap_uint256_to_char(l_ext->value_max, &l_coin_max_str); dap_cli_server_cmd_set_reply_text(a_str_reply, "Number in '-value' param %s is higher than order minimum allowed value %s(%s)", l_value_str, l_coin_max_str, l_value_max_str); @@ -1800,7 +1883,7 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index, DAP_DELETE(l_order); if (compare256(l_sovereign_tax, dap_chain_coins_to_balance("100.0")) == 1 || compare256(l_sovereign_tax, GET_256_FROM_64(100)) == -1) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Tax must be lower or eqal than 100%% and higher or eqal than 1.0e-16%%"); + dap_cli_server_cmd_set_reply_text(a_str_reply, "Tax must be lower or equal than 100%% and higher or equal than 1.0e-16%%"); dap_enc_key_delete(l_enc_key); return -29; } @@ -1813,8 +1896,9 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index, dap_chain_wallet_close(l_wallet); return l_check_result; } - if (compare256(l_value, s_srv_stake->delegate_allowed_min) == -1) { - char *l_coin_min_str, *l_value_min_str = dap_uint256_to_char(s_srv_stake->delegate_allowed_min, &l_coin_min_str); + uint256_t l_allowed_min = dap_chain_net_srv_stake_get_allowed_min_value(l_net->pub.id); + if (compare256(l_value, l_allowed_min) == -1) { + const char *l_coin_min_str, *l_value_min_str = dap_uint256_to_char(l_allowed_min, &l_coin_min_str); dap_cli_server_cmd_set_reply_text(a_str_reply, "Number in '-value' param %s is lower than minimum allowed value %s(%s)", l_value_str, l_coin_min_str, l_value_min_str); dap_enc_key_delete(l_enc_key); @@ -1922,6 +2006,10 @@ static int s_cli_srv_stake_invalidate(int a_argc, char **a_argv, int a_arg_index dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate not found"); return -18; } + if (!l_cert->enc_key->priv_key_data || l_cert->enc_key->priv_key_data_size == 0) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "It is not possible to invalidate a stake using a public key."); + return -31; + } if (dap_chain_addr_fill_from_key(&l_signing_addr, l_cert->enc_key, l_net->pub.id)) { dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate is wrong"); return -22; @@ -1934,8 +2022,13 @@ static int s_cli_srv_stake_invalidate(int a_argc, char **a_argv, int a_arg_index } dap_chain_addr_fill(&l_signing_addr, dap_sign_type_from_str(l_signing_pkey_type_str), &l_pkey_hash, l_net->pub.id); } + dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(l_net->pub.id); + if (!l_srv_stake) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified net have no stake service activated"); + return -25; + } dap_chain_net_srv_stake_item_t *l_stake; - HASH_FIND(hh, s_srv_stake->itemlist, &l_signing_addr, sizeof(dap_chain_addr_t), l_stake); + HASH_FIND(hh, l_srv_stake->itemlist, &l_signing_addr.data.hash_fast, sizeof(dap_hash_fast_t), l_stake); if (!l_stake) { dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate/pkey hash is not delegated nor this delegating is approved." " Try to invalidate with tx hash instead"); @@ -1966,8 +2059,13 @@ static int s_cli_srv_stake_invalidate(int a_argc, char **a_argv, int a_arg_index } } if (l_tx_hash_str || l_cert_str) { + dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(l_net->pub.id); + if (!l_srv_stake) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified net have no stake service activated"); + return -25; + } dap_chain_net_srv_stake_item_t *l_stake; - HASH_FIND(ht, s_srv_stake->tx_itemlist, &l_tx_hash, sizeof(dap_hash_t), l_stake); + HASH_FIND(ht, l_srv_stake->tx_itemlist, &l_tx_hash, sizeof(dap_hash_t), l_stake); if (l_stake) { char l_pkey_hash_str[DAP_HASH_FAST_STR_SIZE]; dap_hash_fast_to_str(&l_stake->signing_addr.data.hash_fast, l_pkey_hash_str, DAP_HASH_FAST_STR_SIZE); @@ -2031,17 +2129,6 @@ static int s_cli_srv_stake_invalidate(int a_argc, char **a_argv, int a_arg_index return 0; } -DAP_STATIC_INLINE bool s_chain_esbocs_started(dap_chain_net_t *a_net) -{ - dap_chain_t *l_chain; - DL_FOREACH(a_net->pub.chains, l_chain) { - if (!strcmp(DAP_CHAIN_PVT(l_chain)->cs_name, "esbocs") && - DAP_CHAIN_PVT(l_chain)->cs_started) - return true; - } - return false; -} - static void s_srv_stake_print(dap_chain_net_srv_stake_item_t *a_stake, uint256_t a_total_weight, dap_string_t *a_string) { char l_tx_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE], l_pkey_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; @@ -2053,9 +2140,9 @@ static void s_srv_stake_print(dap_chain_net_srv_stake_item_t *a_stake, uint256_t DIV_256_COIN(l_tmp, a_total_weight, &l_rel_weight); char *l_rel_weight_str = dap_chain_balance_to_coins(l_rel_weight); char l_active_str[32] = {}; - if (s_chain_esbocs_started(a_stake->net)) + if (dap_chain_esbocs_started(a_stake->signing_addr.net_id)) snprintf(l_active_str, 32, "\tActive: %s\n", a_stake->is_active ? "true" : "false"); - char *l_sov_addr_str = dap_chain_addr_is_blank(&a_stake->sovereign_addr) ? + const char *l_sov_addr_str = dap_chain_addr_is_blank(&a_stake->sovereign_addr) ? "null" : dap_chain_addr_to_str(&a_stake->sovereign_addr); uint256_t l_sov_tax_percent = uint256_0; MULT_256_256(a_stake->sovereign_tax, GET_256_FROM_64(100), &l_sov_tax_percent); @@ -2105,8 +2192,11 @@ static void s_get_tx_filter_callback(dap_chain_net_t* a_net, dap_chain_datum_tx_ dap_hash_fast_t l_datum_hash = *a_tx_hash; if (dap_ledger_tx_hash_is_used_out_item(a_net->pub.ledger, &l_datum_hash, l_out_idx_tmp, NULL)) return; + dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_net->pub.id); + if (!l_srv_stake) + return; dap_chain_net_srv_stake_item_t *l_stake = NULL; - HASH_FIND(ht, s_srv_stake->tx_itemlist, &l_datum_hash, sizeof(dap_hash_fast_t), l_stake); + HASH_FIND(ht, l_srv_stake->tx_itemlist, &l_datum_hash, sizeof(dap_hash_fast_t), l_stake); if (!l_stake) l_args->ret = dap_list_append(l_args->ret,a_tx); } @@ -2213,9 +2303,11 @@ int dap_chain_net_srv_stake_check_validator(dap_chain_net_t * a_net, dap_hash_fa uint256_t dap_chain_net_srv_stake_get_total_weight(dap_chain_net_id_t a_net_id) { + dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_net_id); + dap_return_val_if_fail(l_srv_stake, uint256_0); uint256_t l_total_weight = uint256_0; - for (dap_chain_net_srv_stake_item_t *it = s_srv_stake->itemlist; it; it = it->hh.next) { - if (it->net->pub.id.uint64 != a_net_id.uint64) + for (dap_chain_net_srv_stake_item_t *it = l_srv_stake->itemlist; it; it = it->hh.next) { + if (it->signing_addr.net_id.uint64 != a_net_id.uint64) continue; SUM_256_256(l_total_weight, it->value, &l_total_weight); } @@ -2225,7 +2317,7 @@ uint256_t dap_chain_net_srv_stake_get_total_weight(dap_chain_net_id_t a_net_id) static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply) { enum { - CMD_NONE, CMD_ORDER, CMD_DELEGATE, CMD_APPROVE, CMD_LIST, CMD_INVALIDATE, CMD_MIN_VALUE, CMD_CHECK + CMD_NONE, CMD_ORDER, CMD_DELEGATE, CMD_APPROVE, CMD_LIST, CMD_INVALIDATE, CMD_MIN_VALUE, CMD_CHECK, CMD_MAX_WEIGHT }; int l_arg_index = 1; @@ -2257,10 +2349,13 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply) else if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, dap_min(a_argc, l_arg_index + 1), "invalidate", NULL)) { l_cmd_num = CMD_INVALIDATE; } - // RSetss stake minimum value + // Set stake minimum value else if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, dap_min(a_argc, l_arg_index + 1), "min_value", NULL)) { l_cmd_num = CMD_MIN_VALUE; } + else if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, dap_min(a_argc, l_arg_index + 1), "max_weight", NULL)) { + l_cmd_num = CMD_MAX_WEIGHT; + } else if(dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, dap_min(a_argc, l_arg_index + 1), "check", NULL)) { l_cmd_num = CMD_CHECK; } @@ -2422,6 +2517,11 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply) dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s not found", l_net_str); return -4; } + dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(l_net->pub.id); + if (!l_srv_stake) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified net have no stake service activated"); + return -25; + } dap_chain_net_srv_stake_item_t *l_stake = NULL; dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-cert", &l_cert_str); if (l_cert_str) { @@ -2435,7 +2535,7 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply) dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate is wrong"); return -20; } - HASH_FIND(hh, s_srv_stake->itemlist, &l_signing_addr, sizeof(dap_chain_addr_t), l_stake); + HASH_FIND(hh, l_srv_stake->itemlist, &l_signing_addr.data.hash_fast, sizeof(dap_hash_fast_t), l_stake); if (!l_stake) { dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate isn't delegated nor approved"); return -21; @@ -2449,7 +2549,7 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply) dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified pkey hash is wrong"); return -20; } - l_stake = dap_chain_net_srv_stake_check_pkey_hash(&l_pkey_hash); + l_stake = dap_chain_net_srv_stake_check_pkey_hash(l_net->pub.id, &l_pkey_hash); if (!l_stake) { dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified pkey hash isn't delegated nor approved"); return -21; @@ -2462,31 +2562,38 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply) if (l_stake) s_srv_stake_print(l_stake, l_total_weight, l_reply_str); else - for (l_stake = s_srv_stake->itemlist; l_stake; l_stake = l_stake->hh.next) { - if (l_stake->net->pub.id.uint64 != l_net->pub.id.uint64) - continue; + for (l_stake = l_srv_stake->itemlist; l_stake; l_stake = l_stake->hh.next) { l_total_count++; if (!l_stake->is_active) l_inactive_count++; s_srv_stake_print(l_stake, l_total_weight, l_reply_str); } - if (!HASH_CNT(hh, s_srv_stake->itemlist)) { + if (!HASH_CNT(hh, l_srv_stake->itemlist)) { dap_string_append(l_reply_str, "No keys found\n"); } else { if (!l_cert_str && !l_pkey_hash_str) dap_string_append_printf(l_reply_str, "Total keys count: %zu\n", l_total_count); - if (s_chain_esbocs_started(l_net)) + if (dap_chain_esbocs_started(l_net->pub.id)) dap_string_append_printf(l_reply_str, "Inactive keys count: %zu\n", l_inactive_count); - char *l_total_weight_coins, *l_total_weight_str = + const char *l_total_weight_coins, *l_total_weight_str = dap_uint256_to_char(l_total_weight, &l_total_weight_coins); dap_string_append_printf(l_reply_str, "Total weight: %s (%s)\n", l_total_weight_coins, l_total_weight_str); } - char *l_delegate_min_str; dap_uint256_to_char(s_srv_stake->delegate_allowed_min, &l_delegate_min_str); + const char *l_delegate_min_str; dap_uint256_to_char(dap_chain_net_srv_stake_get_allowed_min_value(l_net->pub.id), + &l_delegate_min_str); char l_delegated_ticker[DAP_CHAIN_TICKER_SIZE_MAX]; dap_chain_datum_token_get_delegated_ticker(l_delegated_ticker, l_net->pub.native_ticker); - dap_string_append_printf(l_reply_str, "Minimum value for key delegating: %s %s", + dap_string_append_printf(l_reply_str, "Minimum value for key delegating: %s %s\n", l_delegate_min_str, l_delegated_ticker); + uint256_t l_percent_max = dap_chain_net_srv_stake_get_percent_max(l_net->pub.id); + const char *l_percent_max_str = NULL; + if (!IS_ZERO_256(l_percent_max)) { + MULT_256_256(l_percent_max, GET_256_FROM_64(100), &l_percent_max); + dap_uint256_to_char(l_percent_max, &l_percent_max_str); + } + dap_string_append_printf(l_reply_str, "Maximum related weight of each validator: %s%%\n", + IS_ZERO_256(l_percent_max) ? "100" : l_percent_max_str); *a_str_reply = dap_string_free(l_reply_str, false); } else if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "tx", NULL)) { const char *l_net_str = NULL; @@ -2513,9 +2620,7 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply) dap_chain_tx_out_cond_t *l_tx_out_cond = NULL; int l_out_idx_tmp = 0; char *spaces = {"--------------------------------------------------------------------------------------------------------------------"}; - char *l_signing_addr_str = NULL; - char *l_balance = NULL; - char *l_coins = NULL; + const char *l_signing_addr_str = NULL, *l_balance = NULL, *l_coins = NULL; char* l_node_address_text_block = NULL; dap_chain_net_get_tx_all(l_net,TX_SEARCH_TYPE_NET,s_get_tx_filter_callback, l_args); l_args->ret = dap_list_sort(l_args->ret, s_callback_compare_tx_list); @@ -2569,10 +2674,16 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply) dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s not found", l_net_str); return -4; } - - dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-cert", &l_cert_str); + dap_chain_t *l_chain = dap_chain_net_get_default_chain_by_chain_type(l_net, CHAIN_TYPE_ANCHOR); + if (!l_chain) + l_chain = dap_chain_net_get_chain_by_chain_type(l_net, CHAIN_TYPE_ANCHOR); + if (!l_chain) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "No chain supported anchor datum type"); + return -2; + } + dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-poa_cert", &l_cert_str); if (!l_cert_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'min_value' requires parameter -cert"); + dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'min_value' requires parameter -poa_cert"); return -3; } dap_cert_t *l_poa_cert = dap_cert_find_by_name(l_cert_str); @@ -2596,7 +2707,7 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply) return -10; } - dap_chain_datum_decree_t *l_decree = s_stake_decree_set_min_stake(l_net, l_value, l_poa_cert); + dap_chain_datum_decree_t *l_decree = s_stake_decree_set_min_stake(l_net, l_chain, l_value, l_poa_cert); char *l_decree_hash_str = NULL; if (l_decree && (l_decree_hash_str = s_stake_decree_put(l_decree, l_net))) { dap_cli_server_cmd_set_reply_text(a_str_reply, "Minimum stake value has been set." @@ -2610,6 +2721,72 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply) } } break; + case CMD_MAX_WEIGHT: { + const char *l_net_str = NULL, + *l_cert_str = NULL, + *l_value_str = NULL; + l_arg_index++; + dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str); + if (!l_net_str) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'min_value' requires parameter -net"); + return -3; + } + dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str); + if (!l_net) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s not found", l_net_str); + return -4; + } + dap_chain_t *l_chain = dap_chain_net_get_default_chain_by_chain_type(l_net, CHAIN_TYPE_ANCHOR); + if (!l_chain) + l_chain = dap_chain_net_get_chain_by_chain_type(l_net, CHAIN_TYPE_ANCHOR); + if (!l_chain) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "No chain supported anchor datum type"); + return -2; + } + dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-poa_cert", &l_cert_str); + if (!l_cert_str) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'min_value' requires parameter -poa_cert"); + return -3; + } + dap_cert_t *l_poa_cert = dap_cert_find_by_name(l_cert_str); + if (!l_poa_cert) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate not found"); + return -25; + } + if (!s_srv_stake_is_poa_cert(l_net, l_poa_cert->enc_key)) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Specified certificate is not PoA root one"); + return -26; + } + + dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-percent", &l_value_str); + if (!l_value_str) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'min_value' requires parameter -percent"); + return -9; + } + uint256_t l_value = dap_chain_balance_scan(l_value_str); + if (IS_ZERO_256(l_value)) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Unrecognized number in '-percent' param"); + return -10; + } + if (compare256(l_value, dap_chain_coins_to_balance("100.0")) >= 0) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Percent must be lower than 100%%"); + return -29; + } + DIV_256(l_value, GET_256_FROM_64(100), &l_value); + dap_chain_datum_decree_t *l_decree = s_stake_decree_set_max_weight(l_net, l_chain, l_value, l_poa_cert); + char *l_decree_hash_str = NULL; + if (l_decree && (l_decree_hash_str = s_stake_decree_put(l_decree, l_net))) { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Maximum weight has been set." + " Decree hash %s", l_decree_hash_str); + DAP_DELETE(l_decree); + DAP_DELETE(l_decree_hash_str); + } else { + dap_cli_server_cmd_set_reply_text(a_str_reply, "Maximum weight setting failed"); + DAP_DEL_Z(l_decree); + return -21; + } + } break; + default: { dap_cli_server_cmd_set_reply_text(a_str_reply, "Command %s not recognized", a_argv[l_arg_index]); return -1; @@ -2681,7 +2858,7 @@ void dap_chain_net_srv_stake_get_fee_validators_str(dap_chain_net_t *a_net, dap_ uint256_t l_min = uint256_0, l_max = uint256_0, l_average = uint256_0, l_median = uint256_0; dap_chain_net_srv_stake_get_fee_validators(a_net, &l_max, &l_average, &l_min, &l_median); const char *l_native_token = a_net->pub.native_ticker; - char *l_coins_str, + const char *l_coins_str, *l_min_balance = dap_strdup(dap_uint256_to_char(l_min, &l_coins_str)), *l_min_coins = dap_strdup(l_coins_str), *l_max_balance = dap_strdup(dap_uint256_to_char(l_max, &l_coins_str)), *l_max_coins = dap_strdup(l_coins_str), *l_average_balance = dap_strdup(dap_uint256_to_char(l_average, &l_coins_str)), *l_average_coins= dap_strdup(l_coins_str), @@ -2708,7 +2885,7 @@ json_object *dap_chain_net_srv_stake_get_fee_validators_json(dap_chain_net_t *a *l_jobj_average = json_object_new_object(), *l_jobj_median = json_object_new_object(), *l_jobj_ret = json_object_new_object(); - char *l_coins_str; + const char *l_coins_str; json_object_object_add( l_jobj_min, "balance", json_object_new_string(dap_uint256_to_char(l_min, &l_coins_str)) ); json_object_object_add( l_jobj_min, "coin", json_object_new_string(l_coins_str) ); @@ -2757,12 +2934,13 @@ static void s_uncache_data(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, d log_it(L_WARNING, "Stake service cache mismatch"); } -dap_chain_net_srv_stake_item_t *dap_chain_net_srv_stake_check_pkey_hash(dap_hash_fast_t *a_pkey_hash) +dap_chain_net_srv_stake_item_t *dap_chain_net_srv_stake_check_pkey_hash(dap_chain_net_id_t a_net_id, dap_hash_fast_t *a_pkey_hash) { - if (!s_srv_stake) + dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_net_id); + if (!l_srv_stake) return NULL; dap_chain_net_srv_stake_item_t *l_stake, *l_tmp; - HASH_ITER(hh, s_srv_stake->itemlist, l_stake, l_tmp) { + HASH_ITER(hh, l_srv_stake->itemlist, l_stake, l_tmp) { if (dap_hash_fast_compare(&l_stake->signing_addr.data.hash_fast, a_pkey_hash)) return l_stake; } diff --git a/modules/service/stake/include/dap_chain_net_srv_stake_pos_delegate.h b/modules/service/stake/include/dap_chain_net_srv_stake_pos_delegate.h index d8fea0a16e67d7554772ed8bdc30411388847ace..9772663f553ca3b7d7ac53fe6c52ecf83ef84ba6 100644 --- a/modules/service/stake/include/dap_chain_net_srv_stake_pos_delegate.h +++ b/modules/service/stake/include/dap_chain_net_srv_stake_pos_delegate.h @@ -25,10 +25,9 @@ #pragma once #include "dap_chain_ledger.h" -#include "dap_chain_net_srv.h" -#include "dap_chain_net_srv_order.h" #include "dap_math_ops.h" #include "dap_stream_ch_chain_net.h" +#include "dap_chain_datum_decree.h" #define DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_ID 0x13 #define DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_ORDERS 0x14 @@ -36,6 +35,7 @@ typedef struct dap_chain_net_srv_stake_item { bool is_active; dap_chain_net_t *net; + uint256_t locked_value; uint256_t value; dap_chain_addr_t signing_addr; dap_chain_hash_fast_t tx_hash; @@ -58,7 +58,9 @@ typedef struct dap_chain_net_srv_stake_cache_item { } dap_chain_net_srv_stake_cache_item_t; typedef struct dap_chain_net_srv_stake { + dap_chain_net_id_t net_id; uint256_t delegate_allowed_min; + uint256_t delegate_percent_max; dap_chain_net_srv_stake_item_t *itemlist; dap_chain_net_srv_stake_item_t *tx_itemlist; dap_chain_net_srv_stake_cache_item_t *cache; @@ -67,15 +69,18 @@ typedef struct dap_chain_net_srv_stake { int dap_chain_net_srv_stake_pos_delegate_init(); void dap_chain_net_srv_stake_pos_delegate_deinit(); +int dap_chain_net_srv_stake_net_add(dap_chain_net_id_t a_net_id); void dap_chain_net_srv_stake_key_delegate(dap_chain_net_t *a_net, dap_chain_addr_t *a_signing_addr, dap_hash_fast_t *a_stake_tx_hash, uint256_t a_value, dap_chain_node_addr_t *a_node_addr); void dap_chain_net_srv_stake_key_invalidate(dap_chain_addr_t *a_signing_addr); -void dap_chain_net_srv_stake_set_allowed_min_value(uint256_t a_value); -uint256_t dap_chain_net_srv_stake_get_allowed_min_value(); +void dap_chain_net_srv_stake_set_allowed_min_value(dap_chain_net_id_t a_net_id, uint256_t a_value); +uint256_t dap_chain_net_srv_stake_get_allowed_min_value(dap_chain_net_id_t a_net_id); +void dap_chain_net_srv_stake_set_percent_max(dap_chain_net_id_t a_net_id, uint256_t a_value); +uint256_t dap_chain_net_srv_stake_get_percent_max(dap_chain_net_id_t a_net_id); int dap_chain_net_srv_stake_key_delegated(dap_chain_addr_t *a_addr); int dap_chain_net_srv_stake_verify_key_and_node(dap_chain_addr_t* a_signing_addr, dap_chain_node_addr_t* a_node_addr); -dap_list_t *dap_chain_net_srv_stake_get_validators(dap_chain_net_id_t a_net_id, bool a_only_active); +dap_list_t *dap_chain_net_srv_stake_get_validators(dap_chain_net_id_t a_net_id, bool a_only_active, uint16_t **a_excluded_list); bool dap_chain_net_srv_stake_get_fee_validators(dap_chain_net_t *a_net, uint256_t *a_max_fee, uint256_t *a_average_fee, uint256_t *a_min_fee, uint256_t *a_median_fee); @@ -93,5 +98,5 @@ dap_chain_datum_decree_t *dap_chain_net_srv_stake_decree_approve(dap_chain_net_t dap_hash_fast_t *a_stake_tx_hash, dap_cert_t *a_cert); int dap_chain_net_srv_stake_mark_validator_active(dap_chain_addr_t *a_signing_addr, bool a_on_off); -dap_chain_net_srv_stake_item_t *dap_chain_net_srv_stake_check_pkey_hash(dap_hash_fast_t *a_pkey_hash); +dap_chain_net_srv_stake_item_t *dap_chain_net_srv_stake_check_pkey_hash(dap_chain_net_id_t a_net_id, dap_hash_fast_t *a_pkey_hash); uint256_t dap_chain_net_srv_stake_get_total_weight(dap_chain_net_id_t a_net_id); diff --git a/modules/service/voting/CMakeLists.txt b/modules/service/voting/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..544179bc63005255c679a62abb4c059d879096c2 --- /dev/null +++ b/modules/service/voting/CMakeLists.txt @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 3.10) +project (dap_chain_net_srv_voting) + +file(GLOB DAP_SRV_VTNG_SRCS *.c) + +file(GLOB DAP_SRV_VTNG_HEADERS include/*.h) + +add_library(${PROJECT_NAME} STATIC ${DAP_SRV_VTNG_SRCS} ${DAP_SRV_VTNG_HEADERS}) + +target_include_directories(${PROJECT_NAME} INTERFACE .) +target_include_directories(${PROJECT_NAME} PUBLIC include) +target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_chain dap_chain_net dap_chain_net_srv) +target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../../dap-sdk/3rdparty/json-c) + +if (INSTALL_SDK) +set_target_properties(${PROJECT_NAME} PROPERTIES PUBLIC_HEADER "${DAP_SRV_BRG_HEADERS}") +INSTALL(TARGETS ${PROJECT_NAME} + LIBRARY DESTINATION lib/modules/service/voting/ + ARCHIVE DESTINATION lib/modules/service/voting/ + PUBLIC_HEADER DESTINATION include/modules/service/voting/ +) +endif() \ No newline at end of file diff --git a/modules/net/dap_chain_net_voting.c b/modules/service/voting/dap_chain_net_srv_voting.c similarity index 98% rename from modules/net/dap_chain_net_voting.c rename to modules/service/voting/dap_chain_net_srv_voting.c index dde9f80b69df14fb8b08ada49c613772e943b128..ffecdaf7cf139585cbbdf1fed9db023c86084722 100644 --- a/modules/net/dap_chain_net_voting.c +++ b/modules/service/voting/dap_chain_net_srv_voting.c @@ -30,12 +30,13 @@ #include <errno.h> #include <pthread.h> -#include "dap_chain_net_voting.h" +#include "dap_chain_net_srv_voting.h" #include "dap_chain_net_srv_stake_pos_delegate.h" -#include "dap_chain_node_cli.h" +#include "dap_chain_net_tx.h" #include "dap_chain_mempool.h" #include "uthash.h" #include "utlist.h" +#include "dap_cli_server.h" #define LOG_TAG "chain_net_voting" @@ -97,7 +98,24 @@ static bool s_datum_tx_voting_verification_callback(dap_ledger_t *a_ledger, dap_ static bool s_datum_tx_voting_verification_delete_callback(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_type, dap_chain_datum_tx_t *a_tx_in); static int s_cli_voting(int argc, char **argv, void **a_str_reply); -int dap_chain_net_voting_init() +static bool s_tag_check_voting(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_datum_tx_item_groups_t *a_items_grp, dap_chain_tx_tag_action_type_t *a_action) +{ + //voting open + if (a_items_grp->items_voting) { + *a_action = DAP_CHAIN_TX_TAG_ACTION_OPEN; + return true; + } + + //voting use + if (a_items_grp->items_vote) { + *a_action = DAP_CHAIN_TX_TAG_ACTION_USE; + return true; + } + + return false; +} + +int dap_chain_net_srv_voting_init() { pthread_rwlock_init(&s_votings_rwlock, NULL); dap_chain_ledger_voting_verificator_add(s_datum_tx_voting_verification_callback, s_datum_tx_voting_verification_delete_callback); @@ -106,9 +124,19 @@ int dap_chain_net_voting_init() "voting vote -net <net_name> -hash <voting_hash> -option_idx <option_index> [-cert <delegate_cert_name>] -fee <value_datoshi> -w <fee_wallet_name>\n" "voting list -net <net_name>\n" "voting dump -net <net_name> -hash <voting_hash>\n"); + + + dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_VOTING_ID }; + dap_ledger_service_add(l_uid, "voting", s_tag_check_voting); + return 0; } +void dap_chain_net_srv_voting_deinit() +{ + +} + uint64_t* dap_chain_net_voting_get_result(dap_ledger_t* a_ledger, dap_chain_hash_fast_t* a_voting_hash) { if(!a_voting_hash){ @@ -295,7 +323,7 @@ bool s_datum_tx_voting_verification_callback(dap_ledger_t *a_ledger, dap_chain_t dap_sign_get_pkey_hash((dap_sign_t*)l_vote_sig->sig, &pkey_hash); if (l_voting->voting_params.delegate_key_required_offset && *(bool*)((byte_t*)l_voting->voting_params.voting_tx + l_voting->voting_params.delegate_key_required_offset)){ - if (!dap_chain_net_srv_stake_check_pkey_hash(&pkey_hash)){ + if (!dap_chain_net_srv_stake_check_pkey_hash(a_ledger->net->pub.id, &pkey_hash)){ log_it(L_ERROR, "The voting required a delegated key."); dap_list_free(l_signs_list); return false; @@ -998,14 +1026,14 @@ static int s_cli_voting(int a_argc, char **a_argv, void **a_str_reply) DIV_256_COIN(l_results[i].weights, l_total_weight, &l_weight_percentage); MULT_256_COIN(l_weight_percentage, dap_chain_coins_to_balance("100.0"), &l_weight_percentage); - char *l_weight_percentage_str = dap_uint256_decimal_to_round_char(l_weight_percentage, 2, true); - char *l_w_coins, *l_w_datoshi = dap_uint256_to_char(l_results[i].weights, &l_w_coins); + const char *l_weight_percentage_str = dap_uint256_decimal_to_round_char(l_weight_percentage, 2, true); + const char *l_w_coins, *l_w_datoshi = dap_uint256_to_char(l_results[i].weights, &l_w_coins); dap_string_append_printf(l_str_out, "\nVotes: %"DAP_UINT64_FORMAT_U" (%.2f%%)\nWeight: %s (%s) %s (%s%%)\n", l_results[i].num_of_votes, l_percentage, l_w_coins, l_w_datoshi, l_net->pub.native_ticker, l_weight_percentage_str); } DAP_DELETE(l_results); dap_string_append_printf(l_str_out, "\nTotal number of votes: %"DAP_UINT64_FORMAT_U, l_votes_count); - char *l_tw_coins, *l_tw_datoshi = dap_uint256_to_char(l_total_weight, &l_tw_coins); + const char *l_tw_coins, *l_tw_datoshi = dap_uint256_to_char(l_total_weight, &l_tw_coins); dap_string_append_printf(l_str_out, "\nTotal weight: %s (%s) %s\n\n", l_tw_coins, l_tw_datoshi, l_net->pub.native_ticker); dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_out->str); dap_string_free(l_str_out, true); @@ -1420,7 +1448,7 @@ int dap_chain_net_vote_voting(dap_cert_t *a_cert, uint256_t a_fee, dap_chain_wal dap_hash_fast_t l_pkey_hash = {0}; dap_hash_fast(l_pub_key, l_pub_key_size, &l_pkey_hash); - if (!dap_chain_net_srv_stake_check_pkey_hash(&l_pkey_hash)) { + if (!dap_chain_net_srv_stake_check_pkey_hash(a_net->pub.id, &l_pkey_hash)) { return DAP_CHAIN_NET_VOTE_VOTING_KEY_IS_NOT_DELEGATED; } dap_list_t *l_temp = l_voting->votes; diff --git a/modules/net/include/dap_chain_net_voting.h b/modules/service/voting/include/dap_chain_net_srv_voting.h similarity index 89% rename from modules/net/include/dap_chain_net_voting.h rename to modules/service/voting/include/dap_chain_net_srv_voting.h index c045605f3025dcb11a41572d7e05b26bb876d6e9..df90751a3e4fee216a65340f413154f13948caa2 100644 --- a/modules/net/include/dap_chain_net_voting.h +++ b/modules/service/voting/include/dap_chain_net_srv_voting.h @@ -28,6 +28,15 @@ #include "dap_chain_common.h" #include "dap_chain_wallet.h" +#define DAP_CHAIN_NET_SRV_VOTING_ID 0x06 + + +//typedef struct dap_chain_net_vote_info_result { +// uint64_t answer_idx; +// uint64_t votes_count; +//}dap_chain_net_vote_result_t; + + typedef struct dap_chain_net_vote_info_option{ uint64_t option_idx; uint64_t votes_count; @@ -36,7 +45,6 @@ typedef struct dap_chain_net_vote_info_option{ char *description; dap_list_t *hashes_tx_votes; }dap_chain_net_vote_info_option_t; - typedef struct dap_chain_net_vote_info{ dap_hash_fast_t hash; dap_chain_net_id_t net_id; @@ -56,9 +64,8 @@ typedef struct dap_chain_net_vote_info{ } options; }dap_chain_net_vote_info_t; - -int dap_chain_net_voting_init(); - +int dap_chain_net_srv_voting_init(); +void dap_chain_net_srv_voting_deinit(); uint64_t* dap_chain_net_voting_get_result(dap_ledger_t* a_ledger, dap_chain_hash_fast_t* a_voting_hash); @@ -80,9 +87,9 @@ enum DAP_CHAIN_NET_VOTE_CREATE_ERROR { DAP_CHAIN_NET_VOTE_CREATE_CAN_NOT_POOL_DATUM_IN_MEMPOOL }; int dap_chain_net_vote_create(const char *a_question, dap_list_t *a_options, dap_time_t a_expire_vote, - uint64_t a_max_vote, uint256_t a_fee, bool a_delegated_key_required, - bool a_vote_changing_allowed, dap_chain_wallet_t *a_wallet, - dap_chain_net_t *a_net, const char *a_hash_out_type, char **a_hash_output); + uint64_t a_max_vote, uint256_t a_fee, bool a_delegated_key_required, + bool a_vote_changing_allowed, dap_chain_wallet_t *a_wallet, + dap_chain_net_t *a_net, const char *a_hash_out_type, char **a_hash_output); enum DAP_CHAIN_NET_VOTE_VOTING_ERROR{ DAP_CHAIN_NET_VOTE_VOTING_OK, @@ -111,3 +118,4 @@ int dap_chain_net_vote_voting(dap_cert_t *a_cert, uint256_t a_fee, dap_chain_wal dap_list_t *dap_chain_net_vote_list(dap_chain_net_t *a_net); dap_chain_net_vote_info_t *dap_chain_net_vote_extract_info(dap_chain_net_t *a_net, dap_hash_fast_t *a_vote_hash); void dap_chain_net_vote_info_free(dap_chain_net_vote_info_t *a_info); + diff --git a/modules/service/vpn/CMakeLists.txt b/modules/service/vpn/CMakeLists.txt index 04be24a936012b5d8c5276799184d26c8aa01eb4..8f5ffe7b7dc7357f35d716f2af3387147b76aa15 100644 --- a/modules/service/vpn/CMakeLists.txt +++ b/modules/service/vpn/CMakeLists.txt @@ -1,16 +1,20 @@ cmake_minimum_required(VERSION 3.10) project (dap_chain_net_srv_vpn) -file(GLOB DAP_CHAIN_NET_SRV_VPN_SRCS *.c) - -file(GLOB DAP_CHAIN_NET_SRV_VPN_HEADERS include/*.h) if(WIN32) + file(GLOB DAP_CHAIN_NET_SRV_VPN_SRCS *common.c) + file(GLOB DAP_CHAIN_NET_SRV_VPN_HEADERS include/*common.h) + include_directories(../../../os/win32/) include_directories(../3rdparty/wepoll/include/) include_directories(../3rdparty/uthash/src/) include_directories(../../dap-sdk/3rdparty/json-c/) include_directories(../3rdparty/libmagic/src/) +else() + file(GLOB DAP_CHAIN_NET_SRV_VPN_SRCS *.c) + file(GLOB DAP_CHAIN_NET_SRV_VPN_HEADERS include/*.h) + endif() add_library(${PROJECT_NAME} STATIC ${DAP_CHAIN_NET_SRV_VPN_SRCS} ${DAP_CHAIN_NET_SRV_VPN_HEADERS}) @@ -28,4 +32,4 @@ INSTALL(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION lib/modules/service/vpn/ PUBLIC_HEADER DESTINATION include/modules/service/vpn/ ) -endif() \ No newline at end of file +endif() diff --git a/modules/service/vpn/dap_chain_net_srv_vpn.c b/modules/service/vpn/dap_chain_net_srv_vpn.c index 4aaf501d40ee48a5689702f47c1af2df31493afa..500e48001f6760dc3ed0edba8e03ac45745bef33 100644 --- a/modules/service/vpn/dap_chain_net_srv_vpn.c +++ b/modules/service/vpn/dap_chain_net_srv_vpn.c @@ -1690,6 +1690,11 @@ static void s_ch_packet_in_vpn_address_request(dap_stream_ch_t* a_ch, dap_chain_ 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; + ch_vpn_pkt_t *l_vpn_pkt = (ch_vpn_pkt_t*)l_pkt->data; + size_t l_vpn_pkt_size = l_pkt->hdr.data_size; + if (l_vpn_pkt_size < sizeof(l_vpn_pkt->header)) + return false; + dap_chain_net_srv_stream_session_t * l_srv_session = DAP_CHAIN_NET_SRV_STREAM_SESSION (a_ch->stream->session ); dap_chain_net_srv_ch_vpn_t *l_ch_vpn = CH_VPN(a_ch); dap_chain_net_srv_usage_t * l_usage = l_srv_session->usage_active;// dap_chain_net_srv_usage_find_unsafe(l_srv_session, l_ch_vpn->usage_id); @@ -1725,12 +1730,8 @@ static bool s_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg) // TODO move address leasing to this structure //dap_chain_net_srv_vpn_t * l_srv_vpn =(dap_chain_net_srv_vpn_t *) l_usage->service->_internal; - - ch_vpn_pkt_t * l_vpn_pkt = (ch_vpn_pkt_t *) l_pkt->data; - size_t l_vpn_pkt_size = l_pkt->hdr.data_size - sizeof (l_vpn_pkt->header); - + l_vpn_pkt_size -= sizeof (l_vpn_pkt->header); debug_if(s_debug_more, L_INFO, "Got srv_vpn packet with op_code=0x%02x", l_vpn_pkt->header.op_code); - if(l_vpn_pkt->header.op_code >= 0xb0) { // Raw packets switch (l_vpn_pkt->header.op_code) { case VPN_PACKET_OP_CODE_PING: 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 695fb53faab302c846a7b4e92dfdd4daaed08ae1..0cb732427a964a3559b39c63f4afc5bbaa1e4ad4 100644 --- a/modules/service/vpn/dap_chain_net_srv_vpn_cmd.c +++ b/modules/service/vpn/dap_chain_net_srv_vpn_cmd.c @@ -110,7 +110,7 @@ int com_vpn_client(int a_argc, char ** a_argv, void **a_str_reply) // find net dap_chain_net_t *l_net = NULL; - if(dap_chain_node_cli_cmd_values_parse_net_chain(&l_arg_index, a_argc, a_argv, a_str_reply, NULL, &l_net) < 0) + if(dap_chain_node_cli_cmd_values_parse_net_chain(&l_arg_index, a_argc, a_argv, a_str_reply, NULL, &l_net, CHAIN_TYPE_INVALID) < 0) return -2; int cmd_num = CMD_NONE; diff --git a/modules/service/vpn/dap_chain_net_srv_vpn_common.c b/modules/service/vpn/dap_chain_net_srv_vpn_common.c new file mode 100644 index 0000000000000000000000000000000000000000..fbfdc2962bc0283f6ea8b87d59ce98c4148543c3 --- /dev/null +++ b/modules/service/vpn/dap_chain_net_srv_vpn_common.c @@ -0,0 +1,44 @@ + +#include "dap_chain_net_srv_vpn_common.h" +#include "dap_chain_ledger.h" + + +static bool s_tag_check_vpn(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_datum_tx_item_groups_t *a_items_grp, dap_chain_tx_tag_action_type_t *a_action) +{ + + //VPN open: have SRV_PAY out with vpn uid + + if (a_items_grp->items_out_cond_srv_pay) { + dap_chain_tx_out_cond_t *l_cond_out = a_items_grp->items_out_cond_srv_pay->data; + if (l_cond_out->header.srv_uid.uint64 == DAP_CHAIN_NET_SRV_VPN_ID) + if (a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_OPEN; + return true; + } + + //VPN native use: have IN_COND linked with DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY out with vpn uid + + if (a_items_grp->items_in_cond) { + for (dap_list_t *it = a_items_grp->items_in_cond; it; it = it->next) { + dap_chain_tx_in_cond_t *l_tx_in = it->data; + dap_chain_tx_out_cond_t *l_tx_out_cond = dap_chain_ledger_get_tx_out_cond_linked_to_tx_in_cond(a_ledger, l_tx_in); + + if (l_tx_out_cond && + l_tx_out_cond->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY && + l_tx_out_cond->header.srv_uid.uint64 == DAP_CHAIN_NET_SRV_VPN_ID) { + if (a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_USE; + return true; + } + } + } + + return false; +} + + + +int dap_chain_net_srv_vpn_pre_init() +{ + dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_VPN_ID }; + dap_ledger_service_add(l_uid, "vpn", s_tag_check_vpn); + return 0; +} diff --git a/modules/service/vpn/include/dap_chain_net_srv_vpn.h b/modules/service/vpn/include/dap_chain_net_srv_vpn.h index 1fb31f7cb439d11c2cbf83de6972ea6d51c626c6..93698d8b18cbac896b6bf51eb6b4aee025c2dad0 100644 --- a/modules/service/vpn/include/dap_chain_net_srv_vpn.h +++ b/modules/service/vpn/include/dap_chain_net_srv_vpn.h @@ -28,6 +28,7 @@ #include "dap_config.h" #include "dap_chain_net_srv.h" #include "dap_events.h" +#include "dap_chain_net_srv_vpn_common.h" #define DAP_CHAIN_NET_SRV_VPN_CDB_GDB_PREFIX "srv.vpn" @@ -36,8 +37,6 @@ #define DAP_STREAM_CH_NET_SRV_ID_VPN 'S' -#define DAP_CHAIN_NET_SRV_VPN_ID 0x0000000000000001 - #define VPN_PACKET_OP_CODE_CONNECTED 0x000000a9 #define VPN_PACKET_OP_CODE_CONNECT 0x000000aa #define VPN_PACKET_OP_CODE_DISCONNECT 0x000000ab @@ -172,6 +171,7 @@ typedef struct dap_chain_net_srv_vpn int dap_chain_net_srv_client_vpn_init(dap_config_t * g_config); +int dap_chain_net_srv_vpn_pre_init(); int dap_chain_net_srv_vpn_init(dap_config_t * g_config); void dap_chain_net_srv_vpn_deinit(void); diff --git a/modules/service/vpn/include/dap_chain_net_srv_vpn_common.h b/modules/service/vpn/include/dap_chain_net_srv_vpn_common.h new file mode 100644 index 0000000000000000000000000000000000000000..abb3ad778b0fb973d578d8a8150970dc72c32ea3 --- /dev/null +++ b/modules/service/vpn/include/dap_chain_net_srv_vpn_common.h @@ -0,0 +1,4 @@ + +#define DAP_CHAIN_NET_SRV_VPN_ID 0x0000000000000001 + +int dap_chain_net_srv_vpn_pre_init(); diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c index e914b297de5edb4fb1218473cc464a06f1db0457..e366308c2ec35d55f87ff3ca7f94d495f9b46677 100644 --- a/modules/service/xchange/dap_chain_net_srv_xchange.c +++ b/modules/service/xchange/dap_chain_net_srv_xchange.c @@ -34,7 +34,7 @@ #include "dap_time.h" #include "dap_chain_net_srv.h" #include "dap_chain_ledger.h" -#include "dap_chain_node_cli.h" +#include "dap_chain_net_srv_order.h" #include "dap_common.h" #include "dap_hash.h" #include "dap_math_ops.h" @@ -42,11 +42,11 @@ #include "dap_chain_common.h" #include "dap_chain_mempool.h" #include "dap_chain_datum_decree.h" -#include "dap_tsd.h" #include "dap_chain_net_tx.h" #include "dap_chain_net_srv.h" #include "dap_chain_net_srv_xchange.h" #include "uthash.h" +#include "dap_cli_server.h" #define LOG_TAG "dap_chain_net_srv_xchange" @@ -56,13 +56,6 @@ typedef enum tx_opt_status { TX_STATUS_INACTIVE } tx_opt_status_t; -typedef enum xchange_tx_type { - TX_TYPE_UNDEFINED=0, - TX_TYPE_ORDER, - TX_TYPE_EXCHANGE, - TX_TYPE_INVALIDATE -} xchange_tx_type_t; - static dap_chain_net_srv_fee_item_t *s_service_fees = NULL; // Governance statements for networks static pthread_rwlock_t s_service_fees_rwlock = PTHREAD_RWLOCK_INITIALIZER; @@ -77,8 +70,6 @@ static int s_callback_requested(dap_chain_net_srv_t *a_srv, uint32_t a_usage_id, static int s_callback_response_success(dap_chain_net_srv_t *a_srv, uint32_t a_usage_id, dap_chain_net_srv_client_remote_t *a_srv_client, const void *a_data, size_t a_data_size); static int s_callback_response_error(dap_chain_net_srv_t *a_srv, uint32_t a_usage_id, dap_chain_net_srv_client_remote_t *a_srv_client, const void *a_data, size_t a_data_size); static int s_callback_receipt_next_success(dap_chain_net_srv_t *a_srv, uint32_t a_usage_id, dap_chain_net_srv_client_remote_t *a_srv_client, const void *a_data, size_t a_data_size); - -static xchange_tx_type_t s_xchange_tx_get_type (dap_chain_net_t * a_net, dap_chain_datum_tx_t * a_tx, dap_chain_tx_out_cond_t **a_out_cond_item, int *a_item_idx, dap_chain_tx_out_cond_t **a_out_prev_cond_item); static int s_tx_check_for_open_close(dap_chain_net_t * a_net, dap_chain_datum_tx_t * a_tx); static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str, dap_chain_net_t * a_net, dap_chain_datum_tx_t * a_tx, tx_opt_status_t a_filter_by_status, bool a_append_prev_hash, bool a_print_status,bool a_print_ts); dap_chain_net_srv_xchange_price_t *s_xchange_price_from_order(dap_chain_net_t *a_net, dap_chain_datum_tx_t *a_order, uint256_t *a_fee, bool a_ret_is_invalid); @@ -86,6 +77,66 @@ dap_chain_net_srv_xchange_price_t *s_xchange_price_from_order(dap_chain_net_t *a static dap_chain_net_srv_xchange_t *s_srv_xchange; static bool s_debug_more = true; + +static bool s_tag_check_xchange(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_datum_tx_item_groups_t *a_items_grp, dap_chain_tx_tag_action_type_t *a_action) +{ + //check if we have in or out for xchange + + bool have_xchange_out = false; + bool have_xchange_in = false; + if (a_items_grp->items_out_cond_srv_xchange) { + dap_chain_tx_out_cond_t *l_cond_out = a_items_grp->items_out_cond_srv_xchange->data; + if (l_cond_out->header.srv_uid.uint64 == DAP_CHAIN_NET_SRV_XCHANGE_ID) + have_xchange_out = true; + } + + if (a_items_grp->items_in_cond) { + for (dap_list_t *it = a_items_grp->items_in_cond; it; it = it->next) { + dap_chain_tx_in_cond_t *l_tx_in = it->data; + dap_chain_tx_out_cond_t *l_tx_out_cond = dap_chain_ledger_get_tx_out_cond_linked_to_tx_in_cond(a_ledger, l_tx_in); + + if (l_tx_out_cond && + l_tx_out_cond->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE && + l_tx_out_cond->header.srv_uid.uint64 == DAP_CHAIN_NET_SRV_XCHANGE_ID) { + have_xchange_in = true; + } + } + } + + if (have_xchange_in || have_xchange_out) { + //xchange by xchange module + xchange_tx_type_t type = dap_chain_net_srv_xchange_tx_get_type(a_ledger, a_tx, NULL, NULL, NULL); + switch(type) + { + case TX_TYPE_ORDER: + { + if(a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_OPEN; + return true; + } + + case TX_TYPE_EXCHANGE: + { + if(a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_USE; + return true; + } + + case TX_TYPE_INVALIDATE: + { + if(a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_CLOSE; + return true; + } + default: + { + if(a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_UNKNOWN; + return false; + } + } + } + + return false; + +} + /** * @brief dap_chain_net_srv_xchange_init Init actions for xchanger stream channel * @return 0 if everything is okay, lesser then zero if errors @@ -136,6 +187,10 @@ int dap_chain_net_srv_xchange_init() l_srv_callbacks.receipt_next_success = s_callback_receipt_next_success; l_srv_callbacks.decree = s_callback_decree; + //register service for tagging + dap_ledger_service_add(l_uid, "xchange", s_tag_check_xchange); + + dap_chain_net_srv_t* l_srv = dap_chain_net_srv_add(l_uid, "srv_xchange", &l_srv_callbacks); s_srv_xchange = DAP_NEW_Z(dap_chain_net_srv_xchange_t); if (!s_srv_xchange || !l_srv) { @@ -210,7 +265,7 @@ static bool s_xchange_verificator_callback(dap_ledger_t *a_ledger, dap_chain_tx_ byte_t * l_tx_item; dap_chain_addr_t l_service_fee_addr, *l_seller_addr = &a_tx_out_cond->subtype.srv_xchange.seller_addr; - uint16_t l_service_fee_type; + uint16_t l_service_fee_type = 0; dap_chain_net_t *l_net = a_ledger->net; bool l_service_fee_used = dap_chain_net_srv_xchange_get_fee(l_net->pub.id, &l_service_fee_val, &l_service_fee_addr, &l_service_fee_type); const char *l_native_ticker = l_net->pub.native_ticker; @@ -647,7 +702,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha l_datoshi_buy = a_datoshi_buy; if (s_debug_more) { - char *l_datoshi_sell_str; dap_uint256_to_char(l_datoshi_sell, &l_datoshi_sell_str); + const char *l_datoshi_sell_str; dap_uint256_to_char(l_datoshi_sell, &l_datoshi_sell_str); log_it(L_NOTICE, "l_value_sell = %s %s", l_datoshi_sell_str, a_price->token_sell); } @@ -671,14 +726,14 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha } // transfer unselling coins (partial exchange) if (s_debug_more) { - char *l_value_str; dap_uint256_to_char(l_tx_out_cond->header.value, &l_value_str); + const char *l_value_str; dap_uint256_to_char(l_tx_out_cond->header.value, &l_value_str); log_it(L_NOTICE, "l_value_cond = %s", l_value_str); } if (compare256(l_tx_out_cond->header.value, l_datoshi_sell) == 1) { SUBTRACT_256_256(l_tx_out_cond->header.value, l_datoshi_sell, &l_value_back); if (s_debug_more) { - char *l_value_back_str; dap_uint256_to_char(l_value_back, &l_value_back_str); + const char *l_value_back_str; dap_uint256_to_char(l_value_back, &l_value_back_str); log_it(L_NOTICE, "l_value_unselled = %s", l_value_back_str); } @@ -703,7 +758,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha return NULL; } if (s_debug_more) { - char *l_buy_str; dap_uint256_to_char(l_datoshi_buy, &l_buy_str); + const char *l_buy_str; dap_uint256_to_char(l_datoshi_buy, &l_buy_str); log_it(L_NOTICE, "l_value_buy = %s %s", l_buy_str, a_price->token_buy); } @@ -715,7 +770,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha return NULL; } if (s_debug_more) { - char *l_fee_str; dap_uint256_to_char(a_datoshi_fee, &l_fee_str); + const char *l_fee_str; dap_uint256_to_char(a_datoshi_fee, &l_fee_str); log_it (L_NOTICE, "l_validator_fee = %s", l_fee_str); } } @@ -727,7 +782,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha return NULL; } if (s_debug_more) { - char *l_net_fee_str; dap_uint256_to_char(l_net_fee, &l_net_fee_str); + const char *l_net_fee_str; dap_uint256_to_char(l_net_fee, &l_net_fee_str); log_it(L_NOTICE, "l_net_fee = %s", l_net_fee_str); } } @@ -739,7 +794,7 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha return NULL; } if (s_debug_more) { - char *l_srv_fee_str; dap_uint256_to_char(l_service_fee, &l_srv_fee_str); + const char *l_srv_fee_str; dap_uint256_to_char(l_service_fee, &l_srv_fee_str); log_it(L_NOTICE, "l_service_fee = %s %s", l_srv_fee_str, l_service_ticker ? l_service_ticker : "<undefined>"); } @@ -754,9 +809,9 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha } } if (s_debug_more) { - char *l_value_transfer_str; dap_uint256_to_char(l_value_transfer, &l_value_transfer_str); + const char *l_value_transfer_str; dap_uint256_to_char(l_value_transfer, &l_value_transfer_str); log_it(L_NOTICE, "l_value_transfer = %s", l_value_transfer_str); - char *l_value_back_str; dap_uint256_to_char(l_value_back, &l_value_back_str); + const char *l_value_back_str; dap_uint256_to_char(l_value_back, &l_value_back_str); log_it(L_NOTICE, "l_value_back = %s", l_value_back_str); } // fee back @@ -770,9 +825,9 @@ static dap_chain_datum_tx_t *s_xchange_tx_create_exchange(dap_chain_net_srv_xcha } } if (s_debug_more) { - char *l_fee_transfer_str; dap_uint256_to_char(l_fee_transfer, &l_fee_transfer_str); + const char *l_fee_transfer_str; dap_uint256_to_char(l_fee_transfer, &l_fee_transfer_str); log_it(L_NOTICE, "l_fee_transfer = %s", l_fee_transfer_str); - char *l_val_back_str; dap_uint256_to_char(l_value_back, &l_val_back_str); + const char *l_val_back_str; dap_uint256_to_char(l_value_back, &l_val_back_str); log_it(L_NOTICE, "l_cashback = %s", l_val_back_str); } } @@ -834,7 +889,7 @@ uint64_t dap_chain_net_srv_xchange_get_order_completion_rate(dap_chain_net_t *a_ MULT_256_COIN(l_percent_completed, dap_chain_coins_to_balance("100.0"), &l_percent_completed); } else { dap_chain_tx_out_cond_t *l_out_prev_cond_item = NULL; - xchange_tx_type_t tx_type = s_xchange_tx_get_type(a_net, l_last_tx, NULL, NULL, &l_out_prev_cond_item); + xchange_tx_type_t tx_type = dap_chain_net_srv_xchange_tx_get_type(a_net->pub.ledger, l_last_tx, NULL, NULL, &l_out_prev_cond_item); if (tx_type == TX_TYPE_EXCHANGE){ SUBTRACT_256_256(l_out_cond->header.value, uint256_0, &l_percent_completed); DIV_256_COIN(l_percent_completed, l_out_cond->header.value, &l_percent_completed); @@ -1328,7 +1383,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v dap_chain_datum_tx_t * l_tx = dap_chain_net_get_tx_by_hash(l_net, &l_order_tx_hash, TX_SEARCH_TYPE_NET); if( l_tx){ - xchange_tx_type_t l_tx_type = s_xchange_tx_get_type(l_net, l_tx, NULL, NULL, NULL); + xchange_tx_type_t l_tx_type = dap_chain_net_srv_xchange_tx_get_type(l_net->pub.ledger, l_tx, NULL, NULL, NULL); char *l_tx_hash = dap_chain_hash_fast_to_str_new(&l_order_tx_hash); if(l_tx_type != TX_TYPE_ORDER){ dap_cli_server_cmd_set_reply_text(a_str_reply, "Datum with hash %s is not order. Check hash.", l_tx_hash); @@ -1507,7 +1562,7 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v 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_amount_coins_str = "0.0", *l_amount_datoshi_str = "0"; + const char *l_amount_coins_str = NULL, *l_amount_datoshi_str = NULL; uint64_t l_percent_completed = dap_chain_net_srv_xchange_get_order_completion_rate(l_net, l_order_tx_hash); @@ -1518,10 +1573,8 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, l_ts_create); l_tmp_buf[strlen(l_tmp_buf) - 1] = '\0'; - if (l_out_cond_last_tx) { + if (l_out_cond_last_tx) l_amount_datoshi_str = dap_uint256_to_char(l_out_cond_last_tx->header.value, &l_amount_coins_str); - } - dap_cli_server_cmd_set_reply_text(a_str_reply, "orderHash: %s\n ts_created: %s (%"DAP_UINT64_FORMAT_U")\n Status: %s, amount: %s (%s) %s, filled: %lu%%, rate (%s/%s): %s, net: %s\n\n", dap_chain_hash_fast_to_str_static(&l_tx_hash), @@ -1533,6 +1586,9 @@ static int s_cli_srv_xchange_order(int a_argc, char **a_argv, int a_arg_index, v l_cp_rate, l_price->net->pub.name); + + DAP_DEL_Z(l_amount_coins_str); + DAP_DEL_Z(l_amount_datoshi_str); DAP_DEL_Z(l_cp_rate); DAP_DEL_Z(l_price); } break; @@ -1584,7 +1640,7 @@ static bool s_filter_tx_list(dap_chain_datum_t *a_datum, dap_chain_t *a_chain, v return false; } -static xchange_tx_type_t s_xchange_tx_get_type (dap_chain_net_t * a_net, dap_chain_datum_tx_t * a_tx, dap_chain_tx_out_cond_t **a_out_cond_item, int *a_item_idx, dap_chain_tx_out_cond_t **a_out_prev_cond_item) +xchange_tx_type_t dap_chain_net_srv_xchange_tx_get_type (dap_ledger_t * a_ledger, dap_chain_datum_tx_t * a_tx, dap_chain_tx_out_cond_t **a_out_cond_item, int *a_item_idx, dap_chain_tx_out_cond_t **a_out_prev_cond_item) { int l_tx_type = TX_TYPE_UNDEFINED; @@ -1597,29 +1653,43 @@ static xchange_tx_type_t s_xchange_tx_get_type (dap_chain_net_t * a_net, dap_cha byte_t *l_tx_item = dap_chain_datum_tx_item_get(a_tx, &l_item_idx, TX_ITEM_TYPE_IN_COND , NULL); dap_chain_tx_in_cond_t * l_in_cond = l_tx_item ? (dap_chain_tx_in_cond_t *) l_tx_item : NULL; int l_prev_cond_idx = 0; - dap_chain_datum_tx_t * l_prev_tx = l_in_cond ? dap_ledger_tx_find_by_hash(a_net->pub.ledger, &l_in_cond->header.tx_prev_hash) : NULL; + dap_chain_datum_tx_t * l_prev_tx = l_in_cond ? dap_ledger_tx_find_by_hash(a_ledger, &l_in_cond->header.tx_prev_hash) : NULL; dap_chain_tx_out_cond_t *l_out_prev_cond_item = l_prev_tx ? dap_chain_datum_tx_out_cond_get(l_prev_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, &l_prev_cond_idx) : NULL; if(l_out_prev_cond_item && l_out_prev_cond_item->header.subtype != DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE) return l_tx_type; - + + if (l_in_cond && l_prev_cond_idx >= 0 && (uint32_t)l_prev_cond_idx != l_in_cond->header.tx_out_prev_idx) + return l_tx_type; + if (l_out_cond_item && !l_out_prev_cond_item) l_tx_type = TX_TYPE_ORDER; else if (l_out_cond_item && l_out_prev_cond_item) + { l_tx_type = TX_TYPE_EXCHANGE; - else if (!l_out_cond_item && l_out_prev_cond_item){ + } + else if (!l_out_cond_item && l_out_prev_cond_item) + { dap_chain_datum_tx_t * l_prev_tx_temp = a_tx; byte_t *l_tx_item_temp = NULL; - while((l_tx_item_temp = dap_chain_datum_tx_item_get(l_prev_tx_temp, &l_item_idx, TX_ITEM_TYPE_IN_COND , NULL)) != NULL){ + while((l_tx_item_temp = dap_chain_datum_tx_item_get(l_prev_tx_temp, &l_item_idx, TX_ITEM_TYPE_IN_COND , NULL)) != NULL) + { dap_chain_tx_in_cond_t * l_in_cond_temp = (dap_chain_tx_in_cond_t *) l_tx_item_temp; - l_prev_tx_temp = dap_ledger_tx_find_by_hash(a_net->pub.ledger, &l_in_cond_temp->header.tx_prev_hash); + l_prev_tx_temp = dap_ledger_tx_find_by_hash(a_ledger, &l_in_cond_temp->header.tx_prev_hash); } - dap_chain_tx_sig_t *l_tx_prev_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(l_prev_tx_temp, NULL, TX_ITEM_TYPE_SIG, NULL); - dap_sign_t *l_prev_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_prev_sig); - dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_SIG, NULL); - dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_sig); + //have to find EXCHANGE tx_out_cond! + l_out_cond_item = NULL; + l_out_cond_item = dap_chain_datum_tx_out_cond_get(l_prev_tx_temp, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE, + &l_cond_idx); + if (!l_out_cond_item) { + l_tx_type = TX_TYPE_UNDEFINED; + } else { + dap_chain_tx_sig_t *l_tx_prev_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(l_prev_tx_temp, NULL, TX_ITEM_TYPE_SIG, NULL); + dap_sign_t *l_prev_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_prev_sig); + dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_SIG, NULL); + dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_sig); bool l_owner = false; l_owner = dap_sign_compare_pkeys(l_prev_sign,l_sign); @@ -1627,14 +1697,16 @@ static xchange_tx_type_t s_xchange_tx_get_type (dap_chain_net_t * a_net, dap_cha l_tx_type = TX_TYPE_INVALIDATE; else l_tx_type = TX_TYPE_EXCHANGE; - } + } - if(a_out_cond_item) - *a_out_cond_item = l_out_cond_item; - if(a_out_prev_cond_item) - *a_out_prev_cond_item = l_out_prev_cond_item; - if (a_item_idx) - *a_item_idx = l_cond_idx; + if(a_out_cond_item) + *a_out_cond_item = l_out_cond_item; + if(a_out_prev_cond_item) + *a_out_prev_cond_item = l_out_prev_cond_item; + if (a_item_idx) + *a_item_idx = l_cond_idx; + return l_tx_type; + } return l_tx_type; } @@ -1702,7 +1774,7 @@ static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str, dap_chain_tx_out_cond_t *l_out_cond_item = NULL; int l_cond_idx = 0; - xchange_tx_type_t l_tx_type = s_xchange_tx_get_type(a_net, a_tx, &l_out_cond_item, &l_cond_idx, &l_out_prev_cond_item); + xchange_tx_type_t l_tx_type = dap_chain_net_srv_xchange_tx_get_type(a_net->pub.ledger, a_tx, &l_out_cond_item, &l_cond_idx, &l_out_prev_cond_item); bool l_is_closed = dap_ledger_tx_hash_is_used_out_item(a_net->pub.ledger, &l_tx_hash, l_cond_idx, NULL); if ((a_filter_by_status == TX_STATUS_ACTIVE && l_is_closed) || (a_filter_by_status == TX_STATUS_INACTIVE && !l_is_closed)) @@ -1713,9 +1785,8 @@ static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str, switch(l_tx_type){ case TX_TYPE_ORDER:{ - char *l_rate_str = dap_chain_balance_to_coins(l_out_cond_item->subtype.srv_xchange.rate), - *l_amount_str, - *l_amount_datoshi_str = dap_uint256_to_char(l_out_cond_item->header.value, &l_amount_str); + char *l_rate_str = dap_chain_balance_to_coins(l_out_cond_item->subtype.srv_xchange.rate); + const char *l_amount_str, *l_amount_datoshi_str = dap_uint256_to_char(l_out_cond_item->header.value, &l_amount_str); dap_string_append_printf(a_reply_str, "Hash: %s\n", l_tx_hash_str); if(a_print_ts){ @@ -1760,19 +1831,20 @@ static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str, if(a_print_status) dap_string_append_printf(a_reply_str, " Status: %s,", l_is_closed ? "inactive" : "active"); - char *l_value_from_str, *l_value_from_datoshi_str = dap_uint256_to_char(l_value_from, &l_value_from_str); + const char *l_value_from_str, *l_value_from_datoshi_str = dap_uint256_to_char(l_value_from, &l_value_from_str); dap_string_append_printf(a_reply_str, " changed %s (%s) %s", l_value_from_str, l_value_from_datoshi_str, l_tx_input_ticker); - char *l_value_to_str, *l_value_to_datoshi_str = dap_uint256_to_char(l_value_to, &l_value_to_str); + const char *l_value_to_str, *l_value_to_datoshi_str = dap_uint256_to_char(l_value_to, &l_value_to_str); dap_string_append_printf(a_reply_str, " for %s (%s) %s,", l_value_to_str, l_value_to_datoshi_str, l_buy_ticker); - char *l_rate_str; dap_uint256_to_char(l_rate, &l_rate_str); + const char *l_rate_str; dap_uint256_to_char(l_rate, &l_rate_str); dap_string_append_printf(a_reply_str, " rate (%s/%s): %s,", l_buy_ticker, l_tx_input_ticker, l_rate_str); - char *l_amount_str = "0.0", + const char *l_amount_str = NULL, *l_amount_datoshi_str = l_out_cond_item ? dap_uint256_to_char(l_out_cond_item->header.value, &l_amount_str) : "0"; - dap_string_append_printf(a_reply_str, " remain amount %s (%s) %s, net: %s", l_amount_str, l_amount_datoshi_str, l_tx_input_ticker, a_net->pub.name); - if(a_print_prev_hash) + dap_string_append_printf(a_reply_str, " remain amount %s (%s) %s, net: %s", l_amount_str ? l_amount_str : "0.0", + l_amount_datoshi_str, l_tx_input_ticker, a_net->pub.name); + if (a_print_prev_hash) dap_string_append_printf(a_reply_str, "\n Prev cond: %s", l_tx_prev_cond_hash_str); } break; case TX_TYPE_INVALIDATE:{ @@ -1810,6 +1882,9 @@ static bool s_string_append_tx_cond_info( dap_string_t * a_reply_str, dap_string_append_printf(a_reply_str, " returned %s(%s) %s to owner from order %s", l_value_from_str, l_value_from_datoshi_str, l_tx_input_ticker, l_order_hash_str); if(a_print_prev_hash) dap_string_append_printf(a_reply_str, "\n Prev cond: %s", l_tx_prev_cond_hash_str); + + DAP_DELETE(l_value_from_str); + DAP_DELETE(l_value_from_datoshi_str); } break; default: return false; } @@ -1958,27 +2033,25 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply) const char *l_offset_str = NULL; dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-limit", &l_limit_str); dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-offset", &l_offset_str); - size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 0; + size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 1000; size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0; - size_t l_arr_start = 0; - if (l_limit > 1) { - l_arr_start = l_limit * l_offset; - } + size_t l_arr_start = 0; size_t l_arr_end = dap_list_length(l_tx_list); - if (l_offset) { + if (l_offset > 0) { + l_arr_start = l_offset; + dap_string_append_printf(l_reply_str, "offset: %lu\n", l_arr_start); + } + if (l_limit) { + dap_string_append_printf(l_reply_str, "limit: %lu\n", l_limit); l_arr_end = l_arr_start + l_limit; if (l_arr_end > dap_list_length(l_tx_list)) { l_arr_end = dap_list_length(l_tx_list); } - } + } size_t i_tmp = 0; // Print all txs for (dap_list_t *it = l_tx_list; it; it = it->next) { - if (i_tmp < l_arr_start || i_tmp > l_arr_end) { - i_tmp++; - continue; - } - i_tmp++; + dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)it->data; dap_chain_tx_out_cond_t *l_out_cond = dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE , NULL); if (!l_out_cond || l_out_cond->header.srv_uid.uint64 != DAP_CHAIN_NET_SRV_XCHANGE_ID) @@ -2023,6 +2096,11 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply) l_status_order = "OPENED"; } + if (i_tmp < l_arr_start || i_tmp >= l_arr_end) { + i_tmp++; + continue; + } + i_tmp++; dap_hash_fast_t l_tx_hash = {}; dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_tx_hash); const char *l_tx_hash_str = dap_chain_hash_fast_to_str_static(&l_tx_hash); @@ -2036,8 +2114,8 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply) l_cp_rate = dap_chain_balance_to_coins(l_price->rate); - char *l_amount_coins_str = "0.0", - *l_amount_datoshi_str = l_out_cond_last_tx ? dap_uint256_to_char(l_out_cond_last_tx->header.value, &l_amount_coins_str) : "0"; + const char *l_amount_coins_str = NULL, + *l_amount_datoshi_str = l_out_cond_last_tx ? dap_uint256_to_char(l_out_cond_last_tx->header.value, &l_amount_coins_str) : NULL; dap_string_append_printf(l_reply_str, "orderHash: %s\n ts_created: %s (%"DAP_UINT64_FORMAT_U")\n Status: %s, amount: %s (%s) %s, filled: %lu%%, rate (%s/%s): %s, net: %s\n\n", l_tx_hash_str, l_tmp_buf, l_ts_create, l_status_order, l_amount_coins_str ? l_amount_coins_str : "0.0", @@ -2298,7 +2376,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply) int l_cond_idx = 0; dap_chain_tx_out_cond_t *l_out_cond_item = NULL; - if (s_xchange_tx_get_type(l_net, l_tx, &l_out_cond_item, &l_cond_idx, NULL) != TX_TYPE_ORDER){ + if (dap_chain_net_srv_xchange_tx_get_type(l_net->pub.ledger, l_tx, &l_out_cond_item, &l_cond_idx, NULL) != TX_TYPE_ORDER){ l_cur = dap_list_next(l_cur); continue; } @@ -2341,9 +2419,9 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply) char l_tmp_buf[DAP_TIME_STR_SIZE]; dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, l_last_rate_time); l_tmp_buf[strlen(l_tmp_buf) - 1] = '\0'; - char *l_rate_average_str; dap_uint256_to_char(l_rate_average, &l_rate_average_str); + const char *l_rate_average_str; dap_uint256_to_char(l_rate_average, &l_rate_average_str); dap_string_append_printf(l_reply_str,"Average rate: %s \r\n", l_rate_average_str); - char *l_last_rate_str; dap_uint256_to_char(l_rate, &l_last_rate_str); + const char *l_last_rate_str; dap_uint256_to_char(l_rate, &l_last_rate_str); dap_string_append_printf(l_reply_str, "Last rate: %s Last rate time: %s (%"DAP_UINT64_FORMAT_U")", l_last_rate_str, l_tmp_buf, l_last_rate_time); *a_str_reply = dap_string_free(l_reply_str, false); @@ -2352,7 +2430,7 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply) const char *l_limit_str = NULL, *l_offset_str = NULL; dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-limit", &l_limit_str); dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-offset", &l_offset_str); - size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 0; + size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 1000; size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0; dap_string_t *l_reply_str = dap_string_new(""); @@ -2370,22 +2448,19 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply) } size_t l_arr_start = 0; size_t l_arr_end = l_datum_num; - if (l_offset > 1) { - l_arr_start = l_limit * l_offset; + if (l_offset > 0) { + l_arr_start = l_offset; + dap_string_append_printf(l_reply_str, "offset: %lu\n", l_arr_start); } if (l_limit) { l_arr_end = l_arr_start + l_limit; + dap_string_append_printf(l_reply_str, "limit: %lu\n", l_limit); } size_t i_tmp = 0; dap_list_t * l_cur = l_datum_list0; while(l_cur){ - if (i_tmp < l_arr_start || i_tmp > l_arr_end) { - i_tmp++; - l_cur = dap_list_next(l_cur); - continue; - } - i_tmp++; + dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*) ((dap_chain_datum_t*) l_cur->data)->data; if(l_tx){ dap_hash_fast_t l_tx_hash = {}; @@ -2417,6 +2492,12 @@ static int s_cli_srv_xchange(int a_argc, char **a_argv, void **a_str_reply) l_cur = dap_list_next(l_cur); continue; } + if (i_tmp < l_arr_start || i_tmp >= l_arr_end) { + i_tmp++; + l_cur = dap_list_next(l_cur); + continue; + } + i_tmp++; s_string_append_tx_cond_info(l_reply_str, l_net, l_tx, TX_STATUS_ALL, false, false, true); } @@ -2525,7 +2606,7 @@ json_object *dap_chain_net_srv_xchange_print_fee_json(dap_chain_net_t *a_net) { dap_chain_addr_t l_addr = {0}; uint16_t l_type = 0; if (dap_chain_net_srv_xchange_get_fee(a_net->pub.id, &l_fee, &l_addr, &l_type)) { - char *l_fee_coins, *l_fee_balance = dap_uint256_to_char(l_fee, &l_fee_coins); + const char *l_fee_coins, *l_fee_balance = dap_uint256_to_char(l_fee, &l_fee_coins); json_object *l_jobj_xchange = json_object_new_object(); json_object_object_add(l_jobj_xchange, "coin", json_object_new_string(l_fee_coins)); json_object_object_add(l_jobj_xchange, "balance", json_object_new_string(l_fee_balance)); @@ -2544,7 +2625,7 @@ void dap_chain_net_srv_xchange_print_fee(dap_chain_net_t *a_net, dap_string_t *a dap_chain_addr_t l_addr = {0}; uint16_t l_type = 0; if (dap_chain_net_srv_xchange_get_fee(a_net->pub.id, &l_fee, &l_addr, &l_type)) { - char *l_fee_coins, *l_fee_balance = dap_uint256_to_char(l_fee, &l_fee_coins); + const char *l_fee_coins, *l_fee_balance = dap_uint256_to_char(l_fee, &l_fee_coins); dap_string_append_printf(a_string_ret, "\txchange:\n" "\t\tFee: %s (%s)\n" "\t\tAddr: %s\n" diff --git a/modules/service/xchange/include/dap_chain_net_srv_xchange.h b/modules/service/xchange/include/dap_chain_net_srv_xchange.h index d6eae10743f4e60d17fcfd12a64121568f79ae1e..9cff53d974fe3c6f960c663dc272c196e81d07c2 100644 --- a/modules/service/xchange/include/dap_chain_net_srv_xchange.h +++ b/modules/service/xchange/include/dap_chain_net_srv_xchange.h @@ -25,7 +25,8 @@ #pragma once #include "dap_chain_net_srv.h" -#include "dap_chain_net_srv_order.h" +#include "dap_chain_wallet.h" +#include "dap_chain_datum_tx_out_cond.h" #define DAP_CHAIN_NET_SRV_XCHANGE_ID 0x2 #define GROUP_LOCAL_XCHANGE "local.xchange" @@ -77,7 +78,7 @@ typedef enum dap_chain_net_srv_xchange_create_error_list{ XCHANGE_CREATE_ERROR_MEMORY_ALLOCATED, XCHANGE_CREATE_ERROR_CAN_NOT_COMPOSE_THE_CONDITIONAL_TRANSACTION, XCHANGE_CREATE_ERROR_CAN_NOT_PUT_TRANSACTION_TO_MEMPOOL, -}dap_chain_net_srv_xchange_create_error_t; +} dap_chain_net_srv_xchange_create_error_t; dap_chain_net_srv_xchange_create_error_t dap_chain_net_srv_xchange_create(dap_chain_net_t *a_net, const char *a_token_buy, const char *a_token_sell, uint256_t a_datoshi_sell, uint256_t a_rate, uint256_t a_fee, dap_chain_wallet_t *a_wallet, @@ -90,7 +91,7 @@ typedef enum dap_chain_net_srv_xchange_remove_error_list{ XCHANGE_REMOVE_ERROR_CAN_NOT_FIND_TX, XCHANGE_REMOVE_ERROR_CAN_NOT_CREATE_PRICE, XCHANGE_REMOVE_ERROR_CAN_NOT_INVALIDATE_TX -}dap_chain_net_srv_xchange_remove_error_t; +} dap_chain_net_srv_xchange_remove_error_t; dap_chain_net_srv_xchange_remove_error_t dap_chain_net_srv_xchange_remove(dap_chain_net_t *a_net, dap_hash_fast_t *a_hash_tx, uint256_t a_fee, dap_chain_wallet_t *a_wallet, char **a_out_hash_tx); @@ -103,7 +104,7 @@ typedef enum dap_chain_net_srv_xchange_purchase_error_list{ XCHANGE_PURCHASE_ERROR_SPECIFIED_ORDER_NOT_FOUND, XCHANGE_PURCHASE_ERROR_CAN_NOT_CREATE_PRICE, XCHANGE_PURCHASE_ERROR_CAN_NOT_CREATE_EXCHANGE_TX, -}dap_chain_net_srv_xchange_purchase_error_t; +} dap_chain_net_srv_xchange_purchase_error_t; dap_chain_net_srv_xchange_purchase_error_t dap_chain_net_srv_xchange_purchase(dap_chain_net_t *a_net, dap_hash_fast_t *a_order_hash, uint256_t a_value, uint256_t a_fee, dap_chain_wallet_t *a_wallet, char **a_hash_out); @@ -113,6 +114,15 @@ typedef enum dap_chain_net_srv_xchange_order_status{ XCHANGE_ORDER_STATUS_OPENED = 0, XCHANGE_ORDER_STATUS_CLOSED, XCHANGE_ORDER_STATUS_UNKNOWN, -}dap_chain_net_srv_xchange_order_status_t; +} dap_chain_net_srv_xchange_order_status_t; + +typedef enum xchange_tx_type{ + TX_TYPE_UNDEFINED=0, + TX_TYPE_ORDER, + TX_TYPE_EXCHANGE, + TX_TYPE_INVALIDATE +} xchange_tx_type_t; + dap_chain_net_srv_xchange_order_status_t dap_chain_net_srv_xchange_get_order_status(dap_chain_net_t *a_net, dap_hash_fast_t a_order_tx_hash); bool dap_chain_net_srv_xchange_get_fee(dap_chain_net_id_t a_net_id, uint256_t *a_fee, dap_chain_addr_t *a_addr, uint16_t *a_type); +xchange_tx_type_t dap_chain_net_srv_xchange_tx_get_type (dap_ledger_t * a_ledger, dap_chain_datum_tx_t * a_tx, dap_chain_tx_out_cond_t **a_out_cond_item, int *a_item_idx, dap_chain_tx_out_cond_t **a_out_prev_cond_item); diff --git a/modules/type/blocks/dap_chain_block.c b/modules/type/blocks/dap_chain_block.c index 244f990165fcee593e212f771d3ffb4caf3c0303..42139e022a670e7c3bdbf3e381f9b7c91cc503b7 100644 --- a/modules/type/blocks/dap_chain_block.c +++ b/modules/type/blocks/dap_chain_block.c @@ -21,13 +21,11 @@ along with any DAP SDK based project. If not, see <http://www.gnu.org/licenses/>. */ #include <stddef.h> -#include "string.h" #include "dap_common.h" #include "dap_config.h" #include "dap_hash.h" #include "dap_uuid.h" #include "dap_chain_block.h" -#include "dap_chain_block_cache.h" #define LOG_TAG "dap_chain_block" @@ -484,49 +482,65 @@ size_t dap_chain_block_meta_add(dap_chain_block_t ** a_block_ptr, size_t a_block return a_block_size + l_add_size; } +static const char *s_meta_type_to_string(uint8_t a_meta_type) +{ + switch (a_meta_type) { + case DAP_CHAIN_BLOCK_META_GENESIS: return "GENESIS"; + case DAP_CHAIN_BLOCK_META_PREV: return "PREV"; + case DAP_CHAIN_BLOCK_META_ANCHOR: return "ANCHOR"; + case DAP_CHAIN_BLOCK_META_LINK: return "LINK"; + case DAP_CHAIN_BLOCK_META_NONCE: return "NONCE"; + case DAP_CHAIN_BLOCK_META_NONCE2: return "NONCE2"; + case DAP_CHAIN_BLOCK_META_MERKLE: return "MERKLE_ROOT"; + case DAP_CHAIN_BLOCK_META_EMERGENCY: return "EMERGENCY"; + case DAP_CHAIN_BLOCK_META_SYNC_ATTEMPT: return "SYNC_ATTEMPT"; + case DAP_CHAIN_BLOCK_META_ROUND_ATTEMPT: return "ROUND_ATTEMPT"; + case DAP_CHAIN_BLOCK_META_EXCLUDED_KEYS: return "EXCLUDED_KEYS"; + default: return "UNNOWN"; + } +} + static uint8_t *s_meta_extract(dap_chain_block_meta_t *a_meta) { switch (a_meta->hdr.type) { case DAP_CHAIN_BLOCK_META_GENESIS: + case DAP_CHAIN_BLOCK_META_EMERGENCY: if (a_meta->hdr.data_size == 0) return DAP_INT_TO_POINTER(1); + log_it(L_WARNING, "Meta %s has wrong size %hu when expecting zero size", + s_meta_type_to_string(a_meta->hdr.type), a_meta->hdr.data_size); break; case DAP_CHAIN_BLOCK_META_PREV: - if (a_meta->hdr.data_size == sizeof(dap_hash_t)) - return a_meta->data; - else - log_it(L_WARNING, "Meta PREV has wrong size %hu when expecting %zu", a_meta->hdr.data_size, sizeof(dap_hash_t)); - break; case DAP_CHAIN_BLOCK_META_ANCHOR: - if (a_meta->hdr.data_size == sizeof(dap_hash_t)) - return a_meta->data; - else - log_it(L_WARNING, "Anchor meta has wrong size %hu when expecting %zu", a_meta->hdr.data_size, sizeof(dap_hash_t)); - break; case DAP_CHAIN_BLOCK_META_LINK: + case DAP_CHAIN_BLOCK_META_MERKLE: if (a_meta->hdr.data_size == sizeof(dap_hash_t)) return a_meta->data; - else - log_it(L_WARNING, "Link meta has wrong size %hu when expecting %zu", a_meta->hdr.data_size, sizeof(dap_hash_t)); + log_it(L_WARNING, "Meta %s has wrong size %hu when expecting %zu", + s_meta_type_to_string(a_meta->hdr.type), a_meta->hdr.data_size, sizeof(dap_hash_t)); break; case DAP_CHAIN_BLOCK_META_NONCE: - if (a_meta->hdr.data_size == sizeof(uint64_t)) - return a_meta->data; - else - log_it(L_WARNING, "NONCE meta has wrong size %hu when expecting %zu", a_meta->hdr.data_size, sizeof(uint64_t)); - break; case DAP_CHAIN_BLOCK_META_NONCE2: + case DAP_CHAIN_BLOCK_META_SYNC_ATTEMPT: if (a_meta->hdr.data_size == sizeof(uint64_t)) return a_meta->data; - else - log_it(L_WARNING, "NONCE2 meta has wrong size %hu when expecting %zu", a_meta->hdr.data_size, sizeof(uint64_t)); + log_it(L_WARNING, "Meta %s has wrong size %hu when expecting %zu", + s_meta_type_to_string(a_meta->hdr.type), a_meta->hdr.data_size, sizeof(uint64_t)); break; - case DAP_CHAIN_BLOCK_META_MERKLE: - if (a_meta->hdr.data_size == sizeof(dap_hash_t)) + case DAP_CHAIN_BLOCK_META_ROUND_ATTEMPT: + if (a_meta->hdr.data_size == sizeof(uint8_t)) return a_meta->data; - else - log_it(L_WARNING, "Merkle root meta has wrong size %hu when expecting %zu", a_meta->hdr.data_size, sizeof (dap_hash_t)); + log_it(L_WARNING, "Meta %s has wrong size %hu when expecting %zu", + s_meta_type_to_string(a_meta->hdr.type), a_meta->hdr.data_size, sizeof(uint8_t)); break; + case DAP_CHAIN_BLOCK_META_EXCLUDED_KEYS: + if (a_meta->hdr.data_size > sizeof(uint16_t)) { + uint16_t l_expected_size = *(uint16_t *)a_meta->data + sizeof(uint16_t); + if (!(l_expected_size % sizeof(uint16_t)) && + l_expected_size == a_meta->hdr.data_size) + return a_meta->data; + } + log_it(L_WARNING, "Meta %s has wrong size %hu", s_meta_type_to_string(a_meta->hdr.type), a_meta->hdr.data_size); default: log_it(L_WARNING, "Unknown meta type 0x%02x (size %u), possible corrupted block or you need to upgrade your software", a_meta->hdr.type, a_meta->hdr.type); @@ -574,10 +588,10 @@ uint8_t *dap_chain_block_meta_get(const dap_chain_block_t *a_block, size_t a_blo * @param a_reward */ int dap_chain_block_meta_extract(dap_chain_block_t *a_block, size_t a_block_size, - dap_chain_hash_fast_t * a_block_prev_hash, - dap_chain_hash_fast_t * a_block_anchor_hash, + dap_chain_hash_fast_t *a_block_prev_hash, + dap_chain_hash_fast_t *a_block_anchor_hash, dap_chain_hash_fast_t *a_merkle, - dap_chain_hash_fast_t ** a_block_links, + dap_chain_hash_fast_t **a_block_links, size_t *a_block_links_count, bool *a_is_genesis, uint64_t *a_nonce, diff --git a/modules/type/blocks/dap_chain_block_cache.c b/modules/type/blocks/dap_chain_block_cache.c index dc1b11c3be82a2339456c17e6aa5a4900bf933c3..0a9926d4d25ca8858c1bf2214e632a2b8f4cddbb 100644 --- a/modules/type/blocks/dap_chain_block_cache.c +++ b/modules/type/blocks/dap_chain_block_cache.c @@ -26,7 +26,6 @@ #include "dap_chain_block_cache.h" #include "dap_chain_datum_tx.h" #include "dap_chain_datum_tx_in.h" -#include "dap_chain_datum_tx_out.h" #define LOG_TAG "dap_chain_block_cache" diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c index 6d630a5d51bd3d10abdbf4b895ccaecc18a09db8..9485ea8ee2e41fbd2b3d9890155ab788951b2703 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -22,7 +22,6 @@ */ #include <pthread.h> #include "dap_common.h" -#include "dap_enc_base58.h" #include "dap_chain.h" #include "dap_chain_cell.h" #include "dap_chain_cs.h" @@ -86,7 +85,7 @@ typedef struct dap_chain_cs_blocks_pvt #define PVT(a) ((dap_chain_cs_blocks_pvt_t *)(a)->_pvt ) static int s_cli_parse_cmd_hash(char ** a_argv, int a_arg_index, int a_argc, void **a_str_reply,const char * a_param, dap_chain_hash_fast_t * a_datum_hash); -static void s_cli_meta_hash_print( dap_string_t * a_str_tmp, const char * a_meta_title, dap_chain_block_meta_t * a_meta); +static void s_cli_meta_hash_print( json_object* json_obj_a, const char * a_meta_title, dap_chain_block_meta_t * a_meta); static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply); // Setup BFT consensus and select the longest chunk @@ -232,7 +231,7 @@ void dap_chain_cs_blocks_deinit() dap_chain_block_cache_deinit(); } -static int s_chain_cs_blocks_new(dap_chain_t * a_chain, dap_config_t * a_chain_config) +static int s_chain_cs_blocks_new(dap_chain_t *a_chain, dap_config_t *a_chain_config) { dap_chain_cs_blocks_t * l_cs_blocks = DAP_NEW_Z(dap_chain_cs_blocks_t); if (!l_cs_blocks) { @@ -432,14 +431,14 @@ static int s_cli_parse_cmd_hash(char ** a_argv, int a_arg_index, int a_argc, voi * @param a_meta_title * @param a_meta */ -static void s_cli_meta_hash_print(dap_string_t *a_str_tmp, const char *a_meta_title, dap_chain_block_meta_t *a_meta) +static void s_cli_meta_hash_print(json_object* json_obj_a, const char *a_meta_title, dap_chain_block_meta_t *a_meta) { if (a_meta->hdr.data_size == sizeof (dap_chain_hash_fast_t)) { char l_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; dap_chain_hash_fast_to_str((dap_chain_hash_fast_t *)a_meta->data, l_hash_str, sizeof(l_hash_str)); - dap_string_append_printf(a_str_tmp, "\t\t%s: %s\n", a_meta_title, l_hash_str); + json_object_object_add(json_obj_a, a_meta_title, json_object_new_string(l_hash_str)); } else - dap_string_append_printf(a_str_tmp,"\t\t\%s: Error, hash size is incorrect\n", a_meta_title); + json_object_object_add(json_obj_a, a_meta_title, json_object_new_string("Error, hash size is incorrect")); } /** @@ -448,36 +447,45 @@ static void s_cli_meta_hash_print(dap_string_t *a_str_tmp, const char *a_meta_ti * @param a_meta_title * @param a_meta */ -static void s_cli_meta_hex_print( dap_string_t * a_str_tmp, const char * a_meta_title, dap_chain_block_meta_t * a_meta) +static void s_cli_meta_hex_print(json_object* json_obj_a, const char * a_meta_title, dap_chain_block_meta_t * a_meta) { char *l_data_hex = DAP_NEW_Z_SIZE(char, a_meta->hdr.data_size * 2 + 3); dap_bin2hex(l_data_hex, a_meta->data, a_meta->hdr.data_size); - dap_string_append_printf(a_str_tmp,"\t\t\%s: 0x%s\n", a_meta_title, l_data_hex); + char l_tmp_buff[70]={0}; + sprintf(l_tmp_buff,"0x%s\n", l_data_hex); + json_object_object_add(json_obj_a, a_meta_title, json_object_new_string(l_tmp_buff)); DAP_DELETE(l_data_hex); } -static void s_print_autocollect_table(dap_chain_net_t *a_net, dap_string_t *a_reply_str, const char *a_table_name) +static void s_print_autocollect_table(dap_chain_net_t *a_net, json_object* json_obj_a, 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 %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"); + char l_tmp_buff[150]={0}; + sprintf(l_tmp_buff,"for %s in network %s is %s\n", a_table_name, a_net->pub.name, + l_status ? "active" : "inactive, cause the network config or consensus starting problems"); + json_object_object_add(json_obj_a, "Autocollect status", json_object_new_string(l_tmp_buff)); if (!l_status) return; - dap_string_append_printf(a_reply_str, "\nAutocollect tables content for:\n=== %s ===\n", a_table_name); + sprintf(l_tmp_buff,"\nAutocollect tables content for:\n=== %s ===\n", a_table_name); + json_object_object_add(json_obj_a, "Autocollect status", json_object_new_string(l_tmp_buff)); size_t l_objs_count = 0; char *l_group = dap_strcmp(a_table_name, "Fees") ? dap_chain_cs_blocks_get_reward_group(a_net->pub.name) : dap_chain_cs_blocks_get_fee_group(a_net->pub.name); dap_global_db_obj_t *l_objs = dap_global_db_get_all_sync(l_group, &l_objs_count); DAP_DELETE(l_group); uint256_t l_total_value = uint256_0; + json_object* json_arr_out = json_object_new_array(); for (size_t i = 0; i < l_objs_count; i++) { + json_object* json_obj_t = json_object_new_object(); dap_global_db_obj_t *l_obj_cur = l_objs + i; uint256_t l_cur_value = *(uint256_t*)l_obj_cur->value; - char *l_value_str; dap_uint256_to_char(l_cur_value, &l_value_str); - dap_string_append_printf(a_reply_str, "%s\t%s\n", l_obj_cur->key, l_value_str); + const char *l_value_str; dap_uint256_to_char(l_cur_value, &l_value_str); + json_object_object_add(json_obj_t, "obj_key",json_object_new_string(l_obj_cur->key)); + json_object_object_add(json_obj_t, "obj_val",json_object_new_string(l_value_str)); + json_object_array_add(json_arr_out, json_obj_t); SUM_256_256(l_total_value, l_cur_value, &l_total_value); } + json_object_object_add(json_obj_a,"Autocollect tables",json_arr_out); if (l_objs_count) { dap_global_db_objs_delete(l_objs, l_objs_count); uint256_t l_collect_fee = dap_chain_esbocs_get_fee(a_net->pub.id); @@ -488,7 +496,7 @@ static void s_print_autocollect_table(dap_chain_net_t *a_net, dap_string_t *a_re dap_pkey_t *l_my_sign_pkey = dap_chain_esbocs_get_sign_pkey(a_net->pub.id); dap_hash_t l_my_sign_pkey_hash; dap_hash_fast(l_my_sign_pkey->pkey, l_my_sign_pkey->header.size, &l_my_sign_pkey_hash); - dap_chain_net_srv_stake_item_t *l_key_item = dap_chain_net_srv_stake_check_pkey_hash(&l_my_sign_pkey_hash); + dap_chain_net_srv_stake_item_t *l_key_item = dap_chain_net_srv_stake_check_pkey_hash(a_net->pub.id, &l_my_sign_pkey_hash); if (l_key_item && !IS_ZERO_256(l_key_item->sovereign_tax) && !dap_chain_addr_is_blank(&l_key_item->sovereign_addr)) { MULT_256_COIN(l_collect_value, l_key_item->sovereign_tax, &l_collect_tax); @@ -499,11 +507,12 @@ static void s_print_autocollect_table(dap_chain_net_t *a_net, dap_string_t *a_re char *l_profit_str = dap_chain_balance_to_coins(l_collect_value); char *l_tax_str = dap_chain_balance_to_coins(l_collect_tax); char *l_fee_str = dap_chain_balance_to_coins(l_collect_fee); - dap_string_append_printf(a_reply_str, "\nTotal prepared value: %s %s, where\n\tprofit is %s, tax is %s, fee is %s\n", + sprintf(l_tmp_buff,"\nTotal prepared value: %s %s, where\n\tprofit is %s, tax is %s, fee is %s\n", l_total_str, a_net->pub.native_ticker, l_profit_str, l_tax_str, l_fee_str); + json_object_object_add(json_obj_a, "status",json_object_new_string(l_tmp_buff)); DAP_DEL_MULTY(l_total_str, l_profit_str, l_tax_str, l_fee_str); } else - dap_string_append(a_reply_str, "Empty\n"); + json_object_object_add(json_obj_a, "status",json_object_new_string("Empty\n")); } /** @@ -516,6 +525,9 @@ static void s_print_autocollect_table(dap_chain_net_t *a_net, dap_string_t *a_re */ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) { + json_object **json_arr_reply = (json_object **)a_str_reply; + //char ** a_str_reply = (char **) reply; + const char *l_hash_out_type = NULL; enum { SUBCMD_UNDEFINED =0, SUBCMD_NEW_FLUSH, @@ -561,16 +573,15 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) dap_chain_net_t * l_net = NULL; // Parse default values - if(dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, a_argc, a_argv, a_str_reply, &l_chain, &l_net) < 0) - return -11; + if (dap_chain_node_cli_cmd_values_parse_net_chain_for_json(&arg_index, a_argc, a_argv, &l_chain, &l_net, CHAIN_TYPE_TX)) + return -DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR; - const char *l_chain_type = dap_chain_net_get_type(l_chain); + const char *l_chain_type = dap_chain_get_cs_type(l_chain); if (!strstr(l_chain_type, "block_") && strcmp(l_chain_type, "esbocs")){ - dap_cli_server_cmd_set_reply_text(a_str_reply, - "Type of chain %s is not block. This chain with type %s is not supported by this command", + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_CHAIN_TYPE_ERR, "Type of chain %s is not block. This chain with type %s is not supported by this command", l_chain->name, l_chain_type); - return -42; + return DAP_CHAIN_NODE_CLI_COM_BLOCK_CHAIN_TYPE_ERR; } l_blocks = DAP_CHAIN_CS_BLOCKS(l_chain); @@ -612,9 +623,8 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) s_cli_parse_cmd_hash(a_argv,arg_index,a_argc,a_str_reply,"-datum", &l_datum_hash ); l_blocks->block_new_size=dap_chain_block_datum_del_by_hash( &l_blocks->block_new, l_blocks->block_new_size, &l_datum_hash ); }else { - dap_cli_server_cmd_set_reply_text(a_str_reply, - "Error! Can't delete datum from hash because no forming new block! Check pls you role, it must be MASTER NODE or greater"); - ret = -12; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_DATUM_DEL_ERR, "Error! Can't delete datum from hash because no forming new block! Check pls you role, it must be MASTER NODE or greater"); + ret = DAP_CHAIN_NODE_CLI_COM_BLOCK_DATUM_DEL_ERR; } pthread_rwlock_unlock( &PVT(l_blocks)->rwlock ); }break; @@ -624,9 +634,9 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) dap_chain_datum_t ** l_datums = DAP_NEW_Z_SIZE(dap_chain_datum_t*, sizeof(dap_chain_datum_t*)*l_datums_count); if (!l_datums) { - log_it(L_CRITICAL, "%s", g_error_memory_alloc); - dap_cli_server_cmd_set_reply_text(a_str_reply,"Out of memory in s_cli_blocks"); - return -1; + log_it(L_CRITICAL, "%s", g_error_memory_alloc); + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_MEMORY_ERR, "Out of memory in s_cli_blocks"); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_MEMORY_ERR; } size_t l_datum_size = 0; @@ -636,16 +646,16 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) for (size_t i = 0; i < l_datums_count; i++) { bool l_err = dap_chain_node_mempool_process(l_chain, l_datums[i], l_subcmd_str_arg); if (l_err) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Error! Datum %s doesn't pass verifications, examine node log files", + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_VERIF_ERR, "Error! Datum %s doesn't pass verifications, examine node log files", l_subcmd_str_arg); - ret = -9; + ret = DAP_CHAIN_NODE_CLI_COM_BLOCK_VERIF_ERR; } else log_it(L_INFO, "Pass datum %s from mempool to block in the new forming round ", l_subcmd_str_arg); if (l_err) break; } - dap_cli_server_cmd_set_reply_text(a_str_reply, "All datums processed"); + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_OK, "All datums processed"); DAP_DELETE(l_gdb_group_mempool); } break; @@ -660,104 +670,131 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) case SUBCMD_DUMP:{ dap_chain_hash_fast_t l_block_hash={0}; if (!l_subcmd_str_arg) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Enter block hash "); - return -13; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_HASH_ERR, "Enter block hash "); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_HASH_ERR; } dap_chain_hash_fast_from_str(l_subcmd_str_arg, &l_block_hash); // Convert argument to hash dap_chain_block_cache_t *l_block_cache = dap_chain_block_cache_get_by_hash(l_blocks, &l_block_hash); if (!l_block_cache) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find block %s ", l_subcmd_str_arg); - return 10; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_FIND_ERR, "Can't find block %s ", l_subcmd_str_arg); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_FIND_ERR; } dap_chain_block_t *l_block = l_block_cache->block; - dap_string_t *l_str_tmp = dap_string_new(NULL); + char l_tmp_buff[70]={0}; + + char l_time_buf[DAP_TIME_STR_SIZE]; + dap_time_to_str_rfc822(l_time_buf, DAP_TIME_STR_SIZE, l_block->hdr.ts_created); // Header - dap_string_append_printf(l_str_tmp, "Block number %"DAP_UINT64_FORMAT_U" hash %s:\n", l_block_cache->block_number, l_subcmd_str_arg); - 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[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); + json_object* json_obj_inf = json_object_new_object(); + json_object_object_add(json_obj_inf, "Block number", json_object_new_uint64(l_block_cache->block_number)); + json_object_object_add(json_obj_inf, "hash", json_object_new_string(l_subcmd_str_arg)); + sprintf(l_tmp_buff,"0x%04X",l_block->hdr.version); + json_object_object_add(json_obj_inf, "version", json_object_new_string(l_tmp_buff)); + sprintf(l_tmp_buff,"0x%016"DAP_UINT64_FORMAT_X"",l_block->hdr.cell_id.uint64); + json_object_object_add(json_obj_inf, "cell_id", json_object_new_string(l_tmp_buff)); + sprintf(l_tmp_buff,"0x%016"DAP_UINT64_FORMAT_X"",l_block->hdr.chain_id.uint64); + json_object_object_add(json_obj_inf, "chain_id", json_object_new_string(l_tmp_buff)); + json_object_object_add(json_obj_inf, "ts_created", json_object_new_string(l_time_buf)); // Dump Metadata size_t l_offset = 0; - dap_string_append_printf(l_str_tmp,"\tMetadata. Count: %us\n",l_block->hdr.meta_count ); + json_object_object_add(json_obj_inf, "Metadata: count", json_object_new_int(l_block->hdr.meta_count)); + json_object* json_arr_meta_out = json_object_new_array(); + json_object_array_add(*json_arr_reply, json_obj_inf); for (uint32_t i=0; i < l_block->hdr.meta_count; i++) { + json_object* json_obj_meta = json_object_new_object(); dap_chain_block_meta_t *l_meta = (dap_chain_block_meta_t *)(l_block->meta_n_datum_n_sign + l_offset); switch (l_meta->hdr.type) { case DAP_CHAIN_BLOCK_META_GENESIS: - dap_string_append_printf(l_str_tmp, "\t\tGENESIS\n"); + json_object_object_add(json_obj_meta, "GENESIS", json_object_new_string("GENESIS")); break; case DAP_CHAIN_BLOCK_META_PREV: - s_cli_meta_hash_print(l_str_tmp, "PREV", l_meta); + s_cli_meta_hash_print(json_obj_meta,"PREV", l_meta); break; case DAP_CHAIN_BLOCK_META_ANCHOR: - s_cli_meta_hash_print(l_str_tmp, "ANCHOR", l_meta); + s_cli_meta_hash_print(json_obj_meta, "ANCHOR", l_meta); break; case DAP_CHAIN_BLOCK_META_LINK: - s_cli_meta_hash_print(l_str_tmp, "LINK", l_meta); + s_cli_meta_hash_print(json_obj_meta, "LINK", l_meta); break; case DAP_CHAIN_BLOCK_META_NONCE: - s_cli_meta_hex_print(l_str_tmp, "NONCE", l_meta); + s_cli_meta_hex_print(json_obj_meta, "NONCE", l_meta); break; case DAP_CHAIN_BLOCK_META_NONCE2: - s_cli_meta_hex_print(l_str_tmp, "NONCE2", l_meta); + s_cli_meta_hex_print(json_obj_meta, "NONCE2", l_meta); break; default: { char * l_data_hex = DAP_NEW_Z_SIZE(char,l_meta->hdr.data_size*2+3); dap_bin2hex(l_data_hex, l_meta->data, l_meta->hdr.data_size); - dap_string_append_printf(l_str_tmp, "\t\t 0x%0X: 0x%s\n", i, l_data_hex ); + sprintf(l_tmp_buff,"0x%0X",i); + json_object_object_add(json_obj_meta, "# -", json_object_new_string(l_tmp_buff)); + sprintf(l_tmp_buff,"0x%s",l_data_hex); + json_object_object_add(json_obj_meta, "Data hex - ", json_object_new_string(l_tmp_buff)); DAP_DELETE(l_data_hex); } } + json_object_array_add(json_arr_meta_out, json_obj_meta); l_offset += sizeof(l_meta->hdr) + l_meta->hdr.data_size; } - dap_string_append_printf(l_str_tmp,"\t\tdatums:\tcount: %zu\n",l_block_cache->datum_count); + json_object_array_add(*json_arr_reply, json_arr_meta_out); + json_object* json_obj_datum = json_object_new_object(); + json_object_object_add(json_obj_datum, "Datums: count", json_object_new_uint64(l_block_cache->datum_count)); + json_object_array_add(*json_arr_reply, json_obj_datum); + json_object* json_arr_datum_out = json_object_new_array(); for (uint32_t i=0; i < l_block_cache->datum_count ; i++){ + char buf[70]; + json_object* json_obj_tx = json_object_new_object(); dap_chain_datum_t * l_datum = l_block_cache->datum[i]; size_t l_datum_size = dap_chain_datum_size(l_datum); - dap_string_append_printf(l_str_tmp,"\t\t\tdatum:\tdatum_size: %zu\n",l_datum_size); + json_object_object_add(json_obj_tx, "datum size ",json_object_new_uint64(l_datum_size)); if (l_datum_size < sizeof (l_datum->header) ){ - dap_string_append_printf(l_str_tmp,"\t\t\tERROR: datum size %zu is smaller than header size %zu \n",l_datum_size, + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_DATUM_SIZE_ERR, "ERROR: datum size %zu is smaller than header size %zu \n",l_datum_size, sizeof (l_datum->header)); break; } // Nested datums - dap_string_append_printf(l_str_tmp,"\t\t\t\tversion:=0x%02X\n", l_datum->header.version_id); + sprintf(l_tmp_buff,"0x%02X",l_datum->header.version_id); + json_object_object_add(json_obj_tx, "version",json_object_new_string(l_tmp_buff)); 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); + json_object_object_add(json_obj_tx, "type_id",json_object_new_string(l_datum_type_str)); 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); + json_object_object_add(json_obj_tx, "ts_create",json_object_new_string(buf)); + json_object_object_add(json_obj_tx, "data_size",json_object_new_int(l_datum->header.data_size)); + dap_chain_datum_dump_json(json_obj_tx,l_datum,l_hash_out_type,l_net->pub.id); + json_object_array_add(json_arr_datum_out, json_obj_tx); } // Signatures - dap_string_append_printf(l_str_tmp,"\t\tsignatures:\tcount: %zu\n", l_block_cache->sign_count ); + json_object_array_add(*json_arr_reply, json_arr_datum_out); + // Signatures + json_object* json_obj_sig = json_object_new_object(); + json_object_object_add(json_obj_sig, "signatures count", json_object_new_uint64(l_block_cache->sign_count)); + json_object_array_add(*json_arr_reply, json_obj_sig); + json_object* json_arr_sign_out = json_object_new_array(); for (uint32_t i=0; i < l_block_cache->sign_count ; i++) { + json_object* json_obj_sign = json_object_new_object(); dap_sign_t * l_sign = dap_chain_block_sign_get(l_block_cache->block, l_block_cache->block_size, i); size_t l_sign_size = dap_sign_get_size(l_sign); dap_chain_hash_fast_t l_pkey_hash; dap_sign_get_pkey_hash(l_sign, &l_pkey_hash); char l_pkey_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; dap_chain_hash_fast_to_str(&l_pkey_hash, l_pkey_hash_str, sizeof(l_pkey_hash_str)); - dap_string_append_printf(l_str_tmp,"\t\t\ttype:%s size: %zd pkey_hash: %s \n" - "\t\t\t\n", dap_sign_type_to_str( l_sign->header.type ), - l_sign_size, l_pkey_hash_str ); + json_object_object_add(json_obj_sign, "type",json_object_new_string(dap_sign_type_to_str( l_sign->header.type ))); + json_object_object_add(json_obj_sign, "size",json_object_new_uint64(l_sign_size)); + json_object_object_add(json_obj_sign, "pkey_hash",json_object_new_string(l_pkey_hash_str)); + json_object_array_add(json_arr_sign_out, json_obj_sign); } - dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_tmp->str); - dap_string_free(l_str_tmp, true); + json_object_array_add(*json_arr_reply, json_arr_sign_out); } break; case SUBCMD_LIST:{ const char *l_cert_name = NULL, *l_from_hash_str = NULL, *l_to_hash_str = NULL, *l_from_date_str = NULL, *l_to_date_str = NULL, *l_pkey_hash_str = NULL, *l_limit_str = NULL, *l_offset_str = NULL; bool l_unspent_flag = false, l_first_signed_flag = false, l_signed_flag = false, l_hash_flag = false; - size_t l_block_count = 0; dap_pkey_t * l_pub_key = NULL; dap_hash_fast_t l_from_hash = {}, l_to_hash = {}, l_pkey_hash = {}; dap_time_t l_from_time = 0, l_to_time = 0; + char l_tmp_buff[150]={0}; l_signed_flag = dap_cli_server_cmd_check_option(a_argv, 1, a_argc, "signed") > 0; l_first_signed_flag = dap_cli_server_cmd_check_option(a_argv, 1, a_argc, "first_signed") > 0; @@ -771,33 +808,32 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-limit", &l_limit_str); dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-offset", &l_offset_str); size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0; - size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 0; + size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 1000; if (l_signed_flag && l_first_signed_flag) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Choose only one option from 'singed' and 'first_signed'"); - return -10; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, "Choose only one option from 'singed' and 'first_signed'"); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR; } if ((l_signed_flag || l_first_signed_flag) && !l_cert_name && !l_pkey_hash_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Option from '%s' requires parameter '-cert' or 'pkey_hash'", + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, "Option from '%s' requires parameter '-cert' or 'pkey_hash'", l_first_signed_flag ? "first_signed" : "signed"); - return -11; + return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR; } if (l_cert_name) { dap_cert_t *l_cert = dap_cert_find_by_name(l_cert_name); if (!l_cert) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find \"%s\" certificate", l_cert_name); - return -18; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_CERT_ERR, "Can't find \"%s\" certificate", l_cert_name); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_CERT_ERR; } l_pub_key = dap_pkey_from_enc_key(l_cert->enc_key); if (!l_pub_key) { - dap_cli_server_cmd_set_reply_text(a_str_reply, - "Corrupted certificate \"%s\" have no public key data", l_cert_name); - return -20; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PUB_KEY_ERR, "Corrupted certificate \"%s\" have no public key data", l_cert_name); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_PUB_KEY_ERR; } } else if (l_pkey_hash_str) { if (dap_chain_hash_fast_from_str(l_pkey_hash_str, &l_pkey_hash)) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't convert \"%s\" to hash", l_pkey_hash_str); - return -12; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_CONVERT_ERR, "Can't convert \"%s\" to hash", l_pkey_hash_str); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_CONVERT_ERR; } } if (l_unspent_flag && l_signed_flag && !l_pkey_hash_str) @@ -807,29 +843,29 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) if (l_from_hash_str) { if (dap_chain_hash_fast_from_str(l_from_hash_str, &l_from_hash)) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't convert \"%s\" to hash", l_from_hash_str); - return -13; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_CONVERT_ERR, "Can't convert \"%s\" to hash", l_from_hash_str); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_CONVERT_ERR; } } if (l_to_hash_str) { if (dap_chain_hash_fast_from_str(l_to_hash_str, &l_to_hash)) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't convert \"%s\" to hash", l_to_hash_str); - return -14; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_CONVERT_ERR, "Can't convert \"%s\" to hash", l_to_hash_str); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_CONVERT_ERR; } } if (l_from_date_str) { l_from_time = dap_time_from_str_simplified(l_from_date_str); if (!l_from_time) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't convert \"%s\" to date", l_from_date_str); - return -21; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_CONVERT_ERR, "Can't convert \"%s\" to date", l_from_date_str); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_CONVERT_ERR; } } if (l_to_date_str) { l_to_time = dap_time_from_str_simplified(l_to_date_str); if (!l_to_time) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't convert \"%s\" to date", l_to_date_str); - return -21; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_CONVERT_ERR, "Can't convert \"%s\" to date", l_to_date_str); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_CONVERT_ERR; } struct tm *l_localtime = localtime((time_t *)&l_to_time); l_localtime->tm_mday += 1; // + 1 day to end date, got it inclusive @@ -837,19 +873,23 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) } pthread_rwlock_rdlock(&PVT(l_blocks)->rwlock); - dap_string_t *l_str_tmp = dap_string_new(NULL); + json_object* json_arr_bl_cache_out = json_object_new_array(); + json_object* json_obj_lim = json_object_new_object(); size_t l_start_arr = 0; - if(l_offset > 1) { - l_start_arr = l_offset * l_limit; + if(l_offset > 0) { + l_start_arr = l_offset; + json_object_object_add(json_obj_lim, "offset",json_object_new_uint64(l_start_arr)); } size_t l_arr_end = PVT(l_blocks)->blocks_count; if (l_limit) { + json_object_object_add(json_obj_lim, "limit",json_object_new_uint64(l_limit)); l_arr_end = l_start_arr + l_limit; if (l_arr_end > PVT(l_blocks)->blocks_count) l_arr_end = PVT(l_blocks)->blocks_count; } + json_object_array_add(json_arr_bl_cache_out, json_obj_lim); size_t i_tmp = 0; - for (dap_chain_block_cache_t *l_block_cache = PVT(l_blocks)->blocks; l_block_cache; l_block_cache = l_block_cache->hh.next) { + for (dap_chain_block_cache_t *l_block_cache = PVT(l_blocks)->blocks; l_block_cache; l_block_cache = l_block_cache->hh.next) { if (i_tmp < l_start_arr || i_tmp >= l_arr_end) { i_tmp++; continue; @@ -916,26 +956,34 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) } } char l_buf[DAP_TIME_STR_SIZE]; + json_object* json_obj_bl_cache = json_object_new_object(); 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++; + json_object_object_add(json_obj_bl_cache, "block",json_object_new_uint64(i_tmp)); + json_object_object_add(json_obj_bl_cache, "hash",json_object_new_string(l_block_cache->block_hash_str)); + json_object_object_add(json_obj_bl_cache, "ts_create",json_object_new_string(l_buf)); + json_object_array_add(json_arr_bl_cache_out, json_obj_bl_cache); if (l_to_hash_str && dap_hash_fast_compare(&l_to_hash, &l_block_cache->block_hash)) break; } pthread_rwlock_unlock(&PVT(l_blocks)->rwlock); + json_object_array_add(*json_arr_reply, json_arr_bl_cache_out); - char *l_filtered_criteria = ""; + char *l_filtered_criteria = "none"; + json_object* json_obj_out = json_object_new_object(); if (l_cert_name || l_pkey_hash_str || l_from_hash_str || l_to_hash_str || l_from_date_str || l_to_date_str) l_filtered_criteria = " filtered according to the specified criteria"; - dap_string_append_printf(l_str_tmp, "%s.%s: Have %"DAP_UINT64_FORMAT_U" blocks%s\n", - l_net->pub.name, l_chain->name, l_block_count, l_filtered_criteria); - dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_tmp->str); - dap_string_free(l_str_tmp, true); + sprintf(l_tmp_buff,"%s.%s with filter - %s, have blocks",l_net->pub.name,l_chain->name,l_filtered_criteria); + json_object_object_add(json_obj_out, l_tmp_buff, json_object_new_uint64(i_tmp)); + json_object_array_add(*json_arr_reply,json_obj_out); } break; case SUBCMD_COUNT: { - dap_cli_server_cmd_set_reply_text(a_str_reply, "%zu blocks in %s.%s", PVT(l_blocks)->blocks_count, - l_net->pub.name, l_chain->name); + char l_tmp_buff[70]={0}; + json_object* json_obj_out = json_object_new_object(); + sprintf(l_tmp_buff,"%s.%s has blocks - ",l_net->pub.name,l_chain->name); + json_object_object_add(json_obj_out, l_tmp_buff, json_object_new_uint64(PVT(l_blocks)->blocks_count)); + json_object_array_add(*json_arr_reply, json_obj_out); + } break; case SUBCMD_FEE: @@ -945,6 +993,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) const char * l_addr_str = NULL; const char * l_hash_out_type = NULL; const char * l_hash_str = NULL; + char l_tmp_buff[70]={0}; uint256_t l_fee_value = {}; size_t l_hashes_count = 0; @@ -953,52 +1002,54 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) if (l_subcmd == SUBCMD_FEE) { if (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "collect") == -1) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block fee' requires subcommand 'collect'"); - return -14; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, "Command 'block fee' requires subcommand 'collect'"); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR; } } else { // l_sumcmd == SUBCMD_REWARD if (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "set") >= 0) { const char *l_value_str = NULL; dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-poa_cert", &l_cert_name); if(!l_cert_name) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block reward set' requires parameter '-poa_cert'"); - return -17; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, "Command 'block reward set' requires parameter '-poa_cert'"); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR; } dap_cert_t *l_cert = dap_cert_find_by_name(l_cert_name); if (!l_cert) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find \"%s\" certificate", l_cert_name); - return -18; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_CERT_ERR, "Can't find \"%s\" certificate", l_cert_name); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_CERT_ERR; } if (!l_cert->enc_key || !l_cert->enc_key->priv_key_data || !l_cert->enc_key->priv_key_data_size) { - dap_cli_server_cmd_set_reply_text(a_str_reply, - "Certificate \"%s\" doesn't contains private key", l_cert_name); - return -19; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PVT_KEY_ERR, "Certificate \"%s\" doesn't contains private key", l_cert_name); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_PVT_KEY_ERR; } dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-value", &l_value_str); uint256_t l_value = dap_chain_balance_scan(l_value_str); if (!l_value_str || IS_ZERO_256(l_value)) { - dap_cli_server_cmd_set_reply_text(a_str_reply, - "Command 'block reward set' requires parameter '-value' to be valid 256-bit unsigned integer"); - return -20; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, "Command 'block reward set' requires parameter '-value' to be valid 256-bit unsigned integer"); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR; } char *l_decree_hash_str = s_blocks_decree_set_reward(l_net, l_chain, l_value, l_cert); if (l_decree_hash_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Decree with hash %s created to set basic block sign reward", l_decree_hash_str); + //добавить вывод + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_OK, "Decree with hash %s created to set basic block sign reward", l_decree_hash_str); DAP_DELETE(l_decree_hash_str); } else { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Basic block sign reward setting failed. Examine log file for details"); - return -21; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_SIGN_ERR, "Basic block sign reward setting failed. Examine log file for details"); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_SIGN_ERR; } break; } else if (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "show") >= 0) { uint256_t l_cur_reward = dap_chain_net_get_reward(l_net, UINT64_MAX); - char *l_reward_str; dap_uint256_to_char(l_cur_reward, &l_reward_str); - dap_cli_server_cmd_set_reply_text(a_str_reply, "Current base block reward is %s\n", l_reward_str); + const char *l_reward_str; dap_uint256_to_char(l_cur_reward, &l_reward_str); + json_object* json_obj_out = json_object_new_object(); + sprintf(l_tmp_buff,"Current base block reward is %s\n", l_reward_str); + json_object_object_add(json_obj_out, "status", json_object_new_string(l_tmp_buff)); + json_object_array_add(*json_arr_reply, json_obj_out); break; } else if (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "collect") == -1) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block reward' requires subcommands 'set' or 'show' or 'collect'"); - return -14; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, "Command 'block reward' requires subcommands 'set' or 'show' or 'collect'"); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR; } } @@ -1007,8 +1058,8 @@ static int s_cli_blocks(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 -15; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, "invalid parameter -H, valid values: -H <hex | base58>"); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR; } // Private certificate @@ -1019,42 +1070,41 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-fee", &l_fee_value_str); if (!l_addr_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block %s collect' requires parameter '-addr'", l_subcmd_str); - return -16; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, "Command 'block %s collect' requires parameter '-addr'", l_subcmd_str); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR; } l_addr = dap_chain_addr_from_str(l_addr_str); if(!l_cert_name) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block %s collect' requires parameter '-cert'", l_subcmd_str); - return -17; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, "Command 'block %s collect' requires parameter '-cert'", l_subcmd_str); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR; } dap_cert_t *l_cert = dap_cert_find_by_name(l_cert_name); if (!l_cert) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find \"%s\" certificate", l_cert_name); - return -18; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_CERT_ERR, "Can't find \"%s\" certificate", l_cert_name); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_CERT_ERR; } if (!l_cert->enc_key || !l_cert->enc_key->priv_key_data || !l_cert->enc_key->priv_key_data_size) { - dap_cli_server_cmd_set_reply_text(a_str_reply, - "Certificate \"%s\" doesn't contains private key", l_cert_name); - return -19; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_CERT_ERR, + "Certificate \"%s\" doesn't contains private key", l_cert_name); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_CERT_ERR; } l_fee_value = dap_chain_balance_scan(l_fee_value_str); if (!l_fee_value_str || IS_ZERO_256(l_fee_value)) { - dap_cli_server_cmd_set_reply_text(a_str_reply, - "Command 'block %s collect' requires parameter '-fee' to be valid uint256", l_subcmd_str); - return -20; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, "Command 'block %s collect' requires parameter '-fee' to be valid uint256", l_subcmd_str); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR; } if (!l_hash_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block fee collect' requires parameter '-hashes'"); - return -21; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, "Command 'block fee collect' requires parameter '-hashes'"); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR; } // NOTE: This call will modify source string l_block_list = s_block_parse_str_list((char *)l_hash_str, &l_hashes_count, l_chain); if (!l_block_list || !l_hashes_count) { - dap_cli_server_cmd_set_reply_text(a_str_reply, - "Block fee collection requires at least one hash to create a transaction"); - return -22; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_HASH_ERR, + "Block fee collection requires at least one hash to create a transaction"); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_HASH_ERR; } char *l_hash_tx = NULL; @@ -1063,11 +1113,15 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) else l_hash_tx = dap_chain_mempool_tx_reward_create(l_blocks, l_cert->enc_key, l_addr, l_block_list, l_fee_value, l_hash_out_type); if (l_hash_tx) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "TX for %s collection created succefully, hash=%s\n", l_subcmd_str, l_hash_tx); + json_object* json_obj_out = json_object_new_object(); + sprintf(l_tmp_buff, "TX for %s collection created succefully, hash = %s\n", l_subcmd_str, l_hash_tx); + json_object_object_add(json_obj_out, "status", json_object_new_string(l_tmp_buff)); + json_object_array_add(*json_arr_reply, json_obj_out); DAP_DELETE(l_hash_tx); } else { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't create %s collect TX\n", l_subcmd_str); - ret = -24; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_HASH_ERR, + "Can't create %s collect TX\n", l_subcmd_str); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_HASH_ERR; } dap_list_free_full(l_block_list, NULL); }break; @@ -1078,6 +1132,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) dap_hash_fast_t l_pkey_hash = {}; dap_chain_addr_t *l_addr = NULL; size_t l_block_count = 0; + char l_tmp_buff[128]={0}; int fl_renew = dap_cli_server_cmd_check_option(a_argv, arg_index,a_argc, "renew"); if(fl_renew != -1) { @@ -1085,27 +1140,30 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-addr", &l_addr_str); l_addr = dap_chain_addr_from_str(l_addr_str); if(!l_cert_name) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block autocollect renew' requires parameter '-cert'"); - return -20; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, + "Command 'block autocollect renew' requires parameter '-cert'", l_subcmd_str); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR; } if (!l_addr_str) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block autocollect renew' requires parameter '-addr'"); - return -20; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, + "Command 'block autocollect renew' requires parameter '-addr'", l_subcmd_str); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR; } dap_cert_t *l_cert = dap_cert_find_by_name(l_cert_name); if (!l_cert) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't find \"%s\" certificate", l_cert_name); - return -20; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_CERT_ERR, + "Can't find \"%s\" certificate", l_cert_name); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_CERT_ERR; } l_pub_key = dap_pkey_from_enc_key(l_cert->enc_key); if (!l_pub_key) { - dap_cli_server_cmd_set_reply_text(a_str_reply, - "Corrupted certificate \"%s\" have no public key data", l_cert_name); - return -20; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PUB_KEY_ERR, + "Corrupted certificate \"%s\" have no public key data", l_cert_name); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_PUB_KEY_ERR; } dap_chain_esbocs_block_collect_t l_block_collect_params = (dap_chain_esbocs_block_collect_t){ - .collecting_level = l_chain->callback_get_collectiong_level(l_chain), - .minimum_fee = l_chain->callback_get_minimum_fee(l_chain), + .collecting_level = dap_chain_esbocs_get_collecting_level(l_chain), + .minimum_fee = dap_chain_esbocs_get_fee(l_chain->net_id), .chain = l_chain, .blocks_sign_key = l_cert->enc_key, .block_sign_pkey = l_pub_key, @@ -1122,7 +1180,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) if(l_objs_rew_count)dap_global_db_objs_delete(l_objs_rew,l_objs_rew_count); DAP_DELETE(l_group_fee); DAP_DELETE(l_group_rew); - dap_string_t *l_str_tmp = dap_string_new(NULL); + json_object* json_arr_bl_out = json_object_new_array(); for (dap_chain_block_cache_t *l_block_cache = PVT(l_blocks)->blocks; l_block_cache; l_block_cache = l_block_cache->hh.next) { dap_time_t l_ts = l_block_cache->block->hdr.ts_created; @@ -1142,10 +1200,13 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) if (NULL == dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE, &l_out_idx_tmp)) continue; if (!dap_ledger_tx_hash_is_used_out_item(l_net->pub.ledger, l_block_cache->datum_hash + i, l_out_idx_tmp, NULL)) { - dap_chain_esbocs_add_block_collect(l_block_cache->block, l_block_cache->block_size, &l_block_collect_params,1); - char l_buf[50]; - dap_time_to_str_rfc822(l_buf, 50, l_ts); - dap_string_append_printf(l_str_tmp, "fee - \t%s: ts_create=%s\n", l_block_cache->block_hash_str, l_buf); + dap_chain_esbocs_add_block_collect(l_block_cache, &l_block_collect_params, DAP_CHAIN_BLOCK_COLLECT_FEES); + char l_buf[DAP_TIME_STR_SIZE]; + json_object* json_obj_bl = json_object_new_object(); + dap_time_to_str_rfc822(l_buf, DAP_TIME_STR_SIZE, l_ts); + sprintf(l_tmp_buff, "fee - \t%s: ts_create=%s\n", l_block_cache->block_hash_str, l_buf); + json_object_object_add(json_obj_bl, "block", json_object_new_string(l_tmp_buff)); + json_object_array_add(json_arr_bl_out, json_obj_bl); l_block_count++; break; } @@ -1170,37 +1231,44 @@ static int s_cli_blocks(int a_argc, char ** a_argv, void **a_str_reply) continue; if (dap_ledger_is_used_reward(l_net->pub.ledger, &l_block_cache->block_hash, &l_pkey_hash)) continue; - dap_chain_esbocs_add_block_collect(l_block_cache->block, l_block_cache->block_size, &l_block_collect_params,2); - { - char l_buf[50]; - dap_time_to_str_rfc822(l_buf, 50, l_ts); - dap_string_append_printf(l_str_tmp, "rewards - \t%s: ts_create=%s\n", l_block_cache->block_hash_str, l_buf); - l_block_count++; - } + dap_chain_esbocs_add_block_collect(l_block_cache, &l_block_collect_params, DAP_CHAIN_BLOCK_COLLECT_REWARDS); + char l_buf[DAP_TIME_STR_SIZE]; + json_object* json_obj_bl = json_object_new_object(); + dap_time_to_str_rfc822(l_buf, DAP_TIME_STR_SIZE, l_ts); + sprintf(l_tmp_buff, "rewards - \t%s: ts_create=%s\n", l_block_cache->block_hash_str, l_buf); + json_object_object_add(json_obj_bl, "block", json_object_new_string(l_tmp_buff)); + json_object_array_add(json_arr_bl_out, json_obj_bl); + l_block_count++; } - dap_string_append_printf(l_str_tmp, "%s.%s: Have %"DAP_UINT64_FORMAT_U" blocks\n", + json_object_array_add(*json_arr_reply, json_arr_bl_out); + json_object* json_obj_out = json_object_new_object(); + sprintf(l_tmp_buff, "%s.%s: Have %"DAP_UINT64_FORMAT_U" blocks\n", l_net->pub.name, l_chain->name, l_block_count); - dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_str_tmp->str); - dap_string_free(l_str_tmp, true); + json_object_object_add(json_obj_out, "status", json_object_new_string(l_tmp_buff)); + json_object_array_add(*json_arr_reply, json_obj_out); }else{ if (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "status") == -1) { - dap_cli_server_cmd_set_reply_text(a_str_reply, "Command 'block autocollect' requires subcommand 'status'"); - return -14; + dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, + "Command 'block autocollect' requires subcommand 'status'"); + return DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR; } - dap_string_t *l_reply_str = dap_string_new(""); - s_print_autocollect_table(l_net, l_reply_str, "Fees"); - s_print_autocollect_table(l_net, l_reply_str, "Rewards"); - dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_reply_str->str); - dap_string_free(l_reply_str, true); + json_object* json_obj_out = json_object_new_object(); + s_print_autocollect_table(l_net, json_obj_out, "Fees"); + s_print_autocollect_table(l_net, json_obj_out, "Rewards"); + json_object_array_add(*json_arr_reply, json_obj_out); } } break; case SUBCMD_UNDEFINED: default: { - dap_cli_server_cmd_set_reply_text(a_str_reply, - "Undefined block subcommand \"%s\" ", + char l_tmp_buff[70]={0}; + json_object* json_obj_out = json_object_new_object(); + snprintf(l_tmp_buff, sizeof(l_tmp_buff), "Undefined block subcommand \"%s\" ", l_subcmd_str); - ret=-11; + json_object_object_add(json_obj_out, "status", json_object_new_string(l_tmp_buff)); + json_object_array_add(*json_arr_reply, json_obj_out); + ret=DAP_CHAIN_NODE_CLI_COM_BLOCK_UNKNOWN; + } break; } return ret; diff --git a/modules/type/blocks/include/dap_chain_block.h b/modules/type/blocks/include/dap_chain_block.h index 3c986857fc699b2d0258f6be811c81c5b06d6795..519b655c85ed90f61657cc85543473fcece94e8b 100644 --- a/modules/type/blocks/include/dap_chain_block.h +++ b/modules/type/blocks/include/dap_chain_block.h @@ -23,12 +23,9 @@ #pragma once #include "dap_common.h" #include "dap_time.h" -#include "dap_math_ops.h" #include "dap_hash.h" -#include "dap_cert.h" #include "dap_chain_common.h" #include "dap_chain_datum.h" -#include "dap_chain_datum_hashtree_roots.h" #define DAP_CHAIN_BLOCK_SIGNATURE 0xDA05BF8E #define DAP_CHAIN_BLOCK_ID_SIZE 4 @@ -65,13 +62,17 @@ typedef struct dap_chain_block_meta{ // Block metadata types -#define DAP_CHAIN_BLOCK_META_GENESIS 0x01 -#define DAP_CHAIN_BLOCK_META_PREV 0x10 -#define DAP_CHAIN_BLOCK_META_ANCHOR 0x11 -#define DAP_CHAIN_BLOCK_META_LINK 0x12 -#define DAP_CHAIN_BLOCK_META_NONCE 0x20 -#define DAP_CHAIN_BLOCK_META_NONCE2 0x21 -#define DAP_CHAIN_BLOCK_META_MERKLE 0x30 +#define DAP_CHAIN_BLOCK_META_GENESIS 0x01 +#define DAP_CHAIN_BLOCK_META_PREV 0x10 +#define DAP_CHAIN_BLOCK_META_ANCHOR 0x11 +#define DAP_CHAIN_BLOCK_META_LINK 0x12 +#define DAP_CHAIN_BLOCK_META_NONCE 0x20 +#define DAP_CHAIN_BLOCK_META_NONCE2 0x21 +#define DAP_CHAIN_BLOCK_META_MERKLE 0x30 +#define DAP_CHAIN_BLOCK_META_EMERGENCY 0x80 +#define DAP_CHAIN_BLOCK_META_SYNC_ATTEMPT 0x81 +#define DAP_CHAIN_BLOCK_META_ROUND_ATTEMPT 0x82 +#define DAP_CHAIN_BLOCK_META_EXCLUDED_KEYS 0x83 /** * @struct dap_chain_block diff --git a/modules/type/blocks/include/dap_chain_block_cache.h b/modules/type/blocks/include/dap_chain_block_cache.h index 4ba9fffaba05aea576dc3db8342a19f482fc2aa7..b7cdf1e38098fd3d6f03f04d3e674f432acaa033 100644 --- a/modules/type/blocks/include/dap_chain_block_cache.h +++ b/modules/type/blocks/include/dap_chain_block_cache.h @@ -22,8 +22,6 @@ */ #pragma once #include "dap_chain_block.h" -#include "dap_chain_datum_tx.h" -#include "dap_sign.h" #include "dap_hash.h" #include "uthash.h" #include "dap_chain_ledger.h" diff --git a/modules/type/blocks/include/dap_chain_cs_blocks.h b/modules/type/blocks/include/dap_chain_cs_blocks.h index 985ead94e7d4497a26522bc7a174bd083658e84a..bb40da5a247e6a4fbb0adf662dd5650a6deaf976 100644 --- a/modules/type/blocks/include/dap_chain_cs_blocks.h +++ b/modules/type/blocks/include/dap_chain_cs_blocks.h @@ -34,8 +34,7 @@ #define DAP_FORK_MAX_DEPTH 100 - -#define DAP_REWARD_INIT_TIMESTAMP 1700870400UL // 25 Nov 00:00:00 GMT +#define DAP_REWARD_INIT_TIMESTAMP 1700870400UL // 25 Nov 2023 00:00:00 GMT typedef struct dap_chain_cs_blocks dap_chain_cs_blocks_t; @@ -65,6 +64,27 @@ typedef struct dap_chain_cs_blocks void * _inheritor; } dap_chain_cs_blocks_t; +typedef enum s_com_blocks_err{ + DAP_CHAIN_NODE_CLI_COM_BLOCK_OK = 0, + DAP_CHAIN_NODE_CLI_COM_BLOCK_PARAM_ERR, + DAP_CHAIN_NODE_CLI_COM_BLOCK_CHAIN_TYPE_ERR, + DAP_CHAIN_NODE_CLI_COM_BLOCK_DATUM_DEL_ERR, + DAP_CHAIN_NODE_CLI_COM_BLOCK_MEMORY_ERR, + DAP_CHAIN_NODE_CLI_COM_BLOCK_VERIF_ERR, + DAP_CHAIN_NODE_CLI_COM_BLOCK_HASH_ERR, + DAP_CHAIN_NODE_CLI_COM_BLOCK_FIND_ERR, + DAP_CHAIN_NODE_CLI_COM_BLOCK_DATUM_SIZE_ERR, + DAP_CHAIN_NODE_CLI_COM_BLOCK_CERT_ERR, + DAP_CHAIN_NODE_CLI_COM_BLOCK_PUB_KEY_ERR, + DAP_CHAIN_NODE_CLI_COM_BLOCK_CONVERT_ERR, + DAP_CHAIN_NODE_CLI_COM_BLOCK_PVT_KEY_ERR, + DAP_CHAIN_NODE_CLI_COM_BLOCK_SIGN_ERR, + + /* add custom codes here */ + + DAP_CHAIN_NODE_CLI_COM_BLOCK_UNKNOWN /* MAX */ +} s_com_blocks_err_t; + #define DAP_CHAIN_CS_BLOCKS(a) ((dap_chain_cs_blocks_t *)(a)->_inheritor) typedef int (*dap_chain_blocks_block_callback_ptr_t)(dap_chain_cs_blocks_t *, dap_chain_block_t *); diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c index b324de02644a4ec4eb46903483e81cdf75c1f04f..7b87103bd1fb1b01571cf7a348893d972fe9b8d2 100644 --- a/modules/type/dag/dap_chain_cs_dag.c +++ b/modules/type/dag/dap_chain_cs_dag.c @@ -83,7 +83,7 @@ typedef struct dap_chain_cs_dag_pvt { dap_chain_cs_dag_event_item_t * events_lasts_unlinked; dap_chain_cs_dag_blocked_t *removed_events_from_treshold; dap_interval_timer_t treshold_fee_timer; - size_t tx_count; + uint64_t tx_count; } dap_chain_cs_dag_pvt_t; #define PVT(a) ((dap_chain_cs_dag_pvt_t *) a->_pvt ) @@ -129,10 +129,10 @@ static dap_chain_datum_t *s_chain_callback_datum_iter_get_next(dap_chain_datum_i static int s_cli_dag(int argc, char ** argv, void **a_str_reply); void s_dag_events_lasts_process_new_last_event(dap_chain_cs_dag_t * a_dag, dap_chain_cs_dag_event_item_t * a_event_item); -static size_t s_dap_chain_callback_get_count_tx(dap_chain_t *a_chain); +static uint64_t s_dap_chain_callback_get_count_tx(dap_chain_t *a_chain); static dap_list_t *s_dap_chain_callback_get_txs(dap_chain_t *a_chain, size_t a_count, size_t a_page, bool a_reverse); -static size_t s_dap_chain_callback_get_count_atom(dap_chain_t *a_chain); +static uint64_t s_dap_chain_callback_get_count_atom(dap_chain_t *a_chain); static dap_list_t *s_callback_get_atoms(dap_chain_t *a_chain, size_t a_count, size_t a_page, bool a_reverse); static bool s_seed_mode = false, s_debug_more = false, s_threshold_enabled = false; @@ -705,8 +705,6 @@ static bool s_chain_callback_datums_pool_proc(dap_chain_t *a_chain, dap_chain_da return l_res; } - - /** * @brief dap_chain_cs_dag_find_event_by_hash * @param a_dag @@ -747,8 +745,6 @@ static bool s_event_verify_size(dap_chain_cs_dag_event_t *a_event, size_t a_even return l_sign_offset == a_event_size; } - - /** * @brief s_chain_callback_atom_verify Verify atomic element * @param a_chain @@ -1055,9 +1051,9 @@ static dap_chain_atom_ptr_t* s_chain_callback_atom_iter_get_links( dap_chain_ato (*a_links_size_array)[i] = l_link_item->event_size; }else { char l_err_str[256]; - unsigned l_off = dap_snprintf(l_err_str, sizeof(l_err_str), "Can't find %s -> ", + unsigned l_off = snprintf(l_err_str, sizeof(l_err_str), "Can't find %s -> ", dap_chain_hash_fast_to_str_static(l_link_hash)); - dap_snprintf(l_err_str + l_off, sizeof(l_err_str) - l_off, "%s links", + snprintf(l_err_str + l_off, sizeof(l_err_str) - l_off, "%s links", l_event_item ? dap_chain_hash_fast_to_str_static(&l_event_item->hash) : "<null>"); log_it(L_ERROR, "%s", l_err_str); (*a_links_size_array)--; @@ -1329,7 +1325,8 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply) return -1; } - dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, argc, argv, a_str_reply, &l_chain, &l_net); + dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, argc, argv, a_str_reply, &l_chain, &l_net, + CHAIN_TYPE_INVALID); if ((l_net == NULL) || (l_chain == NULL)){ return -1; } else if (a_str_reply && *a_str_reply) { @@ -1338,7 +1335,7 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply) } l_dag = DAP_CHAIN_CS_DAG(l_chain); - const char *l_chain_type = dap_chain_net_get_type(l_chain); + const char *l_chain_type = dap_chain_get_cs_type(l_chain); if (!strstr(l_chain_type, "dag_")){ dap_cli_server_cmd_set_reply_text(a_str_reply, @@ -1420,7 +1417,7 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply) // dap_chain_net_sync_all(l_net); } if (strcmp(l_round_cmd_str, "find") == 0) { - dap_cli_server_cmd_find_option_val(argv, arg_index, arg_index + 2, "-datum", &l_datum_hash_str); + dap_cli_server_cmd_find_option_val(argv, arg_index, argc, "-datum", &l_datum_hash_str); char *l_datum_in_hash = NULL; if (l_datum_hash_str) { if(!dap_strncmp(l_datum_hash_str, "0x", 2) || !dap_strncmp(l_datum_hash_str, "0X", 2)) { @@ -1685,7 +1682,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, DAP_TIME_STR_SIZE, l_round_item->round_info.ts_update); + dap_nanotime_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); } @@ -1768,15 +1765,16 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply) size_t l_objs_count = 0; l_objs = dap_global_db_get_all_sync(l_gdb_group_events,&l_objs_count); char *ptr; - size_t l_limit = l_limit_str ? strtoull(l_limit_str, &ptr, 10) : 0; + size_t l_limit = l_limit_str ? strtoull(l_limit_str, &ptr, 10) : 1000; size_t l_offset = l_offset_str ? strtoull(l_offset_str, &ptr, 10) : 0; size_t l_arr_start = 0; if (l_offset) { - l_arr_start = l_offset * l_limit; - dap_string_append_printf(l_str_tmp, "limit: %lu", l_arr_start); + l_arr_start = l_offset; + dap_string_append_printf(l_str_tmp, "offset: %lu\n", l_arr_start); } size_t l_arr_end = l_objs_count; if (l_limit) { + dap_string_append_printf(l_str_tmp, "limit: %lu\n", l_limit); l_arr_end = l_arr_start + l_limit; if (l_arr_end > l_objs_count) l_arr_end = l_objs_count; @@ -1793,14 +1791,14 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply) ((dap_chain_cs_dag_event_round_item_t *)l_objs[i].value)->event_n_signs; char buf[DAP_TIME_STR_SIZE]; dap_time_to_str_rfc822(buf, DAP_TIME_STR_SIZE, l_event->header.ts_created); - dap_string_append_printf(l_str_tmp, "\t%s: ts_create=%s\n", l_objs[i].key, buf); + dap_string_append_printf(l_str_tmp, "\t%zu\t - %s: ts_create=%s\n", i - 1, l_objs[i].key, buf); } if (l_objs && l_objs_count ) dap_global_db_objs_delete(l_objs, l_objs_count); ret = 0; } else { - dap_string_append_printf(l_str_tmp,"%s.%s: Error! No GlobalDB group!\n",l_net->pub.name,l_chain->name); + dap_string_append_printf(l_str_tmp, "%s.%s: Error! No GlobalDB group!\n", l_net->pub.name, l_chain->name); ret = -2; } @@ -1809,15 +1807,16 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply) } else if (!l_from_events_str || (strcmp(l_from_events_str,"events") == 0)) { dap_string_t * l_str_tmp = dap_string_new(NULL); pthread_mutex_lock(&PVT(l_dag)->events_mutex); - size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 0; + size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 1000; size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0; size_t l_arr_start = 0; - if (l_offset > 1) { - l_arr_start = l_offset * l_limit; - dap_string_append_printf(l_str_tmp, "limit: %lu\n", l_arr_start); + if (l_offset > 0) { + l_arr_start = l_offset; + dap_string_append_printf(l_str_tmp, "offset: %lu\n", l_arr_start); } size_t l_arr_end = HASH_COUNT(PVT(l_dag)->events); if (l_limit) { + dap_string_append_printf(l_str_tmp, "limit: %lu\n", l_limit); l_arr_end = l_arr_start + l_limit; if (l_arr_end > HASH_COUNT(PVT(l_dag)->events)) l_arr_end = HASH_COUNT(PVT(l_dag)->events); @@ -1831,7 +1830,7 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply) i_tmp++; 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_string_append_printf(l_str_tmp, "\t%zu\t- %s: ts_create=%s\n", i_tmp, dap_chain_hash_fast_to_str_static(&l_event_item->hash), buf); } @@ -1850,11 +1849,12 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply) size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0; size_t l_arr_start = 0; if (l_offset) { - l_arr_start = l_offset * l_limit; - dap_string_append_printf(l_str_tmp, "limit: %lu", l_arr_start); + l_arr_start = l_offset; + dap_string_append_printf(l_str_tmp, "offset: %lu\n", l_arr_start); } size_t l_arr_end = HASH_COUNT(PVT(l_dag)->events_treshold); if (l_limit) { + dap_string_append_printf(l_str_tmp, "limit: %lu\n", l_limit); l_arr_end = l_arr_start + l_limit; if (l_arr_end > HASH_COUNT(PVT(l_dag)->events_treshold)) l_arr_end = HASH_COUNT(PVT(l_dag)->events_treshold); @@ -1869,7 +1869,7 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply) i_tmp++; 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_string_append_printf(l_str_tmp, "\t%zu\t- %s: ts_create=%s\n", i_tmp, dap_chain_hash_fast_to_str_static( &l_event_item->hash), buf); } @@ -1898,7 +1898,7 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply) } size_t l_event_count = HASH_COUNT(PVT(l_dag)->events); size_t l_event_treshold_count = HASH_COUNT(PVT(l_dag)->events_treshold); - dap_string_append_printf(l_ret_str, "%zu atoms(s) in events\n%zu atom(s) in threshold", l_event_count, l_event_treshold_count); + dap_string_append_printf(l_ret_str, "%zu atom(s) in events\n%zu atom(s) in threshold", l_event_count, l_event_treshold_count); dap_cli_server_cmd_set_reply_text(a_str_reply, "%s", l_ret_str->str); dap_string_free(l_ret_str, true); } break; @@ -1975,7 +1975,7 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply) return ret; } -static size_t s_dap_chain_callback_get_count_tx(dap_chain_t *a_chain) +static uint64_t s_dap_chain_callback_get_count_tx(dap_chain_t *a_chain) { return PVT(DAP_CHAIN_CS_DAG(a_chain))->tx_count; } @@ -2005,10 +2005,11 @@ static dap_list_t *s_dap_chain_callback_get_txs(dap_chain_t *a_chain, size_t a_c return l_list; } -static size_t s_dap_chain_callback_get_count_atom(dap_chain_t *a_chain){ +static uint64_t s_dap_chain_callback_get_count_atom(dap_chain_t *a_chain) +{ dap_chain_cs_dag_t *l_dag = DAP_CHAIN_CS_DAG(a_chain); pthread_mutex_lock(&PVT(l_dag)->events_mutex); - size_t l_count = HASH_COUNT(PVT(l_dag)->events); + uint64_t l_count = HASH_COUNT(PVT(l_dag)->events); pthread_mutex_unlock(&PVT(l_dag)->events_mutex); return l_count; } 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 bbe4f5b064044e7bc25f1b59e601f50fbaebab05..e4ac5b7a66382a90676db4ee389aab97f936c0c1 100644 --- a/modules/type/dag/include/dap_chain_cs_dag_event.h +++ b/modules/type/dag/include/dap_chain_cs_dag_event.h @@ -35,7 +35,7 @@ typedef struct dap_chain_cs_dag dap_chain_cs_dag_t; typedef struct dap_chain_class_dag_event_hdr { uint16_t version; uint64_t round_id; - dap_nanotime_t ts_created; + dap_time_t ts_created; dap_chain_id_t chain_id; dap_chain_cell_id_t cell_id; // Cell id if celled dag uint16_t hash_count; // Number of hashes diff --git a/modules/type/none/dap_chain_cs_none.c b/modules/type/none/dap_chain_cs_none.c index 45f1dee54dfb41ec918bd939bd895dfe9554b7bf..7cc90543c2872bd26ca91e80d8d4732f0cb98ce1 100644 --- a/modules/type/none/dap_chain_cs_none.c +++ b/modules/type/none/dap_chain_cs_none.c @@ -54,8 +54,6 @@ typedef struct dap_nonconsensus_private { bool is_load_mode; // If load mode - not save when new atom adds char *group_datums; dap_chain_t *chain; - pthread_cond_t load_cond; - pthread_mutex_t load_mutex; dap_nonconsensus_datum_hash_item_t * hash_items; } dap_nonconsensus_private_t; @@ -134,6 +132,12 @@ static void s_changes_callback_notify(dap_store_obj_t *a_obj, void *a_arg) s_nonconsensus_callback_atom_add(l_chain, (dap_chain_datum_t *)a_obj->value, a_obj->value_len, &l_hash); } +int s_nonconsensus_callback_created(dap_chain_t *a_chain, dap_config_t UNUSED_ARG *a_chain_cfg) +{ + dap_chain_add_mempool_notify_callback(a_chain, s_nonconsensus_callback_mempool_notify, a_chain); + return 0; +} + /** * @brief configure chain gdb * Set atom element callbacks @@ -167,16 +171,12 @@ static int s_cs_callback_new(dap_chain_t *a_chain, dap_config_t UNUSED_ARG *a_ch dap_global_db_cluster_add(dap_global_db_instance_get_default(), l_net->pub.name, dap_guuid_compose(l_net->pub.id.uint64, 0), l_nochain_priv->group_datums, 0, - true, DAP_GDB_MEMBER_ROLE_USER, DAP_CLUSTER_ROLE_EMBEDDED); + true, DAP_GDB_MEMBER_ROLE_USER, DAP_CLUSTER_TYPE_EMBEDDED); if (!l_nonconsensus_cluster) { log_it(L_ERROR, "Can't create global DB cluster for synchronization"); return -3; } dap_global_db_cluster_add_notify_callback(l_nonconsensus_cluster, s_changes_callback_notify, a_chain); - dap_chain_add_mempool_notify_callback(a_chain, s_nonconsensus_callback_mempool_notify, a_chain); - - pthread_cond_init(&l_nochain_priv->load_cond, NULL); - pthread_mutex_init(&l_nochain_priv->load_mutex, NULL); a_chain->callback_delete = s_nonconsensus_delete; a_chain->callback_purge = s_nonconsensus_callback_purge; @@ -207,6 +207,7 @@ static int s_cs_callback_new(dap_chain_t *a_chain, dap_config_t UNUSED_ARG *a_ch a_chain->callback_add_datums = s_nonconsensus_callback_datums_pool_proc; a_chain->callback_load_from_gdb = s_nonconsensus_ledger_load; + a_chain->callback_created = s_nonconsensus_callback_created; return 0; } @@ -244,46 +245,6 @@ const char* dap_nonconsensus_get_group(dap_chain_t * a_chain) } -/** - * @brief s_ledger_load_callback - * @param a_global_db_context - * @param a_rc - * @param a_group - * @param a_key - * @param a_values_total - * @param a_values_shift - * @param a_values_count - * @param a_values - * @param a_arg - */ -static bool s_ledger_load_callback(UNUSED_ARG dap_global_db_instance_t *a_dbi, - UNUSED_ARG int a_rc, UNUSED_ARG const char *a_group, - UNUSED_ARG const size_t a_values_total, const size_t a_values_count, - dap_global_db_obj_t *a_values, void *a_arg) -{ - assert(a_arg); - dap_chain_t * l_chain = (dap_chain_t *) a_arg; - assert(l_chain); - dap_nonconsensus_t * l_nochain = DAP_NONCONSENSUS(l_chain); - assert(l_nochain); - dap_nonconsensus_private_t * l_nochain_pvt = PVT(l_nochain); - assert(l_nochain_pvt); - // make list of datums - for(size_t i = 0; i < a_values_count; i++) { - dap_global_db_obj_t *it = a_values + i; - dap_hash_fast_t l_hash = {}; - dap_hash_fast(it->value, it->value_len, &l_hash); - s_nonconsensus_callback_atom_add(l_chain, it->value, it->value_len, &l_hash); - log_it(L_DEBUG,"Load mode, doesn't save item %s:%s", it->key, l_nochain_pvt->group_datums); - } - - pthread_mutex_lock(&l_nochain_pvt->load_mutex); - l_nochain_pvt->is_load_mode = false; - pthread_cond_broadcast(&l_nochain_pvt->load_cond); - pthread_mutex_unlock(&l_nochain_pvt->load_mutex); - return true; -} - /** * @brief Load ledger from mempool * @@ -293,16 +254,20 @@ static bool s_ledger_load_callback(UNUSED_ARG dap_global_db_instance_t *a_dbi, */ static void s_nonconsensus_ledger_load(dap_chain_t *a_chain) { - dap_nonconsensus_t * l_nochain = DAP_NONCONSENSUS(a_chain); - dap_nonconsensus_private_t * l_nochain_pvt = PVT(l_nochain); - // load ledger - l_nochain_pvt->is_load_mode = true; + dap_nonconsensus_t *l_nochain = DAP_NONCONSENSUS(a_chain); + dap_nonconsensus_private_t *l_nochain_pvt = PVT(l_nochain); + size_t l_values_count = 0; // Read the entire database into an array of size bytes - pthread_mutex_lock(&l_nochain_pvt->load_mutex); - dap_global_db_get_all(l_nochain_pvt->group_datums, 0, s_ledger_load_callback, a_chain); - while (l_nochain_pvt->is_load_mode) - pthread_cond_wait(&l_nochain_pvt->load_cond, &l_nochain_pvt->load_mutex); - pthread_mutex_unlock(&l_nochain_pvt->load_mutex); + dap_global_db_obj_t *l_values = dap_global_db_get_all_sync(l_nochain_pvt->group_datums, &l_values_count); + // make list of datums + for (size_t i = 0; l_values && i < l_values_count; i++) { + dap_global_db_obj_t *it = l_values + i; + // load ledger + s_nonconsensus_callback_atom_add(a_chain, it->value, it->value_len); + log_it(L_DEBUG,"Load mode, doesn't save item %s:%s", it->key, l_nochain_pvt->group_datums); + } + dap_global_db_objs_delete(l_values, l_values_count); + l_nochain_pvt->is_load_mode = false; } /** @@ -453,7 +418,8 @@ static dap_chain_atom_ptr_t s_nonconsensus_callback_atom_iter_find_by_hash(dap_c dap_nonconsensus_t *l_nochain = DAP_NONCONSENSUS(a_atom_iter->chain); if (l_nochain) { l_ret = dap_global_db_get_sync(PVT(l_nochain)->group_datums, l_key, &l_ret_size, NULL, NULL); - *a_atom_size = l_ret_size; + if (a_atom_size) + *a_atom_size = l_ret_size; } //TODO set a_atom_iter item field return l_ret;