diff --git a/CMakeLists.txt b/CMakeLists.txt index 426811025385c726a2170500dfb712a3dedd516c..eb4b01fd89578a2f97d44cacc1d97f1b63908165 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,12 +49,11 @@ if(WIN32) add_definitions ("-D_POSIX") add_definitions ("-D_POSIX_") add_definitions ("-D_POSIX_THREAD_SAFE_FUNCTIONS") - add_definitions ("-DNODE_NETNAME=\"kelvin\"") + add_definitions ("-DNODE_NETNAME=\"cellframe\"") include_directories(../libdap/src/win32/) include_directories(../3rdparty/wepoll/include/) include_directories(../3rdparty/uthash/src/) include_directories(../3rdparty/libjson-c/) - include_directories(../3rdparty/libmagic/src/) include_directories(../3rdparty/curl/include/) include_directories(../3rdparty/libsqlite3/) endif() @@ -62,7 +61,7 @@ endif() add_library(${PROJECT_NAME} STATIC ${DAP_CHAIN_NET_SRCS} ${DAP_CHAIN_NET_HEADERS} ${IPUTILS_SRCS} ${IPUTILS_HEADERS}) if(WIN32) - target_link_libraries(dap_chain_net dap_core dap_crypto dap_client dap_stream_ch_chain dap_stream_ch_chain_net dap_chain dap_chain_gdb dap_chain_crypto dap_chain_wallet dap_chain_net_srv dap_chain_net_srv_vpn dap_chain_mempool dap_chain_global_db ) + target_link_libraries(dap_chain_net dap_core dap_crypto dap_client dap_stream_ch_chain dap_stream_ch_chain_net dap_chain dap_chain_gdb dap_chain_crypto dap_chain_wallet dap_chain_net_srv dap_chain_mempool dap_chain_global_db ) endif() if(UNIX) diff --git a/dap_chain_net.c b/dap_chain_net.c index a106848e7ad167fb5dcfb30ee1ed1a05fc78587f..9fda000d9d70f7cc7cc1972b4bebf59770eda358 100755 --- a/dap_chain_net.c +++ b/dap_chain_net.c @@ -630,6 +630,7 @@ lb_proc_state: } } break; + default: log_it (L_DEBUG, "Unprocessed state"); } pthread_mutex_unlock(&PVT(l_net)->state_mutex ); return ret; @@ -845,6 +846,13 @@ void dap_chain_net_load_all() continue; } DAP_DELETE(l_full_path); + // search only ".cfg" files + if(strlen(l_dir_entry->d_name) > 4) { // It has non zero name excluding file extension + if(strncmp(l_dir_entry->d_name + strlen(l_dir_entry->d_name) - 4, ".cfg", 4) != 0) { + // its not .cfg file + continue; + } + } log_it(L_DEBUG,"Network config %s try to load", l_dir_entry->d_name); //char* l_dot_pos = rindex(l_dir_entry->d_name,'.'); char* l_dot_pos = strchr(l_dir_entry->d_name,'.'); @@ -1066,6 +1074,23 @@ static int s_cli_net( int argc, char **argv, char **a_str_reply) return ret; } +// for sequential loading chains +typedef struct list_priority_{ + uint16_t prior; + char * chains_path; +}list_priority; + +static int callback_compare_prioritity_list(const void * a_item1, const void * a_item2) +{ + list_priority *l_item1 = (list_priority*) a_item1; + list_priority *l_item2 = (list_priority*) a_item2; + if(!l_item1 || !l_item2 || l_item1->prior == l_item2->prior) + return 0; + if(l_item1->prior > l_item2->prior) + return 1; + return -1; +} + /** * @brief s_net_load * @param a_net_name @@ -1312,6 +1337,9 @@ int s_net_load(const char * a_net_name) DIR * l_chains_dir = opendir(l_chains_path); DAP_DELETE (l_chains_path); if ( l_chains_dir ){ + // for sequential loading chains + dap_list_t *l_prior_list = NULL; + struct dirent * l_dir_entry; while ( (l_dir_entry = readdir(l_chains_dir) )!= NULL ){ if (l_dir_entry->d_name[0]=='\0') @@ -1322,20 +1350,48 @@ int s_net_load(const char * a_net_name) l_entry_name [strlen(l_entry_name)-4] = 0; log_it(L_DEBUG,"Open chain config \"%s\"...",l_entry_name); l_chains_path = dap_strdup_printf("network/%s/%s",l_net->pub.name,l_entry_name); - // Create chain object - dap_chain_t * l_chain = dap_chain_load_from_cfg(l_net->pub.ledger, l_net->pub.name, - l_net->pub.id, l_chains_path); - if(l_chain) { - DL_APPEND(l_net->pub.chains, l_chain); - if(l_chain->callback_created) - l_chain->callback_created(l_chain, l_cfg); + dap_config_t * l_cfg = dap_config_open(l_chains_path); + if(l_cfg) { + list_priority *l_chain_prior = DAP_NEW_Z(list_priority); + l_chain_prior->prior = dap_config_get_item_uint16_default(l_cfg, "chain", "load_priority", 100); + l_chain_prior->chains_path = l_chains_path; + // add chain to load list; + l_prior_list = dap_list_append(l_prior_list, l_chain_prior); } - DAP_DELETE (l_chains_path); + // Create chain object +// dap_chain_t * l_chain = dap_chain_load_from_cfg(l_net->pub.ledger, l_net->pub.name, +// l_net->pub.id, l_chains_path); +// if(l_chain) { +// DL_APPEND(l_net->pub.chains, l_chain); +// if(l_chain->callback_created) +// l_chain->callback_created(l_chain, l_cfg); +// } +// DAP_DELETE (l_chains_path); } } DAP_DELETE (l_entry_name); } closedir(l_chains_dir); + + // sort list with chains names by priority + l_prior_list = dap_list_sort(l_prior_list, callback_compare_prioritity_list); + // load chains by priority + dap_list_t *l_list = l_prior_list; + while(l_list){ + list_priority *l_chain_prior = l_list->data; + // Create chain object + dap_chain_t * l_chain = dap_chain_load_from_cfg(l_net->pub.ledger, l_net->pub.name, + l_net->pub.id, l_chain_prior->chains_path); + if(l_chain) { + DL_APPEND(l_net->pub.chains, l_chain); + if(l_chain->callback_created) + l_chain->callback_created(l_chain, l_cfg); + } + DAP_DELETE (l_chain_prior->chains_path); + l_list = dap_list_next(l_list); + } + dap_list_free(l_prior_list); + } else { log_it(L_ERROR,"Can't any chains for network %s",l_net->pub.name); PVT(l_net)->load_mode = false; @@ -1485,7 +1541,7 @@ dap_chain_t * dap_chain_net_get_chain_by_name( dap_chain_net_t * l_net, const ch { dap_chain_t * l_chain; DL_FOREACH(l_net->pub.chains, l_chain){ - if(strcmp(l_chain->name,a_name) == 0) + if(dap_strcmp(l_chain->name,a_name) == 0) return l_chain; } return NULL; @@ -1561,3 +1617,42 @@ void dap_chain_net_proc_datapool (dap_chain_net_t * a_net) { } + +/** + * @brief dap_chain_net_tx_get_by_hash + * @param a_net + * @param a_tx_hash + * @param a_search_type + * @return + */ +dap_chain_datum_tx_t * dap_chain_net_get_tx_by_hash(dap_chain_net_t * a_net, dap_chain_hash_fast_t * a_tx_hash, + dap_chain_net_tx_search_type_t a_search_type) +{ + dap_ledger_t * l_ledger = dap_chain_ledger_by_net_name( a_net->pub.name ); + dap_chain_datum_tx_t * l_tx = NULL; + + switch (a_search_type) { + case TX_SEARCH_TYPE_NET: + case TX_SEARCH_TYPE_CELL: + case TX_SEARCH_TYPE_LOCAL:{ + if ( ! l_tx ){ + // pass all chains + for ( dap_chain_t * l_chain = a_net->pub.chains; l_chain; l_chain = l_chain->next){ + if ( l_chain->callback_tx_find_by_hash ){ + // try to find transaction in chain ( inside shard ) + l_tx = l_chain->callback_tx_find_by_hash( l_chain, a_tx_hash ); + if (l_tx) + break; + } + } + } + }break; + + case TX_SEARCH_TYPE_NET_UNSPENT: + case TX_SEARCH_TYPE_CELL_UNSPENT:{ + l_tx = dap_chain_ledger_tx_find_by_hash( l_ledger, a_tx_hash ); + }break; + } + return l_tx; +} + diff --git a/dap_chain_net.h b/dap_chain_net.h index 05d9e73f13bd4e687299c83e89e91d342501908a..99cd058fc8b01ce4cb06cfe68619c38a61deeb8e 100644 --- a/dap_chain_net.h +++ b/dap_chain_net.h @@ -1,27 +1,28 @@ /* - * Authors: - * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net> - * Alexander Lysikov <alexander.lysikov@demlabs.net> - * DeM Labs Inc. https://demlabs.net - * Kelvin Project https://github.com/kelvinblockchain - * Copyright (c) 2017-2019 - * 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/>. +* Authors: +* Dmitriy Gerasimov <naeper@demlabs.net> +* Aleksandr Lysikov <alexander.lysikov@demlabs.net> +* Cellframe https://cellframe.net +* DeM Labs Inc. https://demlabs.net +* Copyright (c) 2017-2019 +* All rights reserved. + +This file is part of CellFrame SDK the open source project + +CellFrame SDK 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. + +CellFrame SDK 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 CellFrame SDK based project. If not, see <http://www.gnu.org/licenses/>. */ + #pragma once #ifndef _WIN32 @@ -107,6 +108,21 @@ dap_chain_cell_id_t * dap_chain_net_get_cur_cell( dap_chain_net_t * l_net); void dap_chain_net_links_connect(dap_chain_net_t * a_net); +typedef enum dap_chain_net_tx_search_type { + /// Search local, in memory, possible load data from drive to memory + TX_SEARCH_TYPE_LOCAL, + /// Do the request to the network if its not full node, search inside shard + TX_SEARCH_TYPE_CELL, + /// Do the request for unspent txs in cell + TX_SEARCH_TYPE_CELL_UNSPENT, + /// Do the search in whole network and request tx from others cells if need + TX_SEARCH_TYPE_NET, + /// Do the search in whole network but search only unspent + TX_SEARCH_TYPE_NET_UNSPENT +}dap_chain_net_tx_search_type_t; + +dap_chain_datum_tx_t * dap_chain_net_get_tx_by_hash(dap_chain_net_t * a_net, dap_chain_hash_fast_t * a_tx_hash, + dap_chain_net_tx_search_type_t a_search_type); /** * @brief dap_chain_net_get_gdb_group_mempool diff --git a/dap_chain_node.c b/dap_chain_node.c index 68436d22441b736aeefc2a47cee8b17486fff6ef..1fb9ae970c2cd5b2eda0b3bc9e9e4cfe6385f54c 100644 --- a/dap_chain_node.c +++ b/dap_chain_node.c @@ -86,12 +86,12 @@ bool dap_chain_node_check_addr(dap_chain_net_t * a_net,dap_chain_node_addr_t *ad */ bool dap_chain_node_alias_register(dap_chain_net_t * a_net,const char *alias, dap_chain_node_addr_t *addr) { - const char *a_key = alias; + char *a_key = strdup(alias); // char a_value[2 * sizeof(dap_chain_node_addr_t) + 1]; // if(bin2hex(a_value, (const unsigned char *) addr, sizeof(dap_chain_node_addr_t)) == -1) // return false; // a_value[2 * sizeof(dap_chain_node_addr_t)] = '\0'; - bool res = dap_chain_global_db_gr_set(a_key, (const uint8_t*) addr, sizeof(dap_chain_node_addr_t) + bool res = dap_chain_global_db_gr_set(a_key, addr, sizeof(dap_chain_node_addr_t) , a_net->pub.gdb_nodes_aliases); return res; } @@ -114,7 +114,7 @@ dap_chain_node_addr_t * dap_chain_node_alias_find(dap_chain_net_t * a_net,const */ bool dap_chain_node_alias_delete(dap_chain_net_t * a_net,const char *a_alias) { - const char *a_key = a_alias; + char *a_key = strdup(a_alias); bool res = dap_chain_global_db_gr_del(a_key, a_net->pub.gdb_nodes_aliases); return res; } @@ -153,7 +153,7 @@ int dap_chain_node_info_save(dap_chain_net_t * a_net, dap_chain_node_info_t *nod } //char *a_value = dap_chain_node_info_serialize(node_info, NULL); size_t node_info_size = dap_chain_node_info_get_size(node_info); - bool res = dap_chain_global_db_gr_set(l_key, (const uint8_t *) node_info, node_info_size, a_net->pub.gdb_nodes); + bool res = dap_chain_global_db_gr_set(l_key, node_info, node_info_size, a_net->pub.gdb_nodes); DAP_DELETE(l_key); //DAP_DELETE(a_value); return res?0:-3; diff --git a/dap_chain_node_cli_cmd.c b/dap_chain_node_cli_cmd.c index 216067c774d268d014380bb460ccd9eee8b77d21..8ae4d435ec1287844df1348ff3611867331300a7 100644 --- a/dap_chain_node_cli_cmd.c +++ b/dap_chain_node_cli_cmd.c @@ -63,7 +63,7 @@ #include "dap_strfuncs.h" #include "dap_list.h" #include "dap_string.h" -#include "dap_chain_cert.h" +#include "dap_cert.h" #include "dap_chain_wallet.h" #include "dap_chain_node.h" #include "dap_chain_global_db.h" @@ -1183,7 +1183,7 @@ int com_node(int a_argc, char ** a_argv, char **a_str_reply) } dap_stream_ch_set_ready_to_write(l_ch_chain, true); // wait for finishing of request - timeout_ms = 120000; // 20 min = 1200 sec = 1 200 000 ms + timeout_ms = 1200000; // 20 min = 1200 sec = 1 200 000 ms // TODO add progress info to console res = dap_chain_node_client_wait(l_node_client, NODE_CLIENT_STATE_SYNCED, timeout_ms); if(res < 0) { @@ -1199,12 +1199,14 @@ int com_node(int a_argc, char ** a_argv, char **a_str_reply) dap_chain_t *l_chain = NULL; DL_FOREACH(l_net->pub.chains, l_chain) { + // reset state NODE_CLIENT_STATE_SYNCED + l_node_client->state = NODE_CLIENT_STATE_CONNECTED; // send request dap_stream_ch_chain_sync_request_t l_sync_request = { { 0 } }; if(0 == dap_stream_ch_chain_pkt_write(l_ch_chain, DAP_STREAM_CH_CHAIN_PKT_TYPE_SYNC_CHAINS, l_net->pub.id, l_chain->id, l_remote_node_info->hdr.cell_id, &l_sync_request, sizeof(l_sync_request))) { - dap_chain_node_cli_set_reply_text(a_str_reply, "Error: Cant send sync chains request"); + dap_chain_node_cli_set_reply_text(a_str_reply, "Error: Can't send sync chains request"); // clean client struct dap_chain_node_client_close(l_node_client); DAP_DELETE(l_remote_node_info); @@ -1217,6 +1219,9 @@ int com_node(int a_argc, char ** a_argv, char **a_str_reply) timeout_ms = 120000; // 2 min = 120 sec = 120 000 ms // TODO add progress info to console res = dap_chain_node_client_wait(l_node_client, NODE_CLIENT_STATE_SYNCED, timeout_ms); + if(res < 0) { + log_it(L_ERROR, "Error: Can't sync chain %s", l_chain->name); + } } log_it(L_INFO, "Chains and gdb are synced"); DAP_DELETE(l_remote_node_info); @@ -1575,6 +1580,8 @@ int com_tx_wallet(int argc, char ** argv, char **str_reply) dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-w", &wallet_name); dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-net", &l_net_name); // for + dap_chain_net_t * l_net = l_net_name ? dap_chain_net_by_name( l_net_name) : NULL; + dap_string_t *l_string_ret = dap_string_new(NULL); switch (cmd_num) { // new wallet @@ -1584,18 +1591,18 @@ int com_tx_wallet(int argc, char ** argv, char **str_reply) "wallet name option <-w> not defined"); return -1; } - dap_chain_sign_type_t l_sign_type = { SIG_TYPE_BLISS }; - dap_chain_net_id_t l_net_id = { 0x1 }; + dap_sign_type_t l_sign_type = { SIG_TYPE_BLISS }; // Creates new wallet - dap_chain_wallet_t *l_wallet = dap_chain_wallet_create(wallet_name, c_wallets_path, l_net_id, l_sign_type); - dap_chain_addr_t *l_addr = (dap_chain_addr_t *) dap_chain_wallet_get_addr(l_wallet); - if(!l_wallet || !l_addr) { + dap_chain_wallet_t *l_wallet = dap_chain_wallet_create(wallet_name, c_wallets_path, l_sign_type); + dap_chain_addr_t *l_addr = l_net? dap_chain_wallet_get_addr(l_wallet,l_net->pub.id ) : NULL; + if(!l_wallet ) { dap_chain_node_cli_set_reply_text(str_reply, "wallet is not created"); return -1; } - char *l_addr_str = dap_chain_addr_to_str(l_addr); + char *l_addr_str = l_addr? dap_chain_addr_to_str(l_addr) : NULL; dap_string_append_printf(l_string_ret, "wallet '%s' successfully created\n", l_wallet->name); - dap_string_append_printf(l_string_ret, "new address %s", l_addr_str); + if ( l_addr_str ) + dap_string_append_printf(l_string_ret, "new address %s", l_addr_str); DAP_DELETE(l_addr_str); dap_chain_wallet_close(l_wallet); } @@ -1612,11 +1619,13 @@ int com_tx_wallet(int argc, char ** argv, char **str_reply) char *l_file_path_tmp = dap_strdup_printf("%s/%s", c_wallets_path, l_file_name); dap_chain_wallet_t *l_wallet = dap_chain_wallet_open_file(l_file_path_tmp); if(l_wallet) { - dap_chain_addr_t *l_addr = dap_chain_wallet_get_addr(l_wallet); + dap_chain_addr_t *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); dap_string_append_printf(l_string_ret, "\nwallet: %s\n", l_wallet->name); - dap_string_append_printf(l_string_ret, "addr: %s\n", (l_addr_str) ? l_addr_str : "-"); - DAP_DELETE(l_addr_str); + if ( l_addr_str){ + dap_string_append_printf(l_string_ret, "addr: %s\n", (l_addr_str) ? l_addr_str : "-"); + DAP_DELETE(l_addr_str); + } dap_chain_wallet_close(l_wallet); } DAP_DELETE(l_file_path_tmp); @@ -1634,7 +1643,8 @@ int com_tx_wallet(int argc, char ** argv, char **str_reply) if(wallet_name) { l_wallet = dap_chain_wallet_open(wallet_name, c_wallets_path); - l_addr = (dap_chain_addr_t *) dap_chain_wallet_get_addr(l_wallet); + if ( l_net ) + l_addr = (dap_chain_addr_t *) dap_chain_wallet_get_addr(l_wallet, l_net->pub.id ); } if(!l_addr && addr_str) l_addr = dap_chain_addr_from_str(addr_str); @@ -1774,7 +1784,7 @@ int com_token_decl_sign(int argc, char ** argv, char ** a_str_reply) if(l_datum_hash_str) { const char * l_certs_str = NULL; - dap_chain_cert_t ** l_certs = NULL; + dap_cert_t ** l_certs = NULL; size_t l_certs_count = 0; dap_chain_t * l_chain; @@ -1795,7 +1805,7 @@ int com_token_decl_sign(int argc, char ** argv, char ** a_str_reply) // Load certs lists if (l_certs_str) - dap_chain_cert_parse_str_list(l_certs_str, &l_certs, &l_certs_count); + dap_cert_parse_str_list(l_certs_str, &l_certs, &l_certs_count); if(!l_certs_count) { dap_chain_node_cli_set_reply_text(a_str_reply, @@ -1826,9 +1836,9 @@ int com_token_decl_sign(int argc, char ** argv, char ** a_str_reply) size_t l_signs_count = 0; for(size_t l_offset = 0; l_offset < l_signs_size; l_signs_count++) { - dap_chain_sign_t * l_sign = (dap_chain_sign_t *) l_datum_token->signs + l_offset; - l_offset += dap_chain_sign_get_size(l_sign); - if( dap_chain_sign_verify(l_sign, l_datum_token, sizeof(l_datum_token->header)) != 1) { + dap_sign_t * l_sign = (dap_sign_t *) l_datum_token->signs + l_offset; + l_offset += dap_sign_get_size(l_sign); + if( dap_sign_verify(l_sign, l_datum_token, sizeof(l_datum_token->header)) != 1) { log_it(L_WARNING, "Wrong signature %u for datum_token with key %s in mempool!", l_signs_count, l_datum_hash_str); dap_chain_node_cli_set_reply_text(a_str_reply, "Datum %s with datum token has wrong signature %u, break process and exit", @@ -1865,10 +1875,10 @@ int com_token_decl_sign(int argc, char ** argv, char ** a_str_reply) else if(l_datum_token->header.signs_total >= l_signs_count + l_certs_count) { size_t l_offset = 0; for(size_t i = 0; i < l_certs_count; i++) { - dap_chain_sign_t * l_sign = dap_chain_sign_create(l_certs[i]->enc_key, + dap_sign_t * l_sign = dap_sign_create(l_certs[i]->enc_key, l_datum_token, sizeof(l_datum_token->header), 0); - size_t l_sign_size = dap_chain_sign_get_size(l_sign); + size_t l_sign_size = dap_sign_get_size(l_sign); l_signs_size+= l_sign_size; @@ -1894,14 +1904,15 @@ int com_token_decl_sign(int argc, char ** argv, char ** a_str_reply) // Recalc hash, string and place new datum // Calc datum's hash - dap_chain_hash_fast_t l_key_hash; - dap_hash_fast(l_datum, l_datum_size, (uint8_t*) &l_key_hash); + dap_chain_hash_fast_t l_key_hash={0}; + dap_hash_fast(l_datum, l_datum_size, &l_key_hash); char * l_key_str = dap_chain_hash_fast_to_str_new(&l_key_hash); // Add datum to mempool with datum_token hash as a key if(dap_chain_global_db_gr_set(l_key_str, (uint8_t *) l_datum, l_datum_size, l_gdb_group_mempool)) { + char* l_hash_str = strdup(l_datum_hash_str); // Remove old datum from pool - if(dap_chain_global_db_gr_del(l_datum_hash_str, l_gdb_group_mempool)) { + if(dap_chain_global_db_gr_del( l_hash_str, l_gdb_group_mempool)) { dap_chain_node_cli_set_reply_text(a_str_reply, "datum %s produced from %s is replacing the %s in datum pool", l_key_str, l_datum_hash_str, l_datum_hash_str); @@ -1919,6 +1930,7 @@ int com_token_decl_sign(int argc, char ** argv, char ** a_str_reply) DAP_DELETE(l_gdb_group_mempool); return 1; } + DAP_DELETE(l_hash_str); } else { @@ -2056,12 +2068,15 @@ int com_mempool_delete(int argc, char ** argv, char ** a_str_reply) const char * l_datum_hash_str = NULL; dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-datum", &l_datum_hash_str); if(l_datum_hash_str) { + char * l_datum_hash_str2 = strdup(l_datum_hash_str); char * l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool(l_chain); - if(dap_chain_global_db_gr_del(l_datum_hash_str, l_gdb_group_mempool)) { + if(dap_chain_global_db_gr_del(l_datum_hash_str2, l_gdb_group_mempool)) { dap_chain_node_cli_set_reply_text(a_str_reply, "Datum %s deleted", l_datum_hash_str); + DAP_DELETE( l_datum_hash_str2); return 0; } else { dap_chain_node_cli_set_reply_text(a_str_reply, "Error! Can't find datum %s", l_datum_hash_str); + DAP_DELETE( l_datum_hash_str2); return -4; } } else { @@ -2146,10 +2161,13 @@ int com_mempool_proc(int argc, char ** argv, char ** a_str_reply) if(l_objs_processed > 15) { dap_string_append_printf(l_str_tmp, "...\n"); } + if(l_objs_processed < l_datums_size) + dap_string_append_printf(l_str_tmp, "%s.%s: %d records not processed\n", l_net->pub.name, l_chain->name, + l_datums_size - l_objs_processed); dap_chain_global_db_objs_delete(l_objs, l_objs_size); } else { - dap_string_append_printf(l_str_tmp, "%s.%s: No records in mempool\n", l_net->pub.name, l_chain->name); + dap_string_append_printf(l_str_tmp, "%s.%s: No records in mempool\n", l_net->pub.name, l_chain ? l_chain->name : "[no chain]"); } DAP_DELETE(l_gdb_group_mempool); // only one time if group defined @@ -2184,7 +2202,7 @@ int com_token_decl(int argc, char ** argv, char ** a_str_reply) const char * l_certs_str = NULL; - dap_chain_cert_t ** l_certs = NULL; + dap_cert_t ** l_certs = NULL; size_t l_certs_size = 0; dap_chain_t * l_chain = NULL; @@ -2266,7 +2284,7 @@ int com_token_decl(int argc, char ** argv, char ** a_str_reply) } // Load certs lists - dap_chain_cert_parse_str_list(l_certs_str, &l_certs, &l_certs_size); + dap_cert_parse_str_list(l_certs_str, &l_certs, &l_certs_size); if(!l_certs_size) { dap_chain_node_cli_set_reply_text(a_str_reply, "token_create command requres at least one valid certificate to sign the basic transaction of emission"); @@ -2289,11 +2307,11 @@ int com_token_decl(int argc, char ** argv, char ** a_str_reply) // Sign header with all certificates in the list and add signs to the end of ticker declaration // Important: for(size_t i = 0; i < l_certs_size; i++) { - dap_chain_sign_t * l_sign = dap_chain_cert_sign(l_certs[i], + dap_sign_t * l_sign = dap_cert_sign(l_certs[i], l_datum_token, sizeof(l_datum_token->header), 0); - size_t l_sign_size = dap_chain_sign_get_size(l_sign); + size_t l_sign_size = dap_sign_get_size(l_sign); l_datum_token = DAP_REALLOC(l_datum_token, sizeof(l_datum_token->header) + l_signs_offset + l_sign_size); memcpy(l_datum_token->signs + l_signs_offset, l_sign, l_sign_size); l_signs_offset += l_sign_size; @@ -2305,7 +2323,7 @@ int com_token_decl(int argc, char ** argv, char ** a_str_reply) // Calc datum's hash dap_chain_hash_fast_t l_key_hash; - dap_hash_fast(l_datum, l_datum_size, (uint8_t*) &l_key_hash); + dap_hash_fast(l_datum, l_datum_size, &l_key_hash); char * l_key_str = dap_chain_hash_fast_to_str_new(&l_key_hash); // Add datum to mempool with datum_token hash as a key @@ -2355,7 +2373,7 @@ int com_token_emit(int argc, char ** argv, char ** str_reply) const char * l_certs_str = NULL; - dap_chain_cert_t ** l_certs = NULL; + dap_cert_t ** l_certs = NULL; size_t l_certs_size = 0; const char * l_chain_emission_str = NULL; @@ -2402,7 +2420,7 @@ int com_token_emit(int argc, char ** argv, char ** str_reply) } // Load certs - dap_chain_cert_parse_str_list(l_certs_str, &l_certs, &l_certs_size); + dap_cert_parse_str_list(l_certs_str, &l_certs, &l_certs_size); if(!l_certs_size) { dap_chain_node_cli_set_reply_text(str_reply, @@ -2498,9 +2516,9 @@ int com_token_emit(int argc, char ** argv, char ** str_reply) // Then add signs size_t l_offset = 0; for(size_t i = 0; i < l_certs_size; i++) { - dap_chain_sign_t * l_sign = dap_chain_cert_sign(l_certs[i], &l_token_emission->hdr, + dap_sign_t * l_sign = dap_cert_sign(l_certs[i], &l_token_emission->hdr, sizeof(l_token_emission->hdr), 0); - size_t l_sign_size = dap_chain_sign_get_size(l_sign); + size_t l_sign_size = dap_sign_get_size(l_sign); l_token_emission_size += l_sign_size; l_token_emission = DAP_REALLOC(l_token_emission, l_token_emission_size); memcpy(l_token_emission->data.type_auth.signs + l_offset, l_sign, l_sign_size); @@ -2516,7 +2534,7 @@ int com_token_emit(int argc, char ** argv, char ** str_reply) // Calc token's hash dap_chain_hash_fast_t l_token_emission_hash; - dap_hash_fast(l_token_emission, l_token_emission_size, (uint8_t*) &l_token_emission_hash); + dap_hash_fast(l_token_emission, l_token_emission_size, &l_token_emission_hash); char * l_key_str = dap_chain_hash_fast_to_str_new(&l_token_emission_hash); // Delete token emission @@ -2577,12 +2595,12 @@ int com_token_emit(int argc, char ** argv, char ** str_reply) //dap_hash_fast(l_tx, l_tx_size, &l_key_hash); //dap_hash_fast(l_datum_tx, l_datum_tx_size, &l_key_hash); // calc datum hash dap_chain_hash_fast_t l_datum_tx_hash; - dap_hash_fast(l_datum_tx, l_datum_tx_size, (uint8_t*) &l_datum_tx_hash); + dap_hash_fast(l_datum_tx, l_datum_tx_size, &l_datum_tx_hash); l_key_str = dap_chain_hash_fast_to_str_new(&l_datum_tx_hash); DAP_DELETE(l_tx); // Add to mempool tx token - if(dap_chain_global_db_gr_set(l_key_str, (uint8_t *) l_datum_tx, l_datum_tx_size + if(dap_chain_global_db_gr_set(l_key_str, l_datum_tx, l_datum_tx_size , l_gdb_group_mempool_base_tx)) { dap_chain_node_cli_set_reply_text(str_reply, "%s\ndatum tx %s is placed in datum pool ", str_reply_tmp, l_key_str); @@ -2608,19 +2626,12 @@ int com_tx_cond_create(int argc, char ** argv, char **str_reply) { (void) argc; // test + /* const char * l_token_ticker = NULL; const char *c_wallets_path = dap_chain_wallet_get_path(g_config); const char *c_wallet_name_from = "w_tesla"; // where to take coins for service const char *c_wallet_name_cond = "w_picnic"; // who will be use service, usually the same address (addr_from) -// const char *c_net_name = "kelvin-testnet"; uint64_t l_value = 50; - //debug - { -// dap_chain_wallet_t * l_wallet_tesla = dap_chain_wallet_open("w_picnic", c_wallets_path); -// const dap_chain_addr_t *l_addr_tesla = dap_chain_wallet_get_addr(l_wallet_tesla); - // char *addr = dap_chain_addr_to_str(l_addr_tesla); -// addr = 0; - } dap_chain_wallet_t *l_wallet_from = dap_chain_wallet_open(c_wallet_name_from, c_wallets_path); dap_enc_key_t *l_key = dap_chain_wallet_get_key(l_wallet_from, 0); @@ -2645,6 +2656,8 @@ int com_tx_cond_create(int argc, char ** argv, char **str_reply) dap_chain_node_cli_set_reply_text(str_reply, "cond create=%s\n", (res == 0) ? "Ok" : (res == -2) ? "False, not enough funds for service fee" : "False"); return res; + */ + return -1; } /** @@ -2737,7 +2750,7 @@ int com_tx_create(int argc, char ** argv, char **str_reply) dap_chain_node_cli_set_reply_text(str_reply, "wallet %s does not exist", l_from_wallet_name); return -1; } - const dap_chain_addr_t *addr_from = (const dap_chain_addr_t *) dap_chain_wallet_get_addr(l_wallet); + const dap_chain_addr_t *addr_from = (const dap_chain_addr_t *) dap_chain_wallet_get_addr(l_wallet, l_net->pub.id); dap_chain_addr_t *addr_to = dap_chain_addr_from_str(addr_base58_to); dap_chain_addr_t *addr_fee = dap_chain_addr_from_str(addr_base58_fee); @@ -2867,7 +2880,7 @@ int com_tx_history(int argc, char ** argv, char **str_reply) const char *c_wallets_path = dap_chain_wallet_get_path(g_config); dap_chain_wallet_t * l_wallet = dap_chain_wallet_open(l_wallet_name, c_wallets_path); if(l_wallet) { - dap_chain_addr_t *l_addr_tmp = (dap_chain_addr_t *) dap_chain_wallet_get_addr(l_wallet); + dap_chain_addr_t *l_addr_tmp = (dap_chain_addr_t *) dap_chain_wallet_get_addr(l_wallet, l_net->pub.id); l_addr = DAP_NEW_SIZE(dap_chain_addr_t, sizeof(dap_chain_addr_t)); memcpy(l_addr, l_addr_tmp, sizeof(dap_chain_addr_t)); dap_chain_wallet_close(l_wallet); @@ -2949,6 +2962,7 @@ int com_print_log(int argc, char ** argv, char **str_reply) */ int com_vpn_client(int a_argc, char ** a_argv, char **a_str_reply) { +#ifndef _WIN32 enum { CMD_NONE, CMD_START, CMD_STOP, CMD_STATUS }; @@ -3037,5 +3051,6 @@ int com_vpn_client(int a_argc, char ** a_argv, char **a_str_reply) } break; } +#endif return 0; } diff --git a/dap_chain_node_client.c b/dap_chain_node_client.c index ee356a4b046cdb440ddf3e73aa464f9685243348..0ece420862ece432ad250fe4330e35a779efa46e 100644 --- a/dap_chain_node_client.c +++ b/dap_chain_node_client.c @@ -46,8 +46,10 @@ #include "dap_client.h" #include "dap_config.h" #include "dap_events.h" +#include "dap_hash.h" #include "dap_http_client_simple.h" #include "dap_client_pvt.h" +#include "dap_chain_global_db_remote.h" #include "dap_stream_ch_pkt.h" #include "dap_stream_ch_chain.h" #include "dap_stream_ch_chain_pkt.h" @@ -292,7 +294,11 @@ static void s_ch_chain_callback_notify_packet_in(dap_stream_ch_chain_t* a_ch_cha l_request = (dap_stream_ch_chain_sync_request_t*) a_pkt->data; if(l_request) { - if(l_request->id_start < (uint64_t) dap_db_log_get_last_id()) { + uint64_t l_id_last_here = 1; + // for sync chain not used time + if(a_pkt_type != DAP_STREAM_CH_CHAIN_PKT_TYPE_SYNCED_CHAINS) + l_id_last_here =(uint64_t) dap_db_log_get_last_id(); + if(l_request->id_start < l_id_last_here) { log_it(L_INFO, "Remote is synced but we have updates for it"); // Get log diff a_ch_chain->request_last_ts = dap_db_log_get_last_id(); @@ -305,12 +311,44 @@ static void s_ch_chain_callback_notify_packet_in(dap_stream_ch_chain_t* a_ch_cha a_ch_chain->request_net_id.uint64 = a_pkt->hdr.net_id.uint64; a_ch_chain->request_cell_id.uint64 = a_pkt->hdr.cell_id.uint64; a_ch_chain->request_chain_id.uint64 = a_pkt->hdr.chain_id.uint64; - a_ch_chain->state = CHAIN_STATE_SYNC_GLOBAL_DB; - + a_ch_chain->state = dap_stream_ch_chain_pkt_type_to_dap_stream_ch_chain_state(a_pkt_type);//CHAIN_STATE_SYNC_CHAINS;//GLOBAL_DB; + + // type of first packet + uint8_t l_type = + (a_pkt_type != DAP_STREAM_CH_CHAIN_PKT_TYPE_SYNCED_CHAINS) ? + DAP_STREAM_CH_CHAIN_PKT_TYPE_FIRST_GLOBAL_DB : + DAP_STREAM_CH_CHAIN_PKT_TYPE_FIRST_CHAIN; + if(l_type == DAP_STREAM_CH_CHAIN_PKT_TYPE_FIRST_CHAIN) + { + dap_chain_t * l_chain = dap_chain_find_by_id(a_pkt->hdr.net_id, a_pkt->hdr.chain_id); + dap_chain_atom_iter_t* l_iter = l_chain ? l_chain->callback_atom_iter_create(l_chain) : NULL; + //a_ch_chain->request_atom_iter = l_iter; + + dap_chain_atom_ptr_t * l_lasts = NULL; + size_t l_lasts_size = 0; + l_lasts = l_chain->callback_atom_iter_get_lasts(l_iter, &l_lasts_size); + for(size_t i = 0; i < l_lasts_size; i++) { + dap_chain_atom_item_t * l_item = NULL; + dap_chain_hash_fast_t l_atom_hash; + dap_hash_fast(l_lasts[i], l_chain->callback_atom_get_size(l_lasts[i]), + &l_atom_hash); + HASH_FIND(hh, a_ch_chain->request_atoms_lasts, &l_atom_hash, sizeof(l_atom_hash), l_item); + if(l_item == NULL) { // Not found, add new lasts + l_item = DAP_NEW_Z(dap_chain_atom_item_t); + l_item->atom = l_lasts[i]; + memcpy(&l_item->atom_hash, &l_atom_hash, sizeof(l_atom_hash)); + HASH_ADD(hh, a_ch_chain->request_atoms_lasts, atom_hash, sizeof(l_atom_hash), l_item); + } + else + DAP_DELETE(l_lasts[i]); + } + DAP_DELETE(l_lasts); + DAP_DELETE(l_iter); + } dap_chain_node_addr_t l_node_addr = { 0 }; dap_chain_net_t *l_net = dap_chain_net_by_id(a_ch_chain->request_net_id); - l_node_addr.uint64 = dap_db_get_cur_node_addr(l_net->pub.name); - dap_stream_ch_chain_pkt_write(a_ch_chain->ch, DAP_STREAM_CH_CHAIN_PKT_TYPE_FIRST_GLOBAL_DB, + l_node_addr.uint64 = l_net ? dap_db_get_cur_node_addr(l_net->pub.name) : 0; + dap_stream_ch_chain_pkt_write(a_ch_chain->ch, l_type, a_ch_chain->request_net_id, a_ch_chain->request_chain_id, a_ch_chain->request_cell_id, &l_node_addr, sizeof(dap_chain_node_addr_t));