diff --git a/CMakeLists.txt b/CMakeLists.txt index eb274c7fb471e5c6bdb7bbda2eb021d4d2aac96d..489778264cdd06011a861d071d0795a99d453722 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,11 +2,19 @@ project(cellframe-sdk C) cmake_minimum_required(VERSION 3.0) set(CMAKE_C_STANDARD 11) -set(CELLFRAME_SDK_NATIVE_VERSION "3.0-7") +set(CELLFRAME_SDK_NATIVE_VERSION "3.1-0") add_definitions ("-DCELLFRAME_SDK_VERSION=\"${CELLFRAME_SDK_NATIVE_VERSION}\"") set(DAPSDK_MODULES "") message("Cellframe modules: ${CELLFRAME_MODULES}") +if (CELLFRAME_MODULES MATCHES "modules-dynamic") + add_definitions("-DDAP_MODULES_DYNAMIC") +endif() + +if (CELLFRAME_MODULES MATCHES "srv-stake") + add_definitions("-DDAP_SRV_STAKE_USED") +endif() + if (CELLFRAME_MODULES MATCHES "core") SET(DAPSDK_MODULES "${DAPSDK_MODULES} core crypto") endif() @@ -105,6 +113,30 @@ if (CELLFRAME_MODULES MATCHES "cs-dag-pos") set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_cs_dag_pos) endif() +# Blocks based consensus(es) +if (CELLFRAME_MODULES MATCHES "cs-block-" ) + set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_cs_dag) +endif() + +# PoA consensus for blocks +if (CELLFRAME_MODULES MATCHES "cs-block-poa") + message("[+] Module 'cs-block-poa'") + set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_cs_block_poa) +endif() + +# PoS consensus for blocks +if (CELLFRAME_MODULES MATCHES "cs-block-pos") + message("[+] Module 'cs-block-pos'") + set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_cs_block_pos) +endif() + +# PoW consensus for blocks +if (CELLFRAME_MODULES MATCHES "cs-block-pow") + message("[+] Module 'cs-block-pow'") + set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_cs_block_pos) +endif() + + # No-consensus if (CELLFRAME_MODULES MATCHES "cs-none") message("[+] Module 'cs-none'") @@ -114,45 +146,43 @@ endif() # Enable service Application if (CELLFRAME_MODULES MATCHES "srv-app") message("[+] Module 'srv-app'") - set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_net_srv_app ) + set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_net_srv_app) endif() # Enable service Application DB if (CELLFRAME_MODULES MATCHES "srv-app-db") message("[+] Module 'srv-app-db'") - set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_net_srv_app_db ) + set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_net_srv_app_db) endif() # Enable service datum process if (CELLFRAME_MODULES MATCHES "srv-datum") message("[+] Module 'srv-datum'") - set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_net_srv_datum ) + set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_net_srv_datum) endif() # Enable service VPN if (CELLFRAME_MODULES MATCHES "srv-vpn") message("[+] Module 'srv-vpn'") - set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_net_srv_vpn ) + set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_net_srv_vpn) endif() # Enable service eXchange if (CELLFRAME_MODULES MATCHES "srv-xchange") message("[+] Module 'srv-xchange'") - set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_net_srv_xchange ) + set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_net_srv_xchange) endif() # Enable service of delegated stake if (CELLFRAME_MODULES MATCHES "srv-stake") message("[+] Module 'srv-stake'") - set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_net_srv_stake ) - add_definitions("-DDAP_SRV_STAKE_USED") + set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_chain_net_srv_stake) endif() # Enable service for dynamic modules if (CELLFRAME_MODULES MATCHES "modules-dynamic") message("[+] Module 'dap_modules_dynamic_cdb'") - set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_modules_dynamic_cdb ) - add_definitions("-DDAP_MODULES_DYNAMIC") + set(CELLFRAME_LIBS ${CELLFRAME_LIBS} dap_modules_dynamic_cdb) endif() if (WIN32) diff --git a/dap-sdk/core/include/dap_module.h b/dap-sdk/core/include/dap_module.h index b3193c43dcfe9365439823c487542e61f4e56e97..bae7e6df32518e9fea7232bdf0f05fce6568f598 100755 --- a/dap-sdk/core/include/dap_module.h +++ b/dap-sdk/core/include/dap_module.h @@ -35,7 +35,7 @@ typedef struct dap_module { #define DAP_MODULE_ARGS_MAX 10 typedef struct dap_module_args { const char * name; - const char * args[DAP_MODULE_ARGS_MAX]; // ARGS could me not more than DAP_MODULE_ARGS_MAX define + const char * args[DAP_MODULE_ARGS_MAX]; // ARGS could be not more than DAP_MODULE_ARGS_MAX define } dap_module_args_t; int dap_module_add(const char * a_name, unsigned int a_version, const char * a_dependensies, diff --git a/dap-sdk/crypto/src/dap_enc_dilithium.c b/dap-sdk/crypto/src/dap_enc_dilithium.c index 4825ca399b987bba1d003d58816632a1d28a16dd..bf6ddd748c24db928c2f96e2a2eb4e8e059c5dd7 100755 --- a/dap-sdk/crypto/src/dap_enc_dilithium.c +++ b/dap-sdk/crypto/src/dap_enc_dilithium.c @@ -172,7 +172,7 @@ dilithium_signature_t* dap_enc_dilithium_read_signature(uint8_t *a_buf, size_t a } l_shift_mem = sizeof(uint32_t); } - memcpy(&kind, a_buf + sizeof(uint32_t), sizeof(uint32_t)); + memcpy(&kind, a_buf + l_shift_mem, sizeof(uint32_t)); l_shift_mem += sizeof(uint32_t); dilithium_param_t p; if(!dilithium_params_init(&p, kind)) diff --git a/dap-sdk/crypto/src/dap_hash.c b/dap-sdk/crypto/src/dap_hash.c index a826d81f6f468bd7d6301d41314484a47283b942..7a625746845f623133c80e41c4db00ea531f1cfc 100755 --- a/dap-sdk/crypto/src/dap_hash.c +++ b/dap-sdk/crypto/src/dap_hash.c @@ -54,7 +54,7 @@ int dap_chain_hash_fast_from_str( const char * a_hash_str, dap_chain_hash_fast_t *(a_hash->raw + l_offset / 2 - 1) = l_byte; } return 0; - }else // Wromg string len + }else // Wrong string len return -1; } diff --git a/dap-sdk/crypto/src/dap_sign.c b/dap-sdk/crypto/src/dap_sign.c index 09a66dfb1312bc82119a9417d1fdf4efe558768b..dd1625e88f0215082e14f7330ec070a28b8e8b66 100755 --- a/dap-sdk/crypto/src/dap_sign.c +++ b/dap-sdk/crypto/src/dap_sign.c @@ -374,8 +374,6 @@ int dap_sign_verify(dap_sign_t * a_chain_sign, const void * a_data, const size_t if ( ! l_sign_data ){ log_it(L_WARNING,"Incorrect signature, can't deserialize signature's data"); - l_sign_data_size = a_chain_sign->header.sign_size; - uint8_t * l_sign_data = dap_enc_key_deserealize_sign(l_key->type, l_sign_data_ser, &l_sign_data_size); dap_enc_key_delete(l_key); return -5; } diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index b7d35fe8e87786ac29237543471f39bca4f32373..c1e23565f1487b0f4897b1010b3e762a86796143 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -38,20 +38,10 @@ if (CELLFRAME_MODULES MATCHES "srv") endif() # Consensus type dag -if (CELLFRAME_MODULES MATCHES "cs-dag") +if (CELLFRAME_MODULES MATCHES "cs-dag-") add_subdirectory(type/dag) endif() -# Consensus type dag -if (CELLFRAME_MODULES MATCHES "cs-blocks") - add_subdirectory(type/blocks) -endif() - -# No consensus -if (CELLFRAME_MODULES MATCHES "cs-none") - add_subdirectory(consensus/none) -endif() - # DAG PoA if (CELLFRAME_MODULES MATCHES "cs-dag-poa") add_subdirectory(consensus/dag-poa) @@ -62,6 +52,31 @@ if (CELLFRAME_MODULES MATCHES "cs-dag-pos") add_subdirectory(consensus/dag-pos) endif() +# Consensus type blocks +if (CELLFRAME_MODULES MATCHES "cs-block-") + add_subdirectory(type/blocks) +endif() + +# Block PoA +if (CELLFRAME_MODULES MATCHES "cs-block-poa") + add_subdirectory(consensus/block-poa) +endif() + +# Block PoS +if (CELLFRAME_MODULES MATCHES "cs-block-pos") + add_subdirectory(consensus/block-pos) +endif() + +# Block PoW +if (CELLFRAME_MODULES MATCHES "cs-block-pow") + add_subdirectory(consensus/block-pow) +endif() + +# No consensus +if (CELLFRAME_MODULES MATCHES "cs-none") + add_subdirectory(consensus/none) +endif() + # Service App if (CELLFRAME_MODULES MATCHES "srv-app") add_subdirectory(service/app) diff --git a/modules/chain/dap_chain_ledger.c b/modules/chain/dap_chain_ledger.c index 7602f91439d09103f39074162f24a2b91af7fedf..69262d327348d8ede447d815d48bec5aa210afc0 100644 --- a/modules/chain/dap_chain_ledger.c +++ b/modules/chain/dap_chain_ledger.c @@ -929,7 +929,7 @@ static void s_treshold_emissions_proc(dap_ledger_t * a_ledger) pthread_rwlock_rdlock(&PVT(a_ledger)->treshold_emissions_rwlock); HASH_ITER(hh, PVT(a_ledger)->treshold_emissions, l_emission_item, l_emission_tmp) { pthread_rwlock_unlock(&PVT(a_ledger)->treshold_emissions_rwlock); - int l_res = dap_chain_ledger_token_emission_add(a_ledger, l_emission_item->datum_token_emission, + int l_res = dap_chain_ledger_token_emission_add(a_ledger, (byte_t *)l_emission_item->datum_token_emission, l_emission_item->datum_token_emission_size); if (!l_res) { pthread_rwlock_wrlock(&PVT(a_ledger)->treshold_emissions_rwlock); @@ -1014,11 +1014,14 @@ void dap_chain_ledger_load_cache(dap_ledger_t *a_ledger) continue; dap_chain_ledger_token_emission_item_t *l_emission_item = DAP_NEW_Z(dap_chain_ledger_token_emission_item_t); dap_chain_hash_fast_from_str(l_objs[i].key, &l_emission_item->datum_token_emission_hash); - l_emission_item->datum_token_emission = DAP_NEW_Z_SIZE(dap_chain_datum_token_emission_t, l_objs[i].value_len); - memcpy(l_emission_item->datum_token_emission, l_objs[i].value, l_objs[i].value_len); - const char * c_token_ticker = l_emission_item->datum_token_emission->hdr.ticker; + size_t l_emission_size = l_objs[i].value_len; + const char *c_token_ticker = ((dap_chain_datum_token_emission_t *)l_objs[i].value)->hdr.ticker; dap_chain_ledger_token_item_t *l_token_item = NULL; HASH_FIND_STR(l_ledger_pvt->tokens, c_token_ticker, l_token_item); + l_emission_item->datum_token_emission = l_token_item + ? dap_chain_datum_emission_read(l_objs[i].value, &l_emission_size) + : DAP_DUP_SIZE(l_objs[i].value, l_objs[i].value_len); + l_emission_item->datum_token_emission_size = l_emission_size; if (l_token_item) { HASH_ADD(hh, l_token_item->token_emissions, datum_token_emission_hash, sizeof(dap_chain_hash_fast_t), l_emission_item); @@ -1123,13 +1126,12 @@ dap_ledger_t* dap_chain_ledger_create(uint16_t a_check_flags, char *a_net_name) return l_ledger; } -int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, const dap_chain_datum_token_emission_t *a_token_emission - , size_t a_token_emission_size) +int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size) { int ret = 0; dap_ledger_private_t *l_ledger_priv = PVT(a_ledger); - const char * c_token_ticker = a_token_emission->hdr.ticker; + const char * c_token_ticker = ((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.ticker; dap_chain_ledger_token_item_t * l_token_item = NULL; pthread_rwlock_rdlock(&l_ledger_priv->tokens_rwlock); HASH_FIND_STR(l_ledger_priv->tokens, c_token_ticker, l_token_item); @@ -1151,12 +1153,12 @@ int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, const dap_ : &l_ledger_priv->treshold_emissions_rwlock); if(l_token_emission_item ) { if(s_debug_more) - if ( a_token_emission->hdr.type_value_256 ) + if ( l_token_emission_item->datum_token_emission->hdr.type_value_256 ) log_it(L_ERROR, "Can't add token emission datum of %s %s ( %s ): already present in cache", - dap_chain_u256tostr(a_token_emission->hdr.value_256), c_token_ticker, l_hash_str); + dap_chain_u256tostr(l_token_emission_item->datum_token_emission->hdr.value_256), c_token_ticker, l_hash_str); else log_it(L_ERROR, "Can't add token emission datum of %"DAP_UINT64_FORMAT_U" %s ( %s ): already present in cache", - a_token_emission->hdr.value, c_token_ticker, l_hash_str); + l_token_emission_item->datum_token_emission->hdr.value, c_token_ticker, l_hash_str); ret = -1; }else if ( (! l_token_item) && ( l_threshold_emissions_count >= s_treshold_emissions_max)) { if(s_debug_more) @@ -1164,20 +1166,22 @@ int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, const dap_ s_treshold_emissions_max); ret = -2; }else{ // Chech emission correctness - switch (a_token_emission->hdr.type){ + size_t l_emission_size = a_token_emission_size; + dap_chain_datum_token_emission_t *l_emission = dap_chain_datum_emission_read(a_token_emission, &l_emission_size); + switch (l_emission->hdr.type){ case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH:{ dap_chain_ledger_token_item_t *l_token_item=NULL; pthread_rwlock_rdlock(&PVT(a_ledger)->tokens_rwlock); - HASH_FIND_STR(PVT(a_ledger)->tokens, a_token_emission->hdr.ticker, l_token_item); + HASH_FIND_STR(PVT(a_ledger)->tokens, l_emission->hdr.ticker, l_token_item); pthread_rwlock_unlock(&PVT(a_ledger)->tokens_rwlock); if (l_token_item){ assert(l_token_item->datum_token); if( PVT(a_ledger)->net->pub.token_emission_signs_verify ){ - dap_sign_t * l_sign =(dap_sign_t*) a_token_emission->data.type_auth.signs; - size_t l_offset= (byte_t*)a_token_emission - (byte_t*) l_sign; + dap_sign_t * l_sign =(dap_sign_t*) l_emission->data.type_auth.signs; + size_t l_offset= (byte_t*)l_emission - (byte_t*) l_sign; uint16_t l_aproves = 0, l_aproves_valid = l_token_item->auth_signs_valid; - for (uint16_t i=0; i <a_token_emission->data.type_auth.signs_count && l_offset < a_token_emission_size; i++){ + for (uint16_t i=0; i <l_emission->data.type_auth.signs_count && l_offset < l_emission_size; i++){ size_t l_sign_size = dap_sign_get_size(l_sign); l_sign = (dap_sign_t*) ((byte_t*) l_sign + l_sign_size); if (UINT16_MAX-l_offset> l_sign_size ){ @@ -1187,10 +1191,10 @@ int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, const dap_ for(uint16_t k=0; k< l_token_item->auth_signs_total; k++ ){ if ( dap_hash_fast_compare(&l_sign_pkey_hash, &l_token_item->auth_signs_pkey_hash[k])) { // Verify if its token emission header signed - if (!dap_sign_verify_size(l_sign, a_token_emission_size)) { + if (!dap_sign_verify_size(l_sign, l_emission_size)) { break; } - if( dap_sign_verify(l_sign,&a_token_emission->hdr, sizeof (a_token_emission) ) ){ + if (dap_sign_verify(l_sign, &l_emission->hdr, sizeof(l_emission))) { l_aproves++; break; } @@ -1203,23 +1207,24 @@ int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, const dap_ if (l_aproves < l_aproves_valid ){ if(s_debug_more) - if ( a_token_emission->hdr.type_value_256 ) // 256 + if ( l_emission->hdr.type_value_256 ) // 256 log_it(L_WARNING, "Emission of %s datoshi of %s:%s is wrong: only %u valid aproves when %u need", - dap_chain_u256tostr(a_token_emission->hdr.value_256), a_ledger->net_name, a_token_emission->hdr.ticker, l_aproves, l_aproves_valid ); + dap_chain_u256tostr(l_emission->hdr.value_256), a_ledger->net_name, l_emission->hdr.ticker, l_aproves, l_aproves_valid ); else log_it(L_WARNING, "Emission of %"DAP_UINT64_FORMAT_U" datoshi of %s:%s is wrong: only %u valid aproves when %u need", - a_token_emission->hdr.value, a_ledger->net_name, a_token_emission->hdr.ticker, l_aproves, l_aproves_valid ); + l_emission->hdr.value, a_ledger->net_name, l_emission->hdr.ticker, l_aproves, l_aproves_valid ); ret = -1; } } }else{ if(s_debug_more) - log_it(L_WARNING,"Can't find token declaration %s:%s thats pointed in token emission datum", a_ledger->net_name, a_token_emission->hdr.ticker); + log_it(L_WARNING,"Can't find token declaration %s:%s thats pointed in token emission datum", a_ledger->net_name, l_emission->hdr.ticker); ret = DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS; } }break; default:{} } + DAP_DELETE(l_emission); } DAP_DELETE(l_hash_str); @@ -1232,22 +1237,19 @@ int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, const dap_ * @param a_token_emision_size * @return */ -int dap_chain_ledger_token_emission_add(dap_ledger_t *a_ledger, - const dap_chain_datum_token_emission_t *a_token_emission, size_t a_token_emission_size) +int dap_chain_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size) { int ret = 0; dap_ledger_private_t *l_ledger_priv = PVT(a_ledger); - const char * c_token_ticker = a_token_emission->hdr.ticker; - + const char * c_token_ticker = ((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.ticker; dap_chain_ledger_token_item_t * l_token_item = NULL; pthread_rwlock_rdlock(&l_ledger_priv->tokens_rwlock); HASH_FIND_STR(l_ledger_priv->tokens, c_token_ticker, l_token_item); pthread_rwlock_unlock(&l_ledger_priv->tokens_rwlock); dap_chain_ledger_token_emission_item_t * l_token_emission_item = NULL; // check if such emission is already present in table - dap_chain_hash_fast_t l_token_emission_hash={0}; - dap_chain_hash_fast_t * l_token_emission_hash_ptr = &l_token_emission_hash; + dap_chain_hash_fast_t l_token_emission_hash = {}; dap_hash_fast(a_token_emission, a_token_emission_size, &l_token_emission_hash); char * l_hash_str = dap_chain_hash_fast_to_str_new(&l_token_emission_hash); pthread_rwlock_rdlock( l_token_item ? &l_token_item->token_emissions_rwlock @@ -1260,11 +1262,13 @@ int dap_chain_ledger_token_emission_add(dap_ledger_t *a_ledger, if(l_token_emission_item == NULL ) { if ( l_token_item || l_threshold_emissions_count < s_treshold_emissions_max ) { l_token_emission_item = DAP_NEW_Z(dap_chain_ledger_token_emission_item_t); - l_token_emission_item->datum_token_emission = - DAP_NEW_Z_SIZE(dap_chain_datum_token_emission_t, a_token_emission_size); + size_t l_emission_size = a_token_emission_size; + l_token_emission_item->datum_token_emission = l_token_item + ? dap_chain_datum_emission_read(a_token_emission, &l_emission_size) + : DAP_DUP_SIZE(a_token_emission, a_token_emission_size); memcpy(l_token_emission_item->datum_token_emission, a_token_emission, a_token_emission_size); memcpy(&l_token_emission_item->datum_token_emission_hash, - l_token_emission_hash_ptr, sizeof(l_token_emission_hash)); + &l_token_emission_hash, sizeof(l_token_emission_hash)); l_token_emission_item->datum_token_emission_size = a_token_emission_size; pthread_rwlock_wrlock( l_token_item ? &l_token_item->token_emissions_rwlock : &l_ledger_priv->treshold_emissions_rwlock); @@ -1278,29 +1282,28 @@ int dap_chain_ledger_token_emission_add(dap_ledger_t *a_ledger, pthread_rwlock_unlock( l_token_item ? &l_token_item->token_emissions_rwlock : &l_ledger_priv->treshold_emissions_rwlock); // Add it to cache - dap_chain_datum_token_emission_t *l_emission_cache = DAP_NEW_Z_SIZE(dap_chain_datum_token_emission_t, a_token_emission_size); - memcpy(l_emission_cache, a_token_emission, a_token_emission_size); + dap_chain_datum_token_emission_t *l_emission_cache = DAP_DUP_SIZE(a_token_emission, a_token_emission_size); char *l_gdb_group = dap_chain_ledger_get_gdb_group(a_ledger, DAP_CHAIN_LEDGER_EMISSIONS_STR); if (!dap_chain_global_db_gr_set(dap_strdup(l_hash_str), l_emission_cache, a_token_emission_size, l_gdb_group)) { log_it(L_WARNING, "Ledger cache mismatch"); DAP_DELETE(l_emission_cache); } DAP_DELETE(l_gdb_group); - char * l_token_emission_address_str = dap_chain_addr_to_str( &(a_token_emission->hdr.address) ); + char * l_token_emission_address_str = dap_chain_addr_to_str(&(l_token_emission_item->datum_token_emission->hdr.address) ); if(s_debug_more) - if ( a_token_emission->hdr.type_value_256 ) // 256 + if ( l_token_emission_item->datum_token_emission->hdr.type_value_256 ) // 256 log_it(L_NOTICE, "Added token emission datum to %s: type=%s value=%.1Lf token=%s to_addr=%s ", l_token_item?"emissions cache":"emissions treshold", - c_dap_chain_datum_token_emission_type_str[ a_token_emission->hdr.type ] , + c_dap_chain_datum_token_emission_type_str[ l_token_emission_item->datum_token_emission->hdr.type ] , dap_chain_datoshi_to_coins( - dap_chain_uint128_from_uint256(a_token_emission->hdr.value_256) + dap_chain_uint128_from_uint256(l_token_emission_item->datum_token_emission->hdr.value_256) ), c_token_ticker, l_token_emission_address_str); else log_it(L_NOTICE, "Added token emission datum to %s: type=%s value=%.1Lf token=%s to_addr=%s ", l_token_item?"emissions cache":"emissions treshold", - c_dap_chain_datum_token_emission_type_str[ a_token_emission->hdr.type ] , - dap_chain_datoshi_to_coins(a_token_emission->hdr.value), c_token_ticker, + c_dap_chain_datum_token_emission_type_str[ l_token_emission_item->datum_token_emission->hdr.type ] , + dap_chain_datoshi_to_coins(l_token_emission_item->datum_token_emission->hdr.value), c_token_ticker, l_token_emission_address_str); DAP_DELETE(l_token_emission_address_str); }else{ @@ -1312,12 +1315,12 @@ int dap_chain_ledger_token_emission_add(dap_ledger_t *a_ledger, } else { if (l_token_item) { if(s_debug_more) - if ( a_token_emission->hdr.type_value_256 ) // 256 + if ( ((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.type_value_256 ) // 256 log_it(L_ERROR, "Duplicate token emission datum of %s %s ( %s )", - dap_chain_u256tostr(a_token_emission->hdr.value_256), c_token_ticker, l_hash_str); + dap_chain_u256tostr(((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.value_256), c_token_ticker, l_hash_str); else log_it(L_ERROR, "Duplicate token emission datum of %"DAP_UINT64_FORMAT_U" %s ( %s )", - a_token_emission->hdr.value, c_token_ticker, l_hash_str); + ((dap_chain_datum_token_emission_t *)a_token_emission)->hdr.value, c_token_ticker, l_hash_str); } ret = -1; } @@ -1325,7 +1328,7 @@ int dap_chain_ledger_token_emission_add(dap_ledger_t *a_ledger, return ret; } -int dap_chain_ledger_token_emission_load(dap_ledger_t *a_ledger, const dap_chain_datum_token_emission_t *a_token_emission, size_t a_token_emission_size) +int dap_chain_ledger_token_emission_load(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size) { if (PVT(a_ledger)->last_emit.found) { return dap_chain_ledger_token_emission_add(a_ledger, a_token_emission, a_token_emission_size); @@ -1766,26 +1769,6 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t memcpy(&l_tx_in_from, &bound_item->out.tx_prev_out_ext->addr,sizeof (bound_item->out.tx_prev_out_ext->addr)); } - // if ( l_type == TX_ITEM_TYPE_OUT ) { - // bound_item->out.tx_prev_out = l_tx_prev_out; - // memcpy(&l_tx_in_from, &bound_item->out.tx_prev_out->addr,sizeof (bound_item->out.tx_prev_out->addr)); - // } else if ( l_type == TX_ITEM_TYPE_256_OUT ) { // 256 - // l_is_type_256 = true; - // bound_item->out.tx_prev_out_256 = l_tx_prev_out; - // memcpy(&l_tx_in_from, &bound_item->out.tx_prev_out_256->addr,sizeof (bound_item->out.tx_prev_out_256->addr)); - // } else if (l_type == TX_ITEM_TYPE_OUT_EXT ) { - // bound_item->out.tx_prev_out_ext = l_tx_prev_out; - // memcpy(&l_tx_in_from, &bound_item->out.tx_prev_out_ext->addr,sizeof (bound_item->out.tx_prev_out_ext->addr)); - // } else if ( l_type == TX_ITEM_TYPE_256_OUT_EXT ) { // 256 - // l_is_type_256 = true; - // bound_item->out.tx_prev_out_ext_256 = l_tx_prev_out; - // memcpy(&l_tx_in_from, &bound_item->out.tx_prev_out_ext_256->addr,sizeof (bound_item->out.tx_prev_out_ext_256->addr)); - // } else { - // l_err_num = -8; - // break; - // } - - // calculate hash of public key in current transaction dap_chain_hash_fast_t l_hash_pkey; { @@ -1850,33 +1833,31 @@ int dap_chain_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig((dap_chain_tx_sig_t *)l_tx_sig); size_t l_pkey_ser_size = 0; const uint8_t *l_pkey_ser = dap_sign_get_pkey(l_sign, &l_pkey_ser_size); - dap_chain_tx_out_cond_t *l_tx_prev_out_cond = (dap_chain_tx_out_cond_t *)l_tx_prev_out; l_is_type_256 = l_type == TX_ITEM_TYPE_256_OUT_COND ? true : false; - - if (l_pkey_ser_size != l_prev_pkey_ser_size || - memcmp(l_prev_pkey_ser, l_pkey_ser, l_prev_pkey_ser_size)) { - // 5b. Call verificator for conditional output - dap_chain_ledger_verificator_t *l_verificator; - int l_tmp = (int)l_tx_prev_out_cond->header.subtype; - - - pthread_rwlock_rdlock(&s_verificators_rwlock); - HASH_FIND_INT(s_verificators, &l_tmp, l_verificator); - pthread_rwlock_unlock(&s_verificators_rwlock); - if (!l_verificator || !l_verificator->callback) { - if(s_debug_more) - log_it(L_ERROR, "No verificator set for conditional output subtype %d", l_tmp); - l_err_num = -13; - break; - } - if (l_verificator->callback(l_tx_prev_out_cond, a_tx) == false) { - l_err_num = -14; - break; - } + bool l_owner = false; + if (l_pkey_ser_size == l_prev_pkey_ser_size && + !memcmp(l_prev_pkey_ser, l_pkey_ser, l_prev_pkey_ser_size)) { + l_owner = true; + } + // 5b. Call verificator for conditional output + dap_chain_ledger_verificator_t *l_verificator; + int l_tmp = (int)l_tx_prev_out_cond->header.subtype; + pthread_rwlock_rdlock(&s_verificators_rwlock); + HASH_FIND_INT(s_verificators, &l_tmp, l_verificator); + pthread_rwlock_unlock(&s_verificators_rwlock); + if (!l_verificator || !l_verificator->callback) { + if(s_debug_more) + log_it(L_ERROR, "No verificator set for conditional output subtype %d", l_tmp); + l_err_num = -13; + break; + } + if (l_verificator->callback(l_tx_prev_out_cond, a_tx, l_owner) == false) { + l_err_num = -14; + break; } bound_item->out.tx_prev_out_cond = l_tx_prev_out_cond; @@ -2378,6 +2359,8 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_list_t *l_list_tmp = l_list_bound_items; char *l_ticker_trl = NULL, *l_ticker_old_trl = NULL; + bool l_stake_updated = false; + // Update balance: deducts while(l_list_tmp) { dap_chain_ledger_tx_bound_t *bound_item = l_list_tmp->data; @@ -2449,6 +2432,19 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_tx_in_cond_t *l_tx_in_cond = bound_item->in.tx_cur_in_cond; /// Mark 'out' item in cache because it used l_tx_prev_out_used_idx = l_tx_in_cond->header.tx_out_prev_idx; + // Update stakes if any + dap_chain_tx_out_cond_t *l_cond = bound_item->out.tx_prev_out_cond; + if (l_cond->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE) { + dap_chain_ledger_verificator_t *l_verificator; + int l_tmp = (int)DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_UPDATE; + pthread_rwlock_rdlock(&s_verificators_rwlock); + HASH_FIND_INT(s_verificators, &l_tmp, l_verificator); + pthread_rwlock_unlock(&s_verificators_rwlock); + if (l_verificator && l_verificator->callback) { + l_verificator->callback(l_cond, a_tx, true); + } + l_stake_updated = true; + } } // add a used output @@ -2509,25 +2505,35 @@ int dap_chain_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, for (dap_list_t *l_tx_out = l_list_tx_out; l_tx_out; l_tx_out = dap_list_next(l_tx_out)) { dap_chain_tx_item_type_t l_type = *(uint8_t *)l_tx_out->data; if (l_type == TX_ITEM_TYPE_OUT_COND || l_type == TX_ITEM_TYPE_256_OUT_COND) { + // Update stakes if any + dap_chain_tx_out_cond_t *l_cond = (dap_chain_tx_out_cond_t *)l_tx_out->data; + if (l_cond->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE && !l_stake_updated) { + dap_chain_ledger_verificator_t *l_verificator; + int l_tmp = (int)DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_UPDATE; + pthread_rwlock_rdlock(&s_verificators_rwlock); + HASH_FIND_INT(s_verificators, &l_tmp, l_verificator); + pthread_rwlock_unlock(&s_verificators_rwlock); + if (l_verificator && l_verificator->callback) { + l_verificator->callback(NULL, a_tx, true); + } + } continue; // balance raise will be with next conditional transaction } dap_chain_tx_out_t *l_out_item = NULL; dap_chain_tx_out_ext_t *l_out_item_ext = NULL; - switch (l_type) { - case TX_ITEM_TYPE_256_OUT: l_out_item = l_tx_out->data; break; - case TX_ITEM_TYPE_OUT: l_out_item = l_tx_out->data; break; - case TX_ITEM_TYPE_256_OUT_EXT: l_out_item_ext = l_tx_out->data; break; - case TX_ITEM_TYPE_OUT_EXT: l_out_item_ext = l_tx_out->data; break; + case TX_ITEM_TYPE_256_OUT: l_out_item = (dap_chain_tx_out_t *)l_tx_out->data; break; + case TX_ITEM_TYPE_OUT: l_out_item = (dap_chain_tx_out_t *)l_tx_out->data; break; + case TX_ITEM_TYPE_256_OUT_EXT: l_out_item_ext = (dap_chain_tx_out_ext_t *)l_tx_out->data; break; + case TX_ITEM_TYPE_OUT_EXT: l_out_item_ext = (dap_chain_tx_out_ext_t *)l_tx_out->data; break; default: log_it(L_DEBUG, "Unknown item type %d", l_type); break; } - //if ( (l_out_item||l_out_item_256) && l_ticker_trl) { - if ( l_out_item && l_ticker_trl) { - dap_chain_addr_t *l_addr = (l_type == TX_ITEM_TYPE_OUT || l_type == TX_ITEM_TYPE_256_OUT) ? + if ((l_out_item || l_out_item_ext) && l_ticker_trl) { + dap_chain_addr_t *l_addr = (l_type == TX_ITEM_TYPE_OUT || l_type == TX_ITEM_TYPE_256_OUT) ? &l_out_item->addr : &l_out_item_ext->addr; diff --git a/modules/chain/include/dap_chain_ledger.h b/modules/chain/include/dap_chain_ledger.h index c19d61508f62e2b4b034bcd0979affb21e2940ed..aa8fc05e8c91ed891fd549652f3caf7af90f4998 100644 --- a/modules/chain/include/dap_chain_ledger.h +++ b/modules/chain/include/dap_chain_ledger.h @@ -42,7 +42,7 @@ typedef struct dap_ledger { void *_internal; } dap_ledger_t; -typedef bool (* dap_chain_ledger_verificator_callback_t)(dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx); +typedef bool (* dap_chain_ledger_verificator_callback_t)(dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx, bool a_owner); // Checks the emission of the token, usualy on zero chain #define DAP_CHAIN_LEDGER_CHECK_TOKEN_EMISSION 0x0001 @@ -127,17 +127,14 @@ dap_list_t *dap_chain_ledger_token_info(dap_ledger_t *a_ledger); /** * Add token emission datum */ -int dap_chain_ledger_token_emission_add(dap_ledger_t *a_ledger, - const dap_chain_datum_token_emission_t *a_token_emission, size_t a_token_emission_size); -int dap_chain_ledger_token_emission_load(dap_ledger_t *a_ledger, - const dap_chain_datum_token_emission_t *a_token_emission, size_t a_token_emission_size); +int dap_chain_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size); +int dap_chain_ledger_token_emission_load(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size); // Check if it addable -int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, - const dap_chain_datum_token_emission_t *a_token_emission, size_t a_token_emission_size); +int dap_chain_ledger_token_emission_add_check(dap_ledger_t *a_ledger, byte_t *a_token_emission, size_t a_token_emission_size); -dap_chain_datum_token_emission_t * dap_chain_ledger_token_emission_find(dap_ledger_t *a_ledger, +dap_chain_datum_token_emission_t *dap_chain_ledger_token_emission_find(dap_ledger_t *a_ledger, const char *a_token_ticker, const dap_chain_hash_fast_t *a_token_emission_hash); const char* dap_chain_ledger_tx_get_token_ticker_by_hash(dap_ledger_t *a_ledger,dap_chain_hash_fast_t *a_tx_hash); diff --git a/modules/common/dap_chain_datum_token.c b/modules/common/dap_chain_datum_token.c index 74245df3bd3e37f32cc5381ea3db2aea43920412..140a22e8cdb33b3751d7e5251c4b34d5e6fc924a 100644 --- a/modules/common/dap_chain_datum_token.c +++ b/modules/common/dap_chain_datum_token.c @@ -201,3 +201,59 @@ err: return NULL; } + +size_t dap_chain_datum_emission_get_size(uint8_t *a_emission_serial) +{ + size_t l_ret = 0; + dap_chain_datum_token_emission_t *l_emission = (dap_chain_datum_token_emission_t *)a_emission_serial; + if (l_emission->hdr.version == 0) { + l_ret = sizeof(struct dap_chain_emission_header_v0); + } else { + l_ret = sizeof(l_emission->hdr); + } + switch (l_emission->hdr.type) { + case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH: { + uint16_t l_sign_count = *(uint16_t *)(a_emission_serial + l_ret); + l_ret += sizeof(l_emission->data.type_auth); + for (uint16_t i = 0; i < l_sign_count; i++) { + dap_sign_t *l_sign = (dap_sign_t *)(a_emission_serial + l_ret); + l_ret += dap_sign_get_size(l_sign); + } + } break; + case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_ALGO: + l_ret += sizeof(l_emission->data.type_algo); + break; + case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_ATOM_OWNER: + l_ret += sizeof(l_emission->data.type_atom_owner); + break; + case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_SMART_CONTRACT: + l_ret += sizeof(l_emission->data.type_presale); + break; + case DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_UNDEFINED: + default: + break; + } + return l_ret; +} + +dap_chain_datum_token_emission_t *dap_chain_datum_emission_read(byte_t *a_emission_serial, size_t *a_emission_size) +{ + assert(a_emission_serial); + assert(a_emission_size); + dap_chain_datum_token_emission_t *l_emission; + if (((dap_chain_datum_token_emission_t *)a_emission_serial)->hdr.version == 0) { + size_t l_emission_size = *a_emission_size; + size_t l_old_hdr_size = sizeof(struct dap_chain_emission_header_v0); + size_t l_add_size = sizeof(l_emission->hdr) - l_old_hdr_size; + l_emission = DAP_NEW_Z_SIZE(dap_chain_datum_token_emission_t, l_emission_size + l_add_size); + l_emission->hdr.version = 1; + memcpy(l_emission, a_emission_serial, l_old_hdr_size); + memcpy((byte_t *)l_emission + sizeof(l_emission->hdr), + a_emission_serial + l_old_hdr_size, + l_emission_size - l_old_hdr_size); + l_emission_size += l_add_size; + (*a_emission_size) = l_emission_size; + } else + l_emission = DAP_DUP_SIZE(a_emission_serial, (*a_emission_size)); + return l_emission; +} diff --git a/modules/common/dap_chain_datum_tx_items.c b/modules/common/dap_chain_datum_tx_items.c index a7f68ef472bb8fd2280120b6bbcdc867dab1b057..5648eb92cff4a4b2c54ff49e6c0865487e5f812d 100644 --- a/modules/common/dap_chain_datum_tx_items.c +++ b/modules/common/dap_chain_datum_tx_items.c @@ -382,7 +382,8 @@ dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_256_out_cond_create_srv_xchange } dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_stake(dap_chain_net_srv_uid_t a_srv_uid, uint64_t a_value, long double a_fee_value, - dap_chain_addr_t *a_fee_addr, const void *a_params, uint32_t a_params_size) + dap_chain_addr_t *a_fee_addr, dap_chain_addr_t *a_hldr_addr, + const void *a_params, uint32_t a_params_size) { dap_chain_tx_out_cond_t *l_item = DAP_NEW_Z_SIZE(dap_chain_tx_out_cond_t, sizeof(dap_chain_tx_out_cond_t) + a_params_size); l_item->header.item_type = TX_ITEM_TYPE_OUT_COND; @@ -391,6 +392,7 @@ dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_stake(dap_c l_item->subtype.srv_stake.srv_uid = a_srv_uid; l_item->subtype.srv_stake.fee_value = a_fee_value; memcpy(&l_item->subtype.srv_stake.fee_addr, a_fee_addr, sizeof(dap_chain_addr_t)); + memcpy(&l_item->subtype.srv_stake.hldr_addr, a_hldr_addr, sizeof(dap_chain_addr_t)); l_item->params_size = a_params_size; if (a_params_size) { memcpy(l_item->params, a_params, a_params_size); @@ -400,7 +402,8 @@ dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_stake(dap_c // 256 dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_256_out_cond_create_srv_stake(dap_chain_net_srv_uid_t a_srv_uid, uint256_t a_value, long double a_fee_value, - dap_chain_addr_t *a_fee_addr, const void *a_params, uint32_t a_params_size) + dap_chain_addr_t *a_fee_addr, dap_chain_addr_t *a_hldr_addr, + const void *a_params, uint32_t a_params_size) { dap_chain_tx_out_cond_t *l_item = DAP_NEW_Z_SIZE(dap_chain_tx_out_cond_t, sizeof(dap_chain_tx_out_cond_t) + a_params_size); l_item->header.item_type = TX_ITEM_TYPE_256_OUT_COND; @@ -409,6 +412,7 @@ dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_256_out_cond_create_srv_stake(d l_item->subtype.srv_stake.srv_uid = a_srv_uid; l_item->subtype.srv_stake.fee_value = a_fee_value; memcpy(&l_item->subtype.srv_stake.fee_addr, a_fee_addr, sizeof(dap_chain_addr_t)); + memcpy(&l_item->subtype.srv_stake.hldr_addr, a_hldr_addr, sizeof(dap_chain_addr_t)); l_item->params_size = a_params_size; if (a_params_size) { memcpy(l_item->params, a_params, a_params_size); diff --git a/modules/common/include/dap_chain_datum_token.h b/modules/common/include/dap_chain_datum_token.h index 2824bccf2b5bec72c7ce7f57896ed5da8e828ba9..20a75ba505103de2803f510f891aab6254136deb 100644 --- a/modules/common/include/dap_chain_datum_token.h +++ b/modules/common/include/dap_chain_datum_token.h @@ -195,6 +195,15 @@ static inline uint16_t dap_chain_datum_token_flag_from_str(const char* a_str) #define DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_REMOVE 0x0024 #define DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_CLEAR 0x0025 +#define DAP_CHAIN_DATUM_NONCE_SIZE 64 + +struct DAP_ALIGN_PACKED dap_chain_emission_header_v0 { + uint8_t version; + uint8_t type; // Emission Type + char ticker[DAP_CHAIN_TICKER_SIZE_MAX]; + dap_chain_addr_t address; // Emission holder's address + uint64_t value; +}; // Token emission typedef struct dap_chain_datum_token_emission{ @@ -208,6 +217,7 @@ typedef struct dap_chain_datum_token_emission{ uint64_t value; uint256_t value_256; }; + uint8_t nonce[DAP_CHAIN_DATUM_NONCE_SIZE]; } DAP_ALIGN_PACKED hdr; union { struct { @@ -232,35 +242,6 @@ typedef struct dap_chain_datum_token_emission{ } data; } DAP_ALIGN_PACKED dap_chain_datum_token_emission_t; -// 256 Token emission -// typedef struct dap_chain_datum_256_token_emission{ -// struct { -// uint8_t version; -// uint8_t type; // Emission Type -// char ticker[DAP_CHAIN_TICKER_SIZE_MAX]; -// dap_chain_addr_t address; // Emission holder's address -// uint256_t value; -// } DAP_ALIGN_PACKED hdr; -// union { -// struct { -// dap_chain_addr_t addr; -// int flags; -// uint64_t lock_time; -// } DAP_ALIGN_PACKED type_presale; -// struct { -// uint256_t value_start;// Default value. Static if nothing else is defined -// char value_change_algo_codename[32]; -// } DAP_ALIGN_PACKED type_atom_owner; -// struct { -// char codename[32]; -// } DAP_ALIGN_PACKED type_algo; -// struct { -// uint16_t signs_count; -// byte_t signs[]; -// } DAP_ALIGN_PACKED type_auth;// Signs if exists -// } data; -// } DAP_ALIGN_PACKED dap_chain_datum_256_token_emission_t; - // Different emissions type #define DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_UNDEFINED 0x00 #define DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH 0x01 @@ -276,3 +257,5 @@ dap_tsd_t* dap_chain_datum_token_tsd_get(dap_chain_datum_token_t * a_token, siz void dap_chain_datum_token_flags_dump(dap_string_t * a_str_out, uint16_t a_flags); void dap_chain_datum_token_certs_dump(dap_string_t * a_str_out, byte_t * a_data_n_tsd, size_t a_certs_size); dap_sign_t ** dap_chain_datum_token_simple_signs_parse(dap_chain_datum_token_t * a_datum_token, size_t a_datum_token_size, size_t *a_signs_count, size_t * a_signs_valid); +dap_chain_datum_token_emission_t *dap_chain_datum_emission_read(byte_t *a_emission_serial, size_t *a_emission_size); +size_t dap_chain_datum_emission_get_size(uint8_t *a_emission_serial); diff --git a/modules/common/include/dap_chain_datum_tx_items.h b/modules/common/include/dap_chain_datum_tx_items.h index 76d120b247d9f7b723feb3cd1e84aad6b2deaecd..d5425f70b3085f4b5ef00f5f2bf99f8e65ff15ab 100644 --- a/modules/common/include/dap_chain_datum_tx_items.h +++ b/modules/common/include/dap_chain_datum_tx_items.h @@ -151,11 +151,12 @@ dap_chain_tx_out_cond_t* dap_chain_datum_tx_item_256_out_cond_create_srv_xchange * return item, NULL Error */ dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_stake(dap_chain_net_srv_uid_t a_srv_uid, uint64_t a_value, long double a_fee_value, - dap_chain_addr_t *a_fee_addr, const void *a_params, uint32_t a_params_size); + dap_chain_addr_t *a_fee_addr, dap_chain_addr_t *a_hldr_addr, + const void *a_params, uint32_t a_params_size); // 256 dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_256_out_cond_create_srv_stake(dap_chain_net_srv_uid_t a_srv_uid, uint256_t a_value, long double a_fee_value, - dap_chain_addr_t *a_fee_addr, const void *a_params, uint32_t a_params_size); - + dap_chain_addr_t *a_fee_addr, dap_chain_addr_t *a_hldr_addr, + const void *a_params, uint32_t a_params_size); /** * Create item dap_chain_tx_sig_t * diff --git a/modules/common/include/dap_chain_datum_tx_out_cond.h b/modules/common/include/dap_chain_datum_tx_out_cond.h index 06c1a85f62a85c3a32abf24d959591ddc1fae600..e90701767a1172caf75fb9fe86e62908519fa099 100644 --- a/modules/common/include/dap_chain_datum_tx_out_cond.h +++ b/modules/common/include/dap_chain_datum_tx_out_cond.h @@ -32,7 +32,8 @@ typedef enum dap_chain_tx_out_cond_subtype { DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY = 0x01, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE = 0x02, - DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE = 0x03 + DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE = 0x13, + DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_UPDATE = 0xFA // Virtual type for stake update verificator } dap_chain_tx_out_cond_subtype_t; DAP_STATIC_INLINE const char *dap_chain_tx_out_cond_subtype_to_str(dap_chain_tx_out_cond_subtype_t a_subtype){ @@ -94,6 +95,8 @@ typedef struct dap_chain_tx_out_cond { struct { // Service uid that only could be used for this outout dap_chain_net_srv_uid_t srv_uid; + // Stake holder address + dap_chain_addr_t hldr_addr; // Fee address dap_chain_addr_t fee_addr; // Fee value in percent 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 5aa85e5aa8a02992c9164c9d4f361e7528fd957c..aa93918c49be22d8232d0e8460ff6990e7c3ce4e 100644 --- a/modules/consensus/block-poa/dap_chain_cs_block_poa.c +++ b/modules/consensus/block-poa/dap_chain_cs_block_poa.c @@ -27,6 +27,7 @@ #include "dap_enc_base58.h" #include "dap_cert.h" #include "dap_chain.h" +#include "dap_chain_pvt.h" #include "dap_chain_block.h" #include "dap_chain_block_cache.h" #include "dap_chain_cs_blocks.h" @@ -44,7 +45,7 @@ typedef struct dap_chain_cs_dag_poa_pvt { - dap_cert_t * sign_cert; + dap_enc_key_t *sign_key; dap_cert_t ** auth_certs; char * auth_certs_prefix; uint16_t auth_certs_count; @@ -59,9 +60,10 @@ static void s_callback_delete(dap_chain_cs_blocks_t* a_blocks); static int s_callback_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg); static int s_callback_created(dap_chain_t * a_chain, dap_config_t *a_chain_cfg); 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 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); // CLI commands -static int s_cli_block_poa(int argc, char ** argv, void *arg_func, char **str_reply); +static int s_cli_block_poa(int argc, char ** argv, char **str_reply); static bool s_seed_mode = false; /** @@ -73,8 +75,8 @@ int dap_chain_cs_block_poa_init(void) // Add consensus constructor dap_chain_cs_add ("block_poa", s_callback_new ); s_seed_mode = dap_config_get_item_bool_default(g_config,"general","seed_mode",false); - dap_chain_node_cli_cmd_item_create ("block_poa", s_cli_block_poa, NULL, "Blockchain PoA commands", - "block_poa -net <chain net name> -chain <chain name> block new_block_sign [-cert <cert name>] \n" + dap_chain_node_cli_cmd_item_create ("block_poa", s_cli_block_poa, "Blockchain PoA commands", + "block_poa -net <chain net name> -chain <chain name> block sign [-cert <cert name>] \n" "\tSign new block with certificate <cert name> or withs own PoA certificate\n\n"); return 0; @@ -98,9 +100,8 @@ void dap_chain_cs_block_poa_deinit(void) * @param str_reply * @return */ -static int s_cli_block_poa(int argc, char ** argv, void *arg_func, char **a_str_reply) +static int s_cli_block_poa(int argc, char ** argv, char **a_str_reply) { - (void) arg_func; int ret = -666; int arg_index = 1; dap_chain_net_t * l_chain_net = NULL; @@ -118,25 +119,28 @@ static int s_cli_block_poa(int argc, char ** argv, void *arg_func, char **a_str_ dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index,argc,argv,a_str_reply,&l_chain,&l_chain_net); dap_chain_cs_blocks_t * l_blocks = DAP_CHAIN_CS_BLOCKS(l_chain); - //dap_chain_cs_dag_poa_t * l_poa = DAP_CHAIN_CS_DAG_POA( l_dag ) ; dap_chain_cs_block_poa_pvt_t * l_poa_pvt = PVT ( DAP_CHAIN_CS_BLOCK_POA( l_blocks ) ); const char * l_block_new_cmd_str = NULL; const char * l_block_hash_str = NULL; const char * l_cert_str = NULL; - dap_cert_t * l_cert = l_poa_pvt->sign_cert; - if ( l_poa_pvt->sign_cert == NULL) { - dap_chain_node_cli_set_reply_text(a_str_reply, "No certificate to sign events\n"); - return -2; - } dap_chain_node_cli_find_option_val(argv, arg_index, argc, "block", &l_block_new_cmd_str); dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-block", &l_block_hash_str); dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-cert", &l_cert_str); + dap_enc_key_t *l_sign_key; // Load cert to sign if its present - if (l_cert_str) - l_cert = dap_cert_find_by_name( l_cert_str); + if (l_cert_str) { + dap_cert_t *l_cert = dap_cert_find_by_name( l_cert_str); + l_sign_key = l_cert->enc_key; + } else { + l_sign_key = l_poa_pvt->sign_key; + } + if (!l_sign_key || !l_sign_key->priv_key_data) { + dap_chain_node_cli_set_reply_text(a_str_reply, "No certificate to sign blocks\n"); + return -2; + } // block hash may be in hex or base58 format char *l_block_hash_hex_str; @@ -150,12 +154,10 @@ static int s_cli_block_poa(int argc, char ** argv, void *arg_func, char **a_str_ l_event_hash_base58_str = dap_strdup(l_block_hash_str); } - // Parse block ccmd + // Parse block cmd if ( l_block_new_cmd_str != NULL ){ - if (l_poa_pvt->sign_cert ) - ret = -1; - if ( strcmp(l_block_new_cmd_str,"new_block_sign") == 0) { // Sign event command - l_blocks->block_new_size = dap_chain_block_sign_add( &l_blocks->block_new,l_blocks->block_new_size, l_cert ); + if ( strcmp(l_block_new_cmd_str,"sign") == 0) { // Sign event command + l_blocks->block_new_size = dap_chain_block_sign_add( &l_blocks->block_new,l_blocks->block_new_size, l_sign_key); //dap_chain_hash_fast_t l_block_new_hash; //dap_hash_fast(l_blocks->block_new, l_blocks->block_new_size,&l_block_new_hash); } @@ -170,14 +172,15 @@ static int s_cli_block_poa(int argc, char ** argv, void *arg_func, char **a_str_ */ static int s_callback_new(dap_chain_t * a_chain, dap_config_t * a_chain_cfg) { - dap_chain_cs_create(a_chain,a_chain_cfg); + dap_chain_cs_blocks_new(a_chain, a_chain_cfg); dap_chain_cs_blocks_t * l_blocks = DAP_CHAIN_CS_BLOCKS( a_chain ); dap_chain_cs_block_poa_t * l_poa = DAP_NEW_Z ( dap_chain_cs_block_poa_t); l_blocks->_inheritor = l_poa; l_blocks->callback_delete = s_callback_delete; l_blocks->callback_block_verify = s_callback_block_verify; - l_poa->_pvt = DAP_NEW_Z ( dap_chain_cs_block_poa_pvt_t ); - dap_chain_cs_block_poa_pvt_t * l_poa_pvt = PVT ( l_poa ); + l_blocks->callback_block_sign = s_callback_block_sign; + l_poa->_pvt = DAP_NEW_Z(dap_chain_cs_block_poa_pvt_t); + dap_chain_cs_block_poa_pvt_t *l_poa_pvt = PVT(l_poa); if (dap_config_get_item_str(a_chain_cfg,"block-poa","auth_certs_prefix") ) { l_poa_pvt->auth_certs_count = dap_config_get_item_uint16_default(a_chain_cfg,"block-poa","auth_certs_number",0); @@ -219,14 +222,19 @@ static int s_callback_created(dap_chain_t * a_chain, dap_config_t *a_chain_net_c if (PVT(l_poa)->prev_callback_created ) PVT(l_poa)->prev_callback_created(a_chain,a_chain_net_cfg); - const char * l_sign_cert = NULL; - if ( ( l_sign_cert = dap_config_get_item_str(a_chain_net_cfg,"block-poa","sign-cert") ) != NULL ) { - - if ( ( PVT(l_poa)->sign_cert = dap_cert_find_by_name(l_sign_cert)) == NULL ){ - log_it(L_ERROR,"Can't load sign certificate, name \"%s\" is wrong",l_sign_cert); - }else - log_it(L_NOTICE,"Loaded \"%s\" certificate to sign poa blocks", l_sign_cert); - + const char * l_sign_cert_str = NULL; + if ( ( l_sign_cert_str = dap_config_get_item_str(a_chain_net_cfg,"block-poa","sign-cert") ) != NULL ) { + dap_cert_t *l_sign_cert = dap_cert_find_by_name(l_sign_cert_str); + if (l_sign_cert == NULL) { + log_it(L_ERROR, "Can't load sign certificate, name \"%s\" is wrong", l_sign_cert_str); + } else if (l_sign_cert->enc_key->priv_key_data) { + PVT(l_poa)->sign_key = l_sign_cert->enc_key; + log_it(L_NOTICE, "Loaded \"%s\" certificate to sign poa blocks", l_sign_cert_str); + } else { + log_it(L_ERROR, "Certificate \"%s\" has no private key", l_sign_cert_str); + } + } else { + log_it(L_ERROR, "No sign certificate provided, can't sign any blocks"); } return 0; } @@ -256,6 +264,29 @@ static void s_callback_delete(dap_chain_cs_blocks_t * a_blocks) } } +/** + * @brief + * function makes block singing + * @param a_dag a_blocks dap_chain_cs_blocks_t + * @param a_block dap_chain_block_t + * @param a_block_size size_t size of block object + * @return int + */ +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) +{ + assert(a_blocks); + dap_chain_cs_block_poa_t *l_poa = DAP_CHAIN_CS_BLOCK_POA(a_blocks); + dap_chain_cs_block_poa_pvt_t *l_poa_pvt = PVT(l_poa); + if (!l_poa_pvt->sign_key) { + log_it(L_WARNING, "Can't sign block with sign-cert in [block-poa] section"); + return 0; + } + if (!a_block_ptr || !(*a_block_ptr) || !a_block_size) { + log_it(L_WARNING, "Block size or block pointer is NULL"); + return 0; + } + return dap_chain_block_sign_add(a_block_ptr, a_block_size, l_poa_pvt->sign_key); +} /** * @brief s_callbac_block_verify @@ -276,21 +307,23 @@ static int s_callback_block_verify(dap_chain_cs_blocks_t * a_blocks, dap_chain_b return -2; } // Parse the rest signs - size_t l_offset = (byte_t*)l_sign - (byte_t*) a_block; - while (l_offset < a_block_size - sizeof (a_block->hdr) ){ + size_t l_offset = (byte_t *)l_sign - a_block->meta_n_datum_n_sign; + while (l_offset < a_block_size - sizeof(a_block->hdr)) { + if (!dap_sign_verify_size(l_sign, a_block_size)) { + log_it(L_ERROR, "Corrupted block: sign size is bigger than block size"); + return -3; + } size_t l_sign_size = dap_sign_get_size(l_sign); // Check if sign size 0 if (!l_sign_size){ log_it(L_ERROR, "Corrupted block: sign size got zero"); - return -3; + return -4; } // Check if sign size too big if (l_sign_size > a_block_size- sizeof (a_block->hdr)-l_offset ){ log_it(L_ERROR, "Corrupted block: sign size %zd is too big, out from block size %zd", l_sign_size, a_block_size); - return -3; + return -5; } - l_offset += l_sign_size; - // Compare signature with auth_certs for (uint16_t j = 0; j < l_poa_pvt->auth_certs_count; j++) { if (dap_cert_compare_with_sign ( l_poa_pvt->auth_certs[j], l_sign) == 0){ @@ -298,7 +331,23 @@ static int s_callback_block_verify(dap_chain_cs_blocks_t * a_blocks, dap_chain_b break; } } + l_offset += l_sign_size; + l_sign = (dap_sign_t *)(a_block->meta_n_datum_n_sign + l_offset); + } + if (l_offset != a_block_size - sizeof(a_block->hdr)) { + log_it(L_ERROR, "Corrupted block: sign end exceeded the block bound"); + return -6; } return l_signs_verified_count >= l_poa_pvt->auth_certs_count_verify ? 0 : -1; } +dap_cert_t **dap_chain_cs_block_poa_get_auth_certs(dap_chain_t *a_chain, size_t *a_auth_certs_count) +{ + dap_chain_pvt_t *l_chain_pvt = DAP_CHAIN_PVT(a_chain); + if (strcmp(l_chain_pvt->cs_name, "block_poa")) + return NULL; + dap_chain_cs_block_poa_pvt_t *l_poa_pvt = PVT(DAP_CHAIN_CS_BLOCK_POA(DAP_CHAIN_CS_BLOCKS(a_chain))); + if (a_auth_certs_count) + *a_auth_certs_count = l_poa_pvt->auth_certs_count; + return l_poa_pvt->auth_certs; +} diff --git a/modules/consensus/block-poa/include/dap_chain_cs_block_poa.h b/modules/consensus/block-poa/include/dap_chain_cs_block_poa.h index e2bc7b718b3eea2011854a11178443a34b753024..2ccd4f70254ffd26a8b7da68560c2929d96e4db3 100644 --- a/modules/consensus/block-poa/include/dap_chain_cs_block_poa.h +++ b/modules/consensus/block-poa/include/dap_chain_cs_block_poa.h @@ -38,3 +38,4 @@ typedef struct dap_chain_cs_block_poa int dap_chain_cs_block_poa_init(void); void dap_chain_cs_block_poa_deinit(void); +dap_cert_t **dap_chain_cs_block_poa_get_auth_certs(dap_chain_t *a_chain, size_t *a_auth_certs_count); diff --git a/modules/consensus/block-pos/CMakeLists.txt b/modules/consensus/block-pos/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..2417e6529e529168867e0f383b60606f07463e1a --- /dev/null +++ b/modules/consensus/block-pos/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.0) +project (dap_chain_cs_block_pos) + +file(GLOB DAP_CHAIN_CS_BLOCK_POS_SRCS *.c) +file(GLOB DAP_CHAIN_CS_BLOCK_POS_HEADERS include/*.h) + +add_library(${PROJECT_NAME} STATIC ${DAP_CHAIN_CS_BLOCK_POS_SRCS} ${DAP_CHAIN_CS_BLOCK_POS_HEADERS}) + +target_link_libraries(dap_chain_cs_block_pos dap_core dap_crypto dap_chain dap_chain_cs_blocks dap_chain_net_srv_stake) +target_include_directories(dap_chain_cs_block_pos INTERFACE .) +target_include_directories(${PROJECT_NAME} PUBLIC include) diff --git a/modules/consensus/block-pos/dap_chain_cs_block_pos.c b/modules/consensus/block-pos/dap_chain_cs_block_pos.c new file mode 100644 index 0000000000000000000000000000000000000000..90ffe94de3f5e68243181e331605e6c71697be4d --- /dev/null +++ b/modules/consensus/block-pos/dap_chain_cs_block_pos.c @@ -0,0 +1,285 @@ +/* + * Authors: + * Roman Khlopkov <roman.khlopkov@demlabs.net> + * DeM Labs Inc. https://demlabs.net + * Kelvin Project https://github.com/kelvinblockchain + * Copyright (c) 2017-2021 + * 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 <stdlib.h> + +#include "dap_chain_net.h" +#include "dap_common.h" +#include "dap_string.h" +#include "dap_strfuncs.h" +#include "dap_chain_cs.h" +#include "dap_chain_cs_blocks.h" +#include "dap_chain_cs_block_pos.h" +#include "dap_chain_net_srv_stake.h" +#include "dap_chain_ledger.h" + +#define LOG_TAG "dap_chain_cs_block_pos" + +typedef struct dap_chain_cs_block_pos_pvt +{ + dap_enc_key_t *blocks_sign_key; + char **tokens_hold; + uint64_t *tokens_hold_value; + size_t tokens_hold_size; + uint16_t confirmations_minimum; + dap_chain_callback_new_cfg_t prev_callback_created; +} dap_chain_cs_block_pos_pvt_t; + +#define PVT(a) ((dap_chain_cs_block_pos_pvt_t *)a->_pvt) + +static void s_callback_delete(dap_chain_cs_blocks_t *a_blocks); +static int s_callback_new(dap_chain_t *a_chain, dap_config_t *a_chain_cfg); +static int s_callback_created(dap_chain_t *a_chain, dap_config_t *a_chain_cfg); +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 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); + +/** + * @brief dap_chain_cs_block_pos_init + * @return + */ +int dap_chain_cs_block_pos_init() +{ + dap_chain_cs_add("block_pos", s_callback_new); + return 0; +} + +/** + * @brief dap_chain_cs_block_pos_deinit + */ +void dap_chain_cs_block_pos_deinit(void) +{ + +} + +/** + * @brief s_cs_callback + * @param a_chain + * @param a_chain_cfg + */ +static int s_callback_new(dap_chain_t *a_chain, dap_config_t *a_chain_cfg) +{ + dap_chain_cs_blocks_new(a_chain, a_chain_cfg); + dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain); + dap_chain_cs_block_pos_t *l_pos = DAP_NEW_Z(dap_chain_cs_block_pos_t); + l_blocks->_inheritor = l_pos; + l_blocks->callback_delete = s_callback_delete; + l_blocks->callback_block_verify = s_callback_block_verify; + l_blocks->callback_block_sign = s_callback_block_sign; + l_pos->_pvt = DAP_NEW_Z(dap_chain_cs_block_pos_pvt_t); + + dap_chain_cs_block_pos_pvt_t *l_pos_pvt = PVT(l_pos); + + char ** l_tokens_hold = NULL; + char ** l_tokens_hold_value_str = NULL; + uint16_t l_tokens_hold_size = 0; + uint16_t l_tokens_hold_value_size = 0; + + l_tokens_hold = dap_config_get_array_str(a_chain_cfg, "block-pos", "stake_tokens", &l_tokens_hold_size); + l_tokens_hold_value_str = dap_config_get_array_str(a_chain_cfg, "block-pos", "stake_tokens_value", &l_tokens_hold_value_size); + + if (l_tokens_hold_size != l_tokens_hold_value_size){ + log_it(L_CRITICAL, "Entries tokens_hold and tokens_hold_value are different size!"); + goto lb_err; + } + l_pos_pvt->confirmations_minimum = dap_config_get_item_uint16_default(a_chain_cfg, "block-pos", "verifications_minimum", 1); + l_pos_pvt->tokens_hold_size = l_tokens_hold_size; + l_pos_pvt->tokens_hold = DAP_NEW_Z_SIZE(char *, sizeof(char *) * l_tokens_hold_size); + l_pos_pvt->tokens_hold_value = DAP_NEW_Z_SIZE(uint64_t, l_tokens_hold_value_size * sizeof(uint64_t)); + + for (size_t i = 0; i < l_tokens_hold_value_size; i++) { + l_pos_pvt->tokens_hold[i] = dap_strdup(l_tokens_hold[i]); + if ((l_pos_pvt->tokens_hold_value[i] = + strtoull(l_tokens_hold_value_str[i],NULL,10)) == 0) { + log_it(L_CRITICAL, "Token %s has inproper hold value %s", + l_pos_pvt->tokens_hold[i], l_tokens_hold_value_str[i]); + goto lb_err; + } + } + // Save old callback if present and set the call of its own (chain callbacks) + l_pos_pvt->prev_callback_created = l_blocks->chain->callback_created; + l_blocks->chain->callback_created = s_callback_created; + return 0; + +lb_err: + for (int i = 0; i < l_tokens_hold_size; i++) + DAP_DELETE(l_tokens_hold[i]); + DAP_DELETE(l_tokens_hold); + DAP_DELETE(l_pos_pvt->tokens_hold_value); + DAP_DELETE(l_pos_pvt); + DAP_DELETE(l_pos ); + l_blocks->_inheritor = NULL; + l_blocks->callback_delete = NULL; + l_blocks->callback_block_verify = NULL; + return -1; + +} + +/** + * @brief s_callback_created + * @param a_chain + * @param a_chain_cfg + * @return + */ +static int s_callback_created(dap_chain_t *a_chain, dap_config_t *a_chain_net_cfg) +{ + dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain); + dap_chain_cs_block_pos_t *l_pos = DAP_CHAIN_CS_BLOCK_POS(l_blocks); + + const char * l_sign_cert_str = NULL; + if ( ( l_sign_cert_str = dap_config_get_item_str(a_chain_net_cfg,"block-pos","sign-cert") ) != NULL ) { + dap_cert_t *l_sign_cert = dap_cert_find_by_name(l_sign_cert_str); + if (l_sign_cert == NULL) { + log_it(L_ERROR, "Can't load sign certificate, name \"%s\" is wrong", l_sign_cert_str); + } else if (l_sign_cert->enc_key->priv_key_data) { + PVT(l_pos)->blocks_sign_key = l_sign_cert->enc_key; + log_it(L_NOTICE, "Loaded \"%s\" certificate to sign PoS blocks", l_sign_cert_str); + } else { + log_it(L_ERROR, "Certificate \"%s\" has no private key", l_sign_cert_str); + } + } else { + log_it(L_ERROR, "No sign certificate provided, can't sign any blocks"); + } + return 0; +} + + +/** + * @brief s_chain_cs_block_callback_delete + * @param a_block + */ +static void s_callback_delete(dap_chain_cs_blocks_t *a_blocks) +{ + dap_chain_cs_block_pos_t *l_pos = DAP_CHAIN_CS_BLOCK_POS(a_blocks); + if (l_pos->_pvt) + DAP_DELETE(l_pos->_pvt); +} + +/** + * @brief + * function makes block singing + * @param a_block a_blocks dap_chain_cs_blocks_t + * @param a_block dap_chain_block_t + * @param a_block_size size_t size of block object + * @return int + */ +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) +{ + assert(a_blocks); + dap_chain_cs_block_pos_t *l_pos = DAP_CHAIN_CS_BLOCK_POS(a_blocks); + dap_chain_cs_block_pos_pvt_t *l_pos_pvt = PVT(l_pos); + if (!l_pos_pvt->blocks_sign_key) { + log_it(L_WARNING, "Can't sign block with sign-cert in [block-pos] section"); + return 0; + } + if (!a_block_ptr || !(*a_block_ptr) || !a_block_size) { + log_it(L_WARNING, "Block size or block pointer is NULL"); + return 0; + } + return dap_chain_block_sign_add(a_block_ptr, a_block_size, l_pos_pvt->blocks_sign_key); +} + +/** + * @brief + * function makes block singing verification + * @param a_block a_blocks dap_chain_cs_blocks_t + * @param a_block dap_chain_block_t + * @param a_block_size size_t size of block object + * @return int + */ +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_cs_block_pos_t *l_pos = DAP_CHAIN_CS_BLOCK_POS(a_blocks); + dap_chain_cs_block_pos_pvt_t *l_pos_pvt = PVT(l_pos); + + if (a_blocks->chain->ledger == NULL) { + log_it(L_CRITICAL,"Ledger is NULL can't check PoS on this chain %s", a_blocks->chain->name); + return -3; + } + + if (sizeof(a_block->hdr) >= a_block_size) { + log_it(L_WARNING,"Incorrect size with block %p on chain %s", a_block, a_blocks->chain->name); + return -7; + } + + size_t l_signs_count = dap_chain_block_get_signs_count(a_block, a_block_size); + if (l_signs_count < l_pos_pvt->confirmations_minimum) { + log_it(L_WARNING,"Wrong signature number with block %p on chain %s", a_block, a_blocks->chain->name); + return -2; // Wrong signatures number + } + + uint16_t l_verified_num = 0; + for (size_t l_sig_pos = 0; l_sig_pos < l_signs_count; l_sig_pos++) { + dap_sign_t *l_sign = dap_chain_block_sign_get(a_block, a_block_size, l_sig_pos); + if (l_sign == NULL) { + log_it(L_WARNING, "Block isn't signed with anything: sig pos %zu, event size %zu", l_sig_pos, a_block_size); + return -4; + } + + bool l_sign_size_correct = dap_sign_verify_size(l_sign, a_block_size); + if (!l_sign_size_correct) { + log_it(L_WARNING, "Block's sign #%zu size is incorrect", l_sig_pos); + return -44; + } + size_t l_block_data_size = dap_chain_block_get_sign_offset(a_block, a_block_size); + if (l_block_data_size == a_block_size) { + log_it(L_WARNING,"Block has nothing except sign, nothing to verify so I pass it (who knows why we have it?)"); + return 0; + } + + int l_sign_verified = dap_sign_verify(l_sign, a_block, l_block_data_size); + if (l_sign_verified != 1) { + log_it(L_WARNING, "Block's sign is incorrect: code %d", l_sign_verified); + return -41; + } + + if (l_sig_pos == 0) { + dap_chain_addr_t l_addr = {}; + dap_chain_hash_fast_t l_pkey_hash; + dap_sign_get_pkey_hash(l_sign, &l_pkey_hash); + dap_chain_addr_fill(&l_addr, l_sign->header.type, &l_pkey_hash, a_blocks->chain->net_id); + size_t l_datums_count = 0; + dap_chain_datum_t **l_datums = dap_chain_block_get_datums(a_block, a_block_size, &l_datums_count); + if (!l_datums || !l_datums_count) { + log_it(L_WARNING, "No datums in block %p on chain %s", a_block, a_blocks->chain->name); + return -7; + } + for (size_t i = 0; i < l_datums_count; i++) { + if (!dap_chain_net_srv_stake_validator(&l_addr, l_datums[i])) { + log_it(L_WARNING, "Not passed stake validator datum %zu with block %p on chain %s", i, a_block, a_blocks->chain->name); + DAP_DELETE(l_datums); + return -6; + } + } + DAP_DELETE(l_datums); + } + } + + // Check number + if (l_verified_num >= l_pos_pvt->confirmations_minimum) { + // Passed all checks + return 0; + } else { + log_it(L_WARNING, "Wrong block: only %hu/%hu signs are valid", l_verified_num, l_pos_pvt->confirmations_minimum); + return -2; + } +} diff --git a/modules/consensus/block-pos/include/dap_chain_cs_block_pos.h b/modules/consensus/block-pos/include/dap_chain_cs_block_pos.h new file mode 100644 index 0000000000000000000000000000000000000000..368c77a653e87749451b5860d7c1ab5f2addde5d --- /dev/null +++ b/modules/consensus/block-pos/include/dap_chain_cs_block_pos.h @@ -0,0 +1,39 @@ +/* + * Authors: + * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net> + * DeM Labs Inc. https://demlabs.net + * Kelvin Project https://github.com/kelvinblockchain + * Copyright (c) 2017-2018 + * 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/>. +*/ +#pragma once +#include "dap_chain_cs_blocks.h" +#include "dap_cert.h" + +typedef struct dap_chain_cs_block_pos +{ + dap_chain_t *chain; + dap_chain_cs_blocks_t *blocks; + void *_pvt; +} dap_chain_cs_block_pos_t; + +#define DAP_CHAIN_CS_BLOCK_POS(a) ((dap_chain_cs_block_pos_t *)(a)->_inheritor) + + +int dap_chain_cs_block_pos_init(); +void dap_chain_cs_block_pos_deinit(void); 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 b759fddcec890219dc3ad34eea6f6d6456ee6760..ef2ef81218e97053e8e3bc658673289036518f8b 100644 --- a/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c +++ b/modules/consensus/dag-poa/dap_chain_cs_dag_poa.c @@ -36,6 +36,7 @@ #include "dap_common.h" #include "dap_strfuncs.h" #include "dap_enc_base58.h" +#include "dap_chain_pvt.h" #include "dap_chain_net.h" #include "dap_chain_node_cli.h" #include "dap_chain_node_cli_cmd.h" @@ -402,24 +403,6 @@ static int s_callback_event_verify(dap_chain_cs_dag_t * a_dag, dap_chain_cs_dag_ if (dap_cert_compare_with_sign ( l_poa_pvt->auth_certs[j], l_sign) == 0) l_verified++; } - if (i == 0) { - dap_chain_hash_fast_t l_pkey_hash; - if (!dap_sign_get_pkey_hash(l_sign, &l_pkey_hash)) { - log_it(L_WARNING, "Event's sign has no any key"); - return -5; - } - dap_chain_addr_t l_addr = {}; - dap_chain_addr_fill(&l_addr, l_sign->header.type, &l_pkey_hash, a_dag->chain->net_id); - dap_chain_datum_t *l_datum = (dap_chain_datum_t *)dap_chain_cs_dag_event_get_datum(a_dag_event, a_dag_event_size); - if (l_datum->header.type_id == DAP_CHAIN_DATUM_TX) { - dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)l_datum->data; - if (!dap_chain_net_srv_stake_validator(&l_addr, l_tx)) { - log_it(L_WARNING,"Not passed stake validator event %p", a_dag_event); - return -6; - } - } - } - } return l_verified >= l_poa_pvt->auth_certs_count_verify ? 0 : -1; }else if (a_dag_event->header.hash_count == 0){ @@ -437,3 +420,13 @@ static int s_callback_event_verify(dap_chain_cs_dag_t * a_dag, dap_chain_cs_dag_ } } +dap_cert_t **dap_chain_cs_dag_poa_get_auth_certs(dap_chain_t *a_chain, size_t *a_auth_certs_count) +{ + dap_chain_pvt_t *l_chain_pvt = DAP_CHAIN_PVT(a_chain); + if (strcmp(l_chain_pvt->cs_name, "dag_poa")) + return NULL; + dap_chain_cs_dag_poa_pvt_t *l_poa_pvt = PVT(DAP_CHAIN_CS_DAG_POA(DAP_CHAIN_CS_DAG(a_chain))); + if (a_auth_certs_count) + *a_auth_certs_count = l_poa_pvt->auth_certs_count; + return l_poa_pvt->auth_certs; +} diff --git a/modules/consensus/dag-poa/include/dap_chain_cs_dag_poa.h b/modules/consensus/dag-poa/include/dap_chain_cs_dag_poa.h index b6f05be8207df185de0af5d4ae8e09c884de3e18..c437ff91d2f0f6f47e969196bab192cff9697609 100644 --- a/modules/consensus/dag-poa/include/dap_chain_cs_dag_poa.h +++ b/modules/consensus/dag-poa/include/dap_chain_cs_dag_poa.h @@ -23,6 +23,7 @@ */ #pragma once #include "dap_chain_cs_dag.h" +#include "dap_cert.h" typedef struct dap_chain_cs_dag_poa { @@ -37,3 +38,4 @@ typedef struct dap_chain_cs_dag_poa int dap_chain_cs_dag_poa_init(void); void dap_chain_cs_dag_poa_deinit(void); +dap_cert_t **dap_chain_cs_dag_poa_get_auth_certs(dap_chain_t *a_chain, size_t *a_auth_certs_count); diff --git a/modules/consensus/dag-pos/dap_chain_cs_dag_pos.c b/modules/consensus/dag-pos/dap_chain_cs_dag_pos.c index a87056044de3a392d0da91a694e6f31a980db361..5a98adfca649e6f5c3350516aebe572741f40bcb 100644 --- a/modules/consensus/dag-pos/dap_chain_cs_dag_pos.c +++ b/modules/consensus/dag-pos/dap_chain_cs_dag_pos.c @@ -234,7 +234,6 @@ static int s_callback_event_verify(dap_chain_cs_dag_t * a_dag, dap_chain_cs_dag_ } if ( a_dag_event->header.signs_count >= l_pos_pvt->confirmations_minimum ){ uint16_t l_verified_num = 0; - dap_chain_addr_t l_addr = { 0 }; for ( size_t l_sig_pos=0; l_sig_pos < a_dag_event->header.signs_count; l_sig_pos++ ){ dap_sign_t * l_sign = dap_chain_cs_dag_event_get_sign(a_dag_event, a_dag_event_size,l_sig_pos); @@ -258,28 +257,15 @@ static int s_callback_event_verify(dap_chain_cs_dag_t * a_dag, dap_chain_cs_dag_ return -41; } - if (!l_dag_event_size_without_sign){ - log_it(L_WARNING,"Event has nothing except sign, nothing to verify so I pass it (who knows why we have it?)"); - return 0; - } - - dap_chain_hash_fast_t l_pkey_hash; - if (!dap_sign_get_pkey_hash(l_sign, &l_pkey_hash)) { - log_it(L_WARNING, "Event's sign has no any key"); - return -5; - } - dap_chain_addr_fill(&l_addr, l_sign->header.type, &l_pkey_hash, a_dag->chain->net_id); - - - if (l_sig_pos == 0) { - dap_chain_datum_t *l_datum = (dap_chain_datum_t *)dap_chain_cs_dag_event_get_datum(a_dag_event,a_dag_event_size); - if (l_datum->header.type_id == DAP_CHAIN_DATUM_TX) { - dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)l_datum->data; - if (!dap_chain_net_srv_stake_validator(&l_addr, l_tx)) { - log_it(L_WARNING,"Not passed stake validator with event %p on chain %s", a_dag_event, a_dag->chain->name); - return -6; - } + dap_chain_addr_t l_addr = {}; + dap_chain_hash_fast_t l_pkey_hash; + dap_sign_get_pkey_hash(l_sign, &l_pkey_hash); + dap_chain_addr_fill(&l_addr, l_sign->header.type, &l_pkey_hash, a_dag->chain->net_id); + dap_chain_datum_t *l_datum = (dap_chain_datum_t *)dap_chain_cs_dag_event_get_datum(a_dag_event, a_dag_event_size); + if (!dap_chain_net_srv_stake_validator(&l_addr, l_datum)) { + log_it(L_WARNING, "Not passed stake validator with event %p on chain %s", a_dag_event, a_dag->chain->name); + return -6; } } /* @@ -299,24 +285,24 @@ static int s_callback_event_verify(dap_chain_cs_dag_t * a_dag, dap_chain_cs_dag_ if(l_is_emit) return 0;*/ - bool l_is_enough_balance = false; - for (size_t i =0; i <l_pos_pvt->tokens_hold_size; i++){ - uint256_t l_balance = dap_chain_ledger_calc_balance ( a_dag->chain->ledger , &l_addr, l_pos_pvt->tokens_hold[i] ); - uint64_t l_value = dap_chain_uint256_to(l_balance); - if (l_value >= l_pos_pvt->tokens_hold_value[i]) { - l_verified_num++; - l_is_enough_balance = true; - break; - } - } - if (! l_is_enough_balance ){ - char *l_addr_str = dap_chain_addr_to_str(&l_addr); - log_it(L_WARNING, "Verify of event is false, because bal is not enough for addr=%s", l_addr_str); - DAP_DELETE(l_addr_str); - return -1; - } - } + // bool l_is_enough_balance = false; + // for (size_t i =0; i <l_pos_pvt->tokens_hold_size; i++){ + // uint256_t l_balance = dap_chain_ledger_calc_balance ( a_dag->chain->ledger , &l_addr, l_pos_pvt->tokens_hold[i] ); + // uint64_t l_value = dap_chain_uint256_to(l_balance); + // if (l_value >= l_pos_pvt->tokens_hold_value[i]) { + // l_verified_num++; + // l_is_enough_balance = true; + // break; + // } + // } + // if (! l_is_enough_balance ){ + // char *l_addr_str = dap_chain_addr_to_str(&l_addr); + // log_it(L_WARNING, "Verify of event is false, because bal is not enough for addr=%s", l_addr_str); + // DAP_DELETE(l_addr_str); + // return -1; + //} + } // Check number if ( l_verified_num >= l_pos_pvt->confirmations_minimum ){ // Passed all checks diff --git a/modules/consensus/none/dap_chain_cs_none.c b/modules/consensus/none/dap_chain_cs_none.c index 4662123e1e9017c16705b0ccaab7cf3f3ff8ee1d..99cec6bd6247bb0d9ebd2ff4536bb9d53140d086 100644 --- a/modules/consensus/none/dap_chain_cs_none.c +++ b/modules/consensus/none/dap_chain_cs_none.c @@ -336,6 +336,10 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_add(dap_chain_t * a_cha if(dap_chain_ledger_tx_load(a_chain->ledger, l_tx) != 1) return ATOM_REJECT; }break; + case DAP_CHAIN_DATUM_CA:{ + if ( dap_cert_chain_file_save(l_datum, a_chain->net_name) < 0 ) + return ATOM_REJECT; + }break; default: return ATOM_REJECT; } diff --git a/modules/global-db/dap_chain_global_db.c b/modules/global-db/dap_chain_global_db.c index 65983fbe02ff6c3a704baf60c10d32e1ef6589b6..89d1fbd18ad9ab89166f48dffea62acc494ab387 100644 --- a/modules/global-db/dap_chain_global_db.c +++ b/modules/global-db/dap_chain_global_db.c @@ -351,7 +351,6 @@ static bool global_db_gr_del_add(char *a_key,const char *a_group, time_t a_times return false; } - /** * @brief Deletes info about the deleted object from the database * @param a_key an object key string, looked like "0x8FAFBD00B..." @@ -379,7 +378,6 @@ static bool global_db_gr_del_del(char *a_key, const char *a_group) return false; } - /** * @brief Gets time stamp of the deleted object by a_group and a_key arguments. * @param a_group a group name sring, for example "kelvin-testnet.nodes" @@ -420,7 +418,6 @@ bool dap_chain_global_db_del(char *a_key) return dap_chain_global_db_gr_del(a_key, GROUP_LOCAL_GENERAL); } - /** * @brief Gets a last item from a database by a_group. * @param a_group a group name string @@ -556,7 +553,6 @@ void dap_global_db_obj_track_history(void* a_store_data) } } - /** * @brief Adds a value to a database. * @param a_key a object key string diff --git a/modules/global-db/dap_chain_global_db_driver_cdb.c b/modules/global-db/dap_chain_global_db_driver_cdb.c index 0a480510b8caf414049f29bee3015def5f58ba16..0b647cc4ff8cc6a21702886bb45d7e0c471987e9 100644 --- a/modules/global-db/dap_chain_global_db_driver_cdb.c +++ b/modules/global-db/dap_chain_global_db_driver_cdb.c @@ -141,7 +141,7 @@ bool dap_cdb_get_cond_obj_iter_callback(void *arg, const char *key, int ksize, c return true; } -//** A callback function designed for countng items*/ +//** A callback function designed for counting items*/ bool dap_cdb_get_count_iter_callback(void *arg, const char *key, int ksize, const char *val, int vsize, uint32_t expire, uint64_t oid) { UNUSED(ksize); UNUSED(val); diff --git a/modules/global-db/dap_chain_global_db_driver_pgsql.c b/modules/global-db/dap_chain_global_db_driver_pgsql.c index cf692542c7220a3e6d322c8c6c5519edaefcea61..1232f9837bb27b5d8b2b5a7388cf25cfaaa7e98c 100644 --- a/modules/global-db/dap_chain_global_db_driver_pgsql.c +++ b/modules/global-db/dap_chain_global_db_driver_pgsql.c @@ -83,9 +83,10 @@ static void s_pgsql_free_connection(PGconn *a_conn) } /** - * SQLite library initialization, no thread safe - * - * return 0 if Ok, else error code >0 + * @brief Initializes a PostgreSQL database. + * @param a_filename_dir a path to the database file + * @param a_drv_callback a pointer to a structure of callback functions + * @return If successful returns 0, else a error code <0. */ int dap_db_driver_pgsql_init(const char *a_filename_dir, dap_db_driver_callbacks_t *a_drv_callback) { @@ -189,7 +190,11 @@ int dap_db_driver_pgsql_init(const char *a_filename_dir, dap_db_driver_callbacks return 0; } - +/** + * @brief Deinitializes a SQLite database. + * + * @return Returns 0 if successful. + */ int dap_db_driver_pgsql_deinit(void) { pthread_rwlock_wrlock(&s_db_rwlock); @@ -201,7 +206,9 @@ int dap_db_driver_pgsql_deinit(void) } /** - * Start a transaction + * @brief Starts a transaction. + * + * @return Returns 0 if successful, otherwise -1. */ int dap_db_driver_pgsql_start_transaction(void) { @@ -220,7 +227,9 @@ int dap_db_driver_pgsql_start_transaction(void) } /** - * End of transaction + * @brief Starts a transaction in a PostgreSQL database. + * + * @return Returns 0 if successful, otherwise -1. */ int dap_db_driver_pgsql_end_transaction(void) { @@ -237,9 +246,11 @@ int dap_db_driver_pgsql_end_transaction(void) } /** - * Create table - * - * return 0 if Ok, else error code + * @brief Creates a table in a PostgreSQL database. + * + * @param a_table_name a table name string + * @param a_conn a pointer to the connection object + * @return Returns 0 if successful, otherwise -1. */ static int s_pgsql_create_group_table(const char *a_table_name, PGconn *a_conn) { @@ -261,8 +272,10 @@ static int s_pgsql_create_group_table(const char *a_table_name, PGconn *a_conn) } /** - * Apply data (write or delete) - * + * @brief Applies an object to a PostgreSQL database. + * + * @param a_store_obj a pointer to the object structure + * @return Returns 0 if successful, else a error code less than zero. */ int dap_db_driver_pgsql_apply_store_obj(dap_store_obj_t *a_store_obj) { @@ -337,6 +350,14 @@ int dap_db_driver_pgsql_apply_store_obj(dap_store_obj_t *a_store_obj) return l_ret; } +/** + * @brief Fills a object from a row + * @param a_group a group name string + * @param a_obj a pointer to the object + * @param a_res a pointer to the result structure + * @param a_row a row number + * @return (none) + */ static void s_pgsql_fill_object(const char *a_group, dap_store_obj_t *a_obj, PGresult *a_res, int a_row) { a_obj->group = dap_strdup(a_group); @@ -356,12 +377,12 @@ static void s_pgsql_fill_object(const char *a_group, dap_store_obj_t *a_obj, PGr } /** - * Read several items - * - * a_group - group name - * a_key - key name, may by NULL, it means reading the whole group - * a_count_out[in], how many items to read, 0 - no limits - * a_count_out[out], how many items was read + * @brief Reads some objects from a PostgreSQL database by a_group and a_key. + * @param a_group a group name string + * @param a_key an object key string, if equals NULL reads the whole group + * @param a_count_out[in] a number of objects to be read, if equals 0 reads with no limits + * @param a_count_out[out] a number of objects that were read + * @return If successful, a pointer to an objects, otherwise a null pointer. */ dap_store_obj_t *dap_db_driver_pgsql_read_store_obj(const char *a_group, const char *a_key, size_t *a_count_out) { @@ -409,9 +430,9 @@ dap_store_obj_t *dap_db_driver_pgsql_read_store_obj(const char *a_group, const c } /** - * Read last item - * - * a_group - group name + * @brief Reads a last object from a PostgreSQL database. + * @param a_group a group name string + * @return Returns a pointer to the object if successful, otherwise a null pointer. */ dap_store_obj_t *dap_db_driver_pgsql_read_last_store_obj(const char *a_group) { @@ -444,12 +465,12 @@ dap_store_obj_t *dap_db_driver_pgsql_read_last_store_obj(const char *a_group) } /** - * Read several items with conditoin - * - * a_group - group name - * a_id - read from this id - * a_count_out[in], how many items to read, 0 - no limits - * a_count_out[out], how many items was read + * @brief Reads some objects from a PostgreSQL database by conditions. + * @param a_group a group name string + * @param a_id id + * @param a_count_out[in] a number of objects to be read, if equals 0 reads with no limits + * @param a_count_out[out] a number of objects that were read + * @return If successful, a pointer to an objects, otherwise a null pointer. */ dap_store_obj_t *dap_db_driver_pgsql_read_cond_store_obj(const char *a_group, uint64_t a_id, size_t *a_count_out) { @@ -493,7 +514,11 @@ dap_store_obj_t *dap_db_driver_pgsql_read_cond_store_obj(const char *a_group, ui return l_obj; } - +/** + * @brief Gets a list of group names from a PostgreSQL database by a_group_mask. + * @param a_group_mask a group name mask + * @return Returns a pointer to a list of group names if successful, otherwise a null pointer. + */ dap_list_t *dap_db_driver_pgsql_get_groups_by_mask(const char *a_group_mask) { if (!a_group_mask) @@ -524,6 +549,12 @@ dap_list_t *dap_db_driver_pgsql_get_groups_by_mask(const char *a_group_mask) return l_ret_list; } +/** + * @brief Reads a number of objects from a PostgreSQL database by a_group and a_id. + * @param a_group a group name string + * @param a_id id starting from which the quantity is calculated + * @return Returns a number of objects. + */ size_t dap_db_driver_pgsql_read_count_store(const char *a_group, uint64_t a_id) { if (!a_group) @@ -551,6 +582,12 @@ size_t dap_db_driver_pgsql_read_count_store(const char *a_group, uint64_t a_id) return l_ret; } +/** + * @brief Checks if an object is in a PostgreSQL database by a_group and a_key. + * @param a_group a group name string + * @param a_key a object key string + * @return Returns true if it is, false it's not. + */ bool dap_db_driver_pgsql_is_obj(const char *a_group, const char *a_key) { if (!a_group) @@ -577,6 +614,10 @@ bool dap_db_driver_pgsql_is_obj(const char *a_group, const char *a_key) return l_ret; } +/** + * @brief Flushes a PostgreSQ database cahce to disk. + * @return Returns 0 if successful, else a error code less than zero. + */ int dap_db_driver_pgsql_flush() { PGconn *l_conn = s_pgsql_get_connection(); diff --git a/modules/global-db/dap_chain_global_db_hist.c b/modules/global-db/dap_chain_global_db_hist.c index 9404776f360d6b9d7f5066707b3781ce80b78311..aafef57f07da99f0fb8317dd8e98fe7c285a5cd0 100644 --- a/modules/global-db/dap_chain_global_db_hist.c +++ b/modules/global-db/dap_chain_global_db_hist.c @@ -28,6 +28,12 @@ typedef struct dap_tx_data{ #define LOG_TAG "dap_chain_global_db_hist" +/** + * @brief Packs members of a_rec structure into a single string. + * + * @param a_rec a pointer to the structure + * @return Returns the string. + */ static char* dap_db_history_pack_hist(dap_global_db_hist_t *a_rec) { char *l_ret = dap_strdup_printf("%c%s%u%s%s%s%s", a_rec->type, GLOBAL_DB_HIST_REC_SEPARATOR, a_rec->keys_count, @@ -35,6 +41,13 @@ static char* dap_db_history_pack_hist(dap_global_db_hist_t *a_rec) return l_ret; } +/** + * @brief Unpacks a single string into a structure. + * + * @param l_str_in the string + * @param a_rec_out the structure + * @return Returns 1 if successful, otherwise -1. + */ static int dap_db_history_unpack_hist(char *l_str_in, dap_global_db_hist_t *a_rec_out) { char **l_strv = dap_strsplit(l_str_in, GLOBAL_DB_HIST_REC_SEPARATOR, -1); @@ -49,6 +62,11 @@ static int dap_db_history_unpack_hist(char *l_str_in, dap_global_db_hist_t *a_re return 1; } +/** + * @brief Gets a current time with a suffix. + * + * @return Returns a string containing a current time and a suffix. + */ static char* dap_db_new_history_timestamp() { static pthread_mutex_t s_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -75,7 +93,13 @@ static char* dap_db_new_history_timestamp() } /** - * Add data to the history log + * @brief Adds data to the history log. + * + * @param a_type a type of record + * @param a_store_obj a pointer to the object structure + * @param a_dap_store_count a number of objects + * @param a_group a group name string + * @return Returns true if successful, otherwise false. */ bool dap_db_history_add(char a_type, pdap_store_obj_t a_store_obj, size_t a_dap_store_count, const char *a_group) { @@ -127,7 +151,10 @@ bool dap_db_history_add(char a_type, pdap_store_obj_t a_store_obj, size_t a_dap_ } /** - * Get last id in log + * @brief Gets last id of the log. + * + * @param a_group_name a group name string + * @return Returns id if succeessful. */ uint64_t dap_db_log_get_group_last_id(const char *a_group_name) { @@ -141,7 +168,9 @@ uint64_t dap_db_log_get_group_last_id(const char *a_group_name) } /** - * Get last id in log + * @brief Gets last id of local.history group. + * + * @return Returns id if succeess. */ uint64_t dap_db_log_get_last_id(void) { @@ -149,8 +178,10 @@ uint64_t dap_db_log_get_last_id(void) } /** - * Thread for reading log list - * instead dap_db_log_get_list() + * @brief A function for a thread for reading a log list + * + * @param arg a pointer to the log list structure + * @return Returns NULL. */ static void *s_list_thread_proc(void *arg) { @@ -218,7 +249,12 @@ static void *s_list_thread_proc(void *arg) } /** - * instead dap_db_log_get_list() + * @brief Starts a thread that readding a log list + * @note instead dap_db_log_get_list() + * + * @param a_addr a pointer to the structure + * @param a_flags flags + * @return Returns a pointer to the log list structure if successful, otherwise NULL pointer. */ dap_db_log_list_t* dap_db_log_list_start(dap_chain_node_addr_t a_addr, int a_flags) { @@ -260,7 +296,10 @@ dap_db_log_list_t* dap_db_log_list_start(dap_chain_node_addr_t a_addr, int a_fla } /** - * Get number of items + * @brief Gets a number of objects from a log list. + * + * @param a_db_log_list a pointer to the log list structure + * @return Returns the number if successful, otherwise 0. */ size_t dap_db_log_list_get_count(dap_db_log_list_t *a_db_log_list) { @@ -273,6 +312,12 @@ size_t dap_db_log_list_get_count(dap_db_log_list_t *a_db_log_list) return l_items_number; } +/** + * @brief Gets a number of rest objects from a log list. + * + * @param a_db_log_list a pointer to the log list structure + * @return Returns the number if successful, otherwise 0. + */ size_t dap_db_log_list_get_count_rest(dap_db_log_list_t *a_db_log_list) { if(!a_db_log_list) @@ -283,10 +328,13 @@ size_t dap_db_log_list_get_count_rest(dap_db_log_list_t *a_db_log_list) pthread_mutex_unlock(&a_db_log_list->list_mutex); return l_items_rest; } + /** - * Get one item from log_list + * @brief Gets an object from a list. + * + * @param a_db_log_list a pointer to the log list + * @return Returns a pointer to the object. */ - dap_db_log_list_obj_t *dap_db_log_list_get(dap_db_log_list_t *a_db_log_list) { if(!a_db_log_list) @@ -318,6 +366,12 @@ dap_db_log_list_obj_t *dap_db_log_list_get(dap_db_log_list_t *a_db_log_list) return l_list ? (dap_db_log_list_obj_t *)l_list->data : NULL; } +/** + * @brief Deallocates memory of a list item + * + * @param a_item a pointer to the list item + * @returns (none) + */ void dap_db_log_list_delete_item(void *a_item) { dap_db_log_list_obj_t *l_list_item = (dap_db_log_list_obj_t *)a_item; @@ -326,7 +380,10 @@ void dap_db_log_list_delete_item(void *a_item) } /** - * Get log diff as list_write + * @brief Deallocates memory of a log list. + * + * @param a_db_log_list a pointer to the log list structure + * @returns (none) */ void dap_db_log_list_delete(dap_db_log_list_t *a_db_log_list) { diff --git a/modules/global-db/dap_chain_global_db_remote.c b/modules/global-db/dap_chain_global_db_remote.c index 8bed4f838c9c191b7a8d2dbc0cd68d7558ff674c..3c51d5bec51b247045e1f4041e8fb7957ed6162f 100644 --- a/modules/global-db/dap_chain_global_db_remote.c +++ b/modules/global-db/dap_chain_global_db_remote.c @@ -15,9 +15,9 @@ #define NODE_TIME_EXPIRED_DEFAULT 720 /** - * @brief Sets current node adress + * @brief Sets a current node adress. * @param a_address a current node adress - * @param a_net_name a net name + * @param a_net_name a net name string * @return True if success, otherwise false */ static bool dap_db_set_cur_node_addr_common(uint64_t a_address, char *a_net_name, time_t a_expire_time) @@ -39,7 +39,11 @@ static bool dap_db_set_cur_node_addr_common(uint64_t a_address, char *a_net_name } /** - * Set addr for current node and no expire time + * @brief Sets an adress of a current node and no expire time. + * + * @param a_address an adress of a current node + * @param a_net_name a net name string + * @return Returns true if siccessful, otherwise false */ bool dap_db_set_cur_node_addr(uint64_t a_address, char *a_net_name ) { @@ -47,7 +51,11 @@ bool dap_db_set_cur_node_addr(uint64_t a_address, char *a_net_name ) } /** - * Set addr for current node and expire time + * @brief Sets an adress of a current node and expire time. + * + * @param a_address an adress of a current node + * @param a_net_name a net name string + * @return Returns true if siccessful, otherwise false */ bool dap_db_set_cur_node_addr_exp(uint64_t a_address, char *a_net_name ) { @@ -55,10 +63,11 @@ bool dap_db_set_cur_node_addr_exp(uint64_t a_address, char *a_net_name ) return dap_db_set_cur_node_addr_common(a_address,a_net_name,l_cur_time); } - - /** - * Get addr for current node + * @brief Gets an adress of current node by a net name. + * + * @param a_net_name a net name string + * @return Returns an adress if successful, otherwise 0. */ uint64_t dap_db_get_cur_node_addr(char *a_net_name) { @@ -105,7 +114,12 @@ uint64_t dap_db_get_cur_node_addr(char *a_net_name) } /** - * Set last id for remote node + * @brief Sets last id of a remote node. + * + * @param a_node_addr a node adress + * @param a_id id + * @param a_group a group name string + * @return Returns true if successful, otherwise false. */ bool dap_db_set_last_id_remote(uint64_t a_node_addr, uint64_t a_id, char *a_group) { @@ -119,7 +133,11 @@ bool dap_db_set_last_id_remote(uint64_t a_node_addr, uint64_t a_id, char *a_grou } /** - * Get last id for remote node + * @brief Gets last id of a remote node. + * + * @param a_node_addr a node adress + * @param a_group a group name string + * @return Returns id if successful, otherwise 0. */ uint64_t dap_db_get_last_id_remote(uint64_t a_node_addr, char *a_group) { @@ -138,7 +156,13 @@ uint64_t dap_db_get_last_id_remote(uint64_t a_node_addr, char *a_group) } /** - * Set last hash for chain for remote node + * @brief Sets the last hash of a remote node. + * + * @param a_node_addr a node adress + * @param a_chain a pointer to the chain stucture + * @param a_hash a + * @return true + * @return false */ bool dap_db_set_last_hash_remote(uint64_t a_node_addr, dap_chain_t *a_chain, dap_chain_hash_fast_t *a_hash) { @@ -147,7 +171,11 @@ bool dap_db_set_last_hash_remote(uint64_t a_node_addr, dap_chain_t *a_chain, dap } /** - * Get last hash for chain for remote node + * @brief Gets the last hash of a remote node. + * + * @param a_node_addr a node adress + * @param a_chain a pointer to a chain structure + * @return Returns a hash if successful. */ dap_chain_hash_fast_t *dap_db_get_last_hash_remote(uint64_t a_node_addr, dap_chain_t *a_chain) { @@ -159,6 +187,12 @@ dap_chain_hash_fast_t *dap_db_get_last_hash_remote(uint64_t a_node_addr, dap_cha return (dap_chain_hash_fast_t *)l_hash; } +/** + * @brief Gets a size of an object. + * + * @param store_obj a pointer to the object + * @return Returns the size. + */ static size_t dap_db_get_size_pdap_store_obj_t(pdap_store_obj_t store_obj) { size_t size = sizeof(uint32_t) + 2 * sizeof(uint16_t) + sizeof(time_t) @@ -168,10 +202,10 @@ static size_t dap_db_get_size_pdap_store_obj_t(pdap_store_obj_t store_obj) } /** - * serialization - * @param a_old_pkt an object for multiplexation - * @param a_new_pkt an object for multiplexation - * @return NULL in case of an error + * @brief Multiples data into a_old_pkt structure from a_new_pkt structure. + * @param a_old_pkt a pointer to the old object + * @param a_new_pkt a pointer to the new object + * @return Returns a pointer to the multiple object */ dap_store_obj_pkt_t *dap_store_packet_multiple(dap_store_obj_pkt_t *a_old_pkt, dap_store_obj_pkt_t *a_new_pkt) { @@ -188,6 +222,13 @@ dap_store_obj_pkt_t *dap_store_packet_multiple(dap_store_obj_pkt_t *a_old_pkt, d return a_old_pkt; } +/** + * @brief Changes id in a packed structure. + * + * @param a_pkt a pointer to the packed structure + * @param a_id id + * @return (none) + */ void dap_store_packet_change_id(dap_store_obj_pkt_t *a_pkt, uint64_t a_id) { uint16_t l_gr_len; @@ -197,9 +238,9 @@ void dap_store_packet_change_id(dap_store_obj_pkt_t *a_pkt, uint64_t a_id) } /** - * serialization - * @param a_store_obj an object for serialization - * @return NULL in case of an error + * @brief Serializes an object into a packed structure. + * @param a_store_obj a pointer to the object to be serialized + * @return Returns a pointer to the packed sructure if successful, otherwise NULL. */ dap_store_obj_pkt_t *dap_store_packet_single(pdap_store_obj_t a_store_obj) { @@ -235,12 +276,13 @@ dap_store_obj_pkt_t *dap_store_packet_single(pdap_store_obj_t a_store_obj) assert(l_offset == l_data_size_out); return l_pkt; } + /** - * deserialization - * @param store_obj_count[out] count of the output structures store_obj - * @return NULL in case of an error* + * @brief Deserializes some objects from a packed structure into an array of objects. + * @param pkt a pointer to the serialized packed structure + * @param store_obj_count[out] a number of deserialized objects in the array + * @return Returns a pointer to the first object in the array, if successful; otherwise NULL. */ - dap_store_obj_t *dap_store_unpacket_multiple(const dap_store_obj_pkt_t *pkt, size_t *store_obj_count) { if(!pkt || pkt->data_size < 1) diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c index 2f7f9de17b8991ae0e83d076f2828c9f891c55aa..011e0dbfa8b88fdda35379941fae1852ab8356e7 100644 --- a/modules/net/dap_chain_net.c +++ b/modules/net/dap_chain_net.c @@ -99,7 +99,6 @@ #include "dap_stream_ch.h" #include "dap_stream_ch_pkt.h" #include "dap_chain_node_dns_client.h" - #include "dap_module.h" #include <stdio.h> @@ -2893,11 +2892,14 @@ void dap_chain_net_dump_datum(dap_string_t * a_str_out, dap_chain_datum_t * a_da case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE:{ dap_string_append_printf(a_str_out,"\tsubtype: DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE\n"); }break; + default:{ + dap_string_append_printf(a_str_out,"\tsubtype: UNKNOWN\n"); + }break; } dap_string_append_printf(a_str_out,"\tparams_size : %u\n", l_out->params_size ); } break; - case TX_ITEM_TYPE_RECEIPT:{} break; - default:{} + case TX_ITEM_TYPE_RECEIPT: + default: break; } n++; } @@ -2991,3 +2993,26 @@ static uint8_t *dap_chain_net_set_acl(dap_chain_hash_fast_t *a_pkey_hash) } return NULL; } + +/** + * @brief dap_cert_chain_file_save + * @param datum + */ +int dap_cert_chain_file_save(dap_chain_datum_t * datum, char * net_name) +{ + const char * s_system_chain_ca_dir = dap_config_get_item_str(g_config, "resources", "chain_ca_folder"); + + dap_cert_t * cert = dap_cert_mem_load(datum->data, datum->header.data_size); + const char * cert_name = cert->name; + + size_t cert_path_length = strlen(net_name)+strlen(cert_name)+9+strlen(s_system_chain_ca_dir); + char *cert_path = DAP_NEW_Z_SIZE(char,cert_path_length); + + snprintf(cert_path,cert_path_length,"%s/%s/%s.dcert",s_system_chain_ca_dir,net_name,cert_name); + +// if ( access( l_cert_path, F_OK ) != -1 ) { +// log_it (L_ERROR, "File %s is already exists.", l_cert_path); +// return -1; +// } else + return dap_cert_file_save(cert, cert_path); +} diff --git a/modules/net/dap_chain_node_cli.c b/modules/net/dap_chain_node_cli.c index dc27fd869b16608b44da8f9f228337b3e1445c97..09745c70f49314a71740572eead1de2d47bfb82c 100644 --- a/modules/net/dap_chain_node_cli.c +++ b/modules/net/dap_chain_node_cli.c @@ -1071,6 +1071,13 @@ int dap_chain_node_cli_init(dap_config_t * g_config) "Add pubic certificate into the mempool to prepare its way to chains", "mempool_add_ca -net <net name> [-chain <chain name>] -ca_name <Certificate name>\n"); + dap_chain_node_cli_cmd_item_create ("chain_ca_pub", com_chain_ca_pub, + "Add pubic certificate into the mempool to prepare its way to chains", + "chain_ca -net <net name> [-chain <chain name>] -ca_name <Certificate name>\n"); + + dap_chain_node_cli_cmd_item_create ("chain_ca_copy", com_chain_ca_copy, + "Copy pubic certificate into the mempool to prepare its way to chains", + "chain_ca -net <net name> [-chain <chain name>] -ca_name <Public certificate name>\n"); // Transaction commands dap_chain_node_cli_cmd_item_create ("tx_create", com_tx_create, "Make transaction", diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index 90ab16fab659dc789efd7c1be82edadbe1c698b9..0ca0fb95cd7a2d6169450e685a9932fcd1ca8669 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -3186,13 +3186,13 @@ int com_token_emit(int a_argc, char ** a_argv, char ** a_str_reply) return -43; } - // Wallet address that recieves the emission + // Token emission dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-emission", &l_emission_hash_str); // 256 dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-256", &l_type_256); - // Wallet address that recieves the emission + // Emission certs dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-certs", &l_certs_str); // Wallet address that recieves the emission @@ -3201,7 +3201,7 @@ int com_token_emit(int a_argc, char ** a_argv, char ** a_str_reply) // Token ticker dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-token", &l_ticker); - // Token emission + // Emission value if(dap_chain_node_cli_find_option_val(a_argv, arg_index, a_argc, "-emission_value", &str_tmp)) { // l_emission_value = strtoull(str_tmp, NULL, 10); l_emission_value = GET_256_FROM_128(dap_strtou128(str_tmp, NULL, 10)); @@ -3305,8 +3305,8 @@ int com_token_emit(int a_argc, char ** a_argv, char ** a_str_reply) // size_t l_emission_256_size = sizeof(l_emission_256->hdr) + // sizeof(l_emission_256->data.type_auth.signs_count); - size_t l_offset = 0; l_emission = DAP_NEW_Z_SIZE(dap_chain_datum_token_emission_t, l_emission_size); + if ( !l_type_256 ) { l_emission->hdr.type_value_256 = false; l_emission->hdr.value = dap_chain_uint256_to(l_emission_value); @@ -3314,11 +3314,18 @@ int com_token_emit(int a_argc, char ** a_argv, char ** a_str_reply) l_emission->hdr.type_value_256 = true; l_emission->hdr.value_256 = l_emission_value; } - + + l_emission->hdr.version = 1; + strncpy(l_emission->hdr.ticker, l_ticker, sizeof(l_emission->hdr.ticker) - 1); l_emission->hdr.type = DAP_CHAIN_DATUM_TOKEN_EMISSION_TYPE_AUTH; memcpy(&l_emission->hdr.address, l_addr, sizeof(l_emission->hdr.address)); + time_t l_time = time(NULL); + memcpy(&l_emission->hdr.nonce, &l_time, sizeof(time_t)); + // Then add signs + size_t l_offset = 0; + for(size_t i = 0; i < l_certs_size; i++) { dap_sign_t * l_sign = dap_cert_sign(l_certs[i], &l_emission->hdr, sizeof(l_emission->hdr), 0); @@ -3364,15 +3371,15 @@ int com_token_emit(int a_argc, char ** a_argv, char ** a_str_reply) if(dap_chain_global_db_gr_set(dap_strdup(l_emission_hash_str_new), (uint8_t *) l_datum_emission, l_datum_emission_size , l_gdb_group_mempool_emission)) { if(!dap_strcmp(l_hash_out_type,"hex")) - str_reply_tmp = dap_strdup_printf("datum emission %s is placed in datum pool ", l_emission_hash_str_new); + str_reply_tmp = dap_strdup_printf("Datum emission %s is placed in datum pool", l_emission_hash_str_new); else - str_reply_tmp = dap_strdup_printf("datum emission %s is placed in datum pool ", l_emission_hash_str_base58); + str_reply_tmp = dap_strdup_printf("Datum emission %s is placed in datum pool", l_emission_hash_str_base58); } else { if(!dap_strcmp(l_hash_out_type,"hex")) - dap_chain_node_cli_set_reply_text(a_str_reply, "datum emission %s is not placed in datum pool ", l_emission_hash_str_new); + dap_chain_node_cli_set_reply_text(a_str_reply, "Datum emission %s is not placed in datum pool", l_emission_hash_str_new); else - dap_chain_node_cli_set_reply_text(a_str_reply, "datum emission %s is not placed in datum pool ", l_emission_hash_str_base58); + dap_chain_node_cli_set_reply_text(a_str_reply, "Datum emission %s is not placed in datum pool", l_emission_hash_str_base58); DAP_DEL_Z(l_emission_hash_str_new); l_emission_hash_str = NULL; DAP_DEL_Z(l_emission_hash_str_base58); @@ -3754,6 +3761,102 @@ int com_mempool_add_ca(int a_argc, char ** a_argv, char ** a_str_reply) } } +/** + * @brief com_chain_ca_copy + * @details copy public CA into the mempool + * @param a_argc + * @param a_argv + * @param a_arg_func + * @param a_str_reply + * @return + */ +int com_chain_ca_copy( int a_argc, char ** a_argv, char ** a_str_reply) +{ + return com_mempool_add_ca(a_argc, a_argv, a_str_reply); +} + + +/** + * @brief com_chain_ca_pub + * @details place public CA into the mempool + * @param a_argc + * @param a_argv + * @param a_arg_func + * @param a_str_reply + * @return + */ +int com_chain_ca_pub( int a_argc, char ** a_argv, char ** a_str_reply) +{ + int arg_index = 1; + // Read params + const char * l_ca_name = NULL; + dap_chain_net_t * l_net = NULL; + dap_chain_t * l_chain = NULL; + + dap_chain_node_cli_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_cert_t * l_cert = dap_cert_find_by_name( l_ca_name ); + if( l_cert == NULL ){ + dap_chain_node_cli_set_reply_text(a_str_reply, + "Can't find \"%s\" certificate", l_ca_name ); + return -4; + } + + + if( l_cert->enc_key == NULL ){ + dap_chain_node_cli_set_reply_text(a_str_reply, + "Corrupted certificate \"%s\" without keys certificate", l_ca_name ); + return -5; + } + + // Create empty new cert + dap_cert_t * l_cert_new = dap_cert_new(l_ca_name); + l_cert_new->enc_key = dap_enc_key_new( l_cert->enc_key->type); + + // Copy only public key + l_cert_new->enc_key->pub_key_data = DAP_NEW_Z_SIZE(uint8_t, + l_cert_new->enc_key->pub_key_data_size = + l_cert->enc_key->pub_key_data_size ); + memcpy(l_cert_new->enc_key->pub_key_data, l_cert->enc_key->pub_key_data,l_cert->enc_key->pub_key_data_size); + + // Serialize certificate into memory + uint32_t l_cert_serialized_size = 0; + byte_t * l_cert_serialized = dap_cert_mem_save( l_cert_new, &l_cert_serialized_size ); + if( l_cert_serialized == NULL){ + dap_chain_node_cli_set_reply_text(a_str_reply, + "Can't serialize in memory certificate" ); + return -7; + } + if( l_cert_serialized == NULL){ + dap_chain_node_cli_set_reply_text(a_str_reply, + "Can't serialize in memory certificate"); + return -7; + } + // Now all the chechs passed, forming datum for mempool + dap_chain_datum_t * l_datum = dap_chain_datum_create( DAP_CHAIN_DATUM_CA, l_cert_serialized , l_cert_serialized_size); + DAP_DELETE( l_cert_serialized); + if( l_datum == NULL){ + dap_chain_node_cli_set_reply_text(a_str_reply, + "Can't produce datum from certificate"); + return -7; + } + + // Finaly add datum to mempool + char *l_hash_str = dap_chain_mempool_datum_add(l_datum,l_chain); + if (l_hash_str) { + dap_chain_node_cli_set_reply_text(a_str_reply, + "Datum %s was successfully placed to mempool", l_hash_str); + DAP_DELETE(l_hash_str); + return 0; + } else { + dap_chain_node_cli_set_reply_text(a_str_reply, + "Can't place certificate \"%s\" to mempool", l_ca_name); + DAP_DELETE( l_datum ); + return -8; + } +} + /** * @brief Create transaction diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c index 928453d9477437ea9da31a8ed1a647ea45e64342..bd40a3fb9e47e53fe5074d5a2a7893020a48bd79 100644 --- a/modules/net/dap_chain_node_cli_cmd_tx.c +++ b/modules/net/dap_chain_node_cli_cmd_tx.c @@ -323,7 +323,7 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, ((dap_chain_tx_out_cond_t*)item)->header.value, dap_chain_tx_out_cond_subtype_to_str(((dap_chain_tx_out_cond_t*)item)->header.subtype)); switch (((dap_chain_tx_out_cond_t*)item)->header.subtype) { - case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY: + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY: l_hash_str_tmp = dap_chain_hash_fast_to_str_new(&((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.pkey_hash); dap_string_append_printf(a_str_out, "\t\t\t unit: 0x%08x\n" "\t\t\t uid: 0x%016"DAP_UINT64_FORMAT_x"\n" @@ -338,7 +338,7 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, ((dap_chain_tx_out_cond_t*)item)->subtype.srv_pay.unit_price_max_datoshi); DAP_FREE(l_hash_str_tmp); break; - case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE: + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE: dap_string_append_printf(a_str_out, "\t\t\t uid: 0x%016"DAP_UINT64_FORMAT_x"\n" "\t\t\t addr: %s\n" "\t\t\t value: %Lf", @@ -348,7 +348,7 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, ), ((dap_chain_tx_out_cond_t*)item)->subtype.srv_stake.fee_value); break; - case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE: + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE: dap_string_append_printf(a_str_out, "\t\t\t uid: 0x%016"DAP_UINT64_FORMAT_x"\n" "\t\t\t net id: 0x%016"DAP_UINT64_FORMAT_x"\n" "\t\t\t token: %s\n" @@ -363,6 +363,7 @@ static void s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum, ), ((dap_chain_tx_out_cond_t*)item)->subtype.srv_xchange.value); break; + default: break; } break; case TX_ITEM_TYPE_256_OUT_COND: // 256 @@ -1378,7 +1379,8 @@ static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger l_token_num++; break; } - dap_chain_datum_token_emission_t *l_token_em = (dap_chain_datum_token_emission_t*) l_datum->data; + size_t l_emission_size = dap_chain_datum_emission_get_size(l_datum->data); + dap_chain_datum_token_emission_t *l_token_em = dap_chain_datum_emission_read(l_datum->data, &l_emission_size); if(!a_filter_token_name || !dap_strcmp(l_token_em->hdr.ticker, a_filter_token_name)) { char * l_token_emission_address_str = dap_chain_addr_to_str(&(l_token_em->hdr.address)); // filter for addr @@ -1442,10 +1444,10 @@ static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger dap_string_append_printf(l_str_out, "\n"); l_emission_num++; } - } - break; + DAP_DELETE(l_token_em); + } break; - // transaction + // transaction case DAP_CHAIN_DATUM_TX:{ // datum out of page @@ -1455,247 +1457,8 @@ static char* dap_db_history_filter(dap_chain_t * a_chain, dap_ledger_t *a_ledger } dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*)l_datum->data; -// dap_chain_tx_hash_processed_ht_t *l_tx_hash_processed = a_tx_hash_processed; //calc tx hash s_dap_chain_datum_tx_out_data(l_tx, a_ledger, l_str_out, a_hash_out_type, true, &a_tx_hash_processed, &l_tx_num); -// a_tx_hash_processed = l_tx_hash_processed; -// l_tx_num++; - - /*dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*) l_datum->data; - - // find Token items - present in emit transaction - dap_list_t *l_list_tx_token = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_TOKEN, NULL); - // find OUT items - dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT, NULL); - - dap_tx_data_t *l_tx_data = NULL; - - // calc tx hash - dap_chain_hash_fast_t l_tx_hash; - dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_tx_hash); - char *tx_hash_str; - char l_tx_hash_str[70]; - dap_chain_hash_fast_to_str(&l_tx_hash, l_tx_hash_str, 70); - if(!dap_strcmp(a_hash_out_type, "hex")) - tx_hash_str = dap_strdup(l_tx_hash_str); - else - tx_hash_str = dap_enc_base58_from_hex_str_to_str(l_tx_hash_str); - - dap_string_append_printf(l_str_out, "transaction: %s hash: %s\n", l_list_tx_token ? "(emit)" : "", tx_hash_str); - DAP_DELETE(tx_hash_str); - - dap_list_t *l_list_tmp = l_list_out_items; - while(l_list_tmp) { - const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) l_list_tmp->data; - // save OUT item l_tx_out - only for first OUT item - if(!l_tx_data) - { - // save tx hash - l_tx_data = DAP_NEW_Z(dap_tx_data_t); - dap_chain_hash_fast_t l_tx_hash; - dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_tx_hash); - memcpy(&l_tx_data->tx_hash, &l_tx_hash, sizeof(dap_chain_hash_fast_t)); - memcpy(&l_tx_data->addr, &l_tx_out->addr, sizeof(dap_chain_addr_t)); - dap_chain_hash_fast_to_str(&l_tx_data->tx_hash, l_tx_data->tx_hash_str, - sizeof(l_tx_data->tx_hash_str)); - l_tx_data->datum = DAP_NEW_SIZE(dap_chain_datum_t, l_atom_size); - memcpy(l_tx_data->datum, l_datum, l_atom_size); - // save token name - if(l_list_tx_token) { - dap_chain_tx_token_t *tk = l_list_tx_token->data; - memcpy(l_tx_data->token_ticker, tk->header.ticker, sizeof(l_tx_data->token_ticker)); - } - // take token from prev out item - else { - - // find IN items - dap_list_t *l_list_in_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_IN, NULL); - dap_list_t *l_list_tmp_in = l_list_in_items; - // find token_ticker in prev OUT items - while(l_list_tmp_in) { - const dap_chain_tx_in_t *l_tx_in = - (const dap_chain_tx_in_t*) l_list_tmp_in->data; - dap_chain_hash_fast_t tx_prev_hash = l_tx_in->header.tx_prev_hash; - - //find prev OUT item - dap_tx_data_t *l_tx_data_prev = NULL; - HASH_FIND(hh, l_tx_data_hash, &tx_prev_hash, sizeof(dap_chain_hash_fast_t), l_tx_data_prev); - if(l_tx_data_prev != NULL) { - // fill token in l_tx_data from prev transaction - if(l_tx_data) { - // get token from prev tx - memcpy(l_tx_data->token_ticker, l_tx_data_prev->token_ticker, - sizeof(l_tx_data->token_ticker)); - break; - } - } - l_list_tmp_in = dap_list_next(l_list_tmp_in); - } - if(l_list_in_items) - dap_list_free(l_list_in_items); - } - HASH_ADD(hh, l_tx_data_hash, tx_hash, sizeof(dap_chain_hash_fast_t), l_tx_data); - } - l_list_tmp = dap_list_next(l_list_tmp); - } - - if(l_list_out_items) - dap_list_free(l_list_out_items); - - // found a_tx_hash now - // transaction time - if(l_tx->header.ts_created > 0) { - time_t rawtime = (time_t) l_tx->header.ts_created; - struct tm l_timeinfo = { 0 }; - localtime_r(&rawtime, &l_timeinfo); - dap_string_append_printf(l_str_out, " %s", asctime(&l_timeinfo)); - } - - // find all OUT items in transaction - l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT, NULL); - l_list_tmp = l_list_out_items; - while(l_list_tmp) { - const dap_chain_tx_out_t *l_tx_out = (const dap_chain_tx_out_t*) l_list_tmp->data; - dap_tx_data_t *l_tx_data_prev = NULL; - - const char *l_token_str = NULL; - if(l_tx_data) - l_token_str = l_tx_data->token_ticker; - char *l_dst_to_str = - (l_tx_out) ? dap_chain_addr_to_str(&l_tx_out->addr) : - NULL; - dap_string_append_printf(l_str_out, " OUT item %lld %s to %s\n", - l_tx_out->header.value, - dap_strlen(l_token_str) > 0 ? l_token_str : "?", - l_dst_to_str ? l_dst_to_str : "?" - ); - DAP_DELETE(l_dst_to_str); - l_list_tmp = dap_list_next(l_list_tmp); - } - - // find all IN items in transaction - dap_list_t *l_list_in_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_IN, NULL); - l_list_tmp = l_list_in_items; - // find cur addr in prev OUT items - while(l_list_tmp) { - const dap_chain_tx_in_t *l_tx_in = (const dap_chain_tx_in_t*) l_list_tmp->data; - dap_chain_hash_fast_t tx_prev_hash = l_tx_in->header.tx_prev_hash; - char l_tx_hash_str[70]; - char *tx_hash_base58_str = NULL; - if(!dap_hash_fast_is_blank(&tx_prev_hash)) { - tx_hash_base58_str = dap_enc_base58_from_hex_str_to_str(l_tx_data->tx_hash_str); - dap_chain_hash_fast_to_str(&tx_prev_hash, l_tx_hash_str, sizeof(l_tx_hash_str)); - } - else { - strcpy(l_tx_hash_str, "Null"); - tx_hash_base58_str = dap_strdup("Null"); - } - if(!dap_strcmp(a_hash_out_type, "hex")) - dap_string_append_printf(l_str_out, " IN item \n prev tx_hash %s\n", l_tx_hash_str); - else - dap_string_append_printf(l_str_out, " IN item \n prev tx_hash %s\n", tx_hash_base58_str); - DAP_DELETE(tx_hash_base58_str); - - //find prev OUT item - dap_tx_data_t *l_tx_data_prev = NULL; - HASH_FIND(hh, l_tx_data_hash, &tx_prev_hash, sizeof(dap_chain_hash_fast_t), l_tx_data_prev); - if(l_tx_data_prev != NULL) { - - dap_chain_datum_t *l_datum_prev = get_prev_tx(l_tx_data_prev); - dap_chain_datum_tx_t *l_tx_prev = - l_datum_prev ? (dap_chain_datum_tx_t*) l_datum_prev->data : NULL; - - // find OUT items in prev datum - dap_list_t *l_list_out_prev_items = dap_chain_datum_tx_items_get(l_tx_prev, - TX_ITEM_TYPE_OUT, NULL); - // find OUT item for IN item; - dap_list_t *l_list_out_prev_item = dap_list_nth(l_list_out_prev_items, - l_tx_in->header.tx_out_prev_idx); - dap_chain_tx_out_t *l_tx_prev_out = - l_list_out_prev_item ? - (dap_chain_tx_out_t*) l_list_out_prev_item->data : - NULL; - // print value from prev out item - dap_string_append_printf(l_str_out, " prev OUT item value=%lld", - l_tx_prev_out ? l_tx_prev_out->header.value : 0); - } - l_list_tmp = dap_list_next(l_list_tmp); - } - - //find SIG type - dap_list_t *l_list_sig_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_SIG, NULL); - unsigned int l_list_sig_items_len = dap_list_length(l_list_sig_items); - //TX_ITEM_TYPE_SIG - dap_string_append_printf(l_str_out, "Count SIGN: %i \n", l_list_sig_items_len); - l_list_tmp = l_list_sig_items; - while (l_list_tmp) { - dap_chain_tx_sig_t *l_sig_tx = (dap_chain_tx_sig_t *)l_list_tmp->data; - dap_chain_hash_fast_t *l_sign_hash_fast = DAP_NEW(dap_chain_hash_fast_t); - dap_sign_t *l_sign = dap_chain_datum_tx_item_sign_get_sig(l_sig_tx); - if (dap_sign_get_pkey_hash(l_sign, l_sign_hash_fast)){ - char l_tx_sign_hash_str[70]; - dap_chain_hash_fast_to_str(l_sign_hash_fast, l_tx_sign_hash_str, 70); - dap_string_append_printf(l_str_out, "%s\n", l_tx_sign_hash_str); - }else{ - dap_string_append_printf(l_str_out, "Can't get pkey for sign \n"); - } - DAP_FREE(l_sign_hash_fast); - l_list_tmp = dap_list_next(l_list_tmp); - } - dap_list_free(l_list_sig_items); - //find PKEY - dap_list_t *l_list_pkey_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_PKEY, NULL); - unsigned int l_list_pkey_items_len = dap_list_length(l_list_pkey_items); - dap_string_append_printf(l_str_out, "Count PKEY: %i \n", l_list_pkey_items_len); - dap_list_free(l_list_pkey_items); - //find TOKEN - dap_list_t *l_list_token_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_TOKEN, NULL); - unsigned int l_list_token_items_len = dap_list_length(l_list_token_items); - dap_string_append_printf(l_str_out, "Count TOKEN: %i \n", l_list_token_items_len); - l_list_tmp = l_list_token_items; - while(l_list_tmp){ - dap_chain_tx_token_t *l_token = (dap_chain_tx_token_t*)l_list_tmp->data; - l_list_tmp = dap_list_next(l_list_tmp); - } - dap_list_free(l_list_token_items); - //find IN_COND - dap_list_t *l_list_in_cond_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_IN_COND, NULL); - unsigned int l_list_in_cond_items_len = dap_list_length(l_list_in_cond_items); - dap_string_append_printf(l_str_out, "Count IN_COND: %i \n", l_list_in_cond_items_len); - dap_list_free(l_list_in_cond_items); - //find OUT_COND - dap_list_t *l_list_out_cond_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_COND, NULL); - unsigned int l_list_out_cond_items_len = dap_list_length(l_list_out_cond_items); - dap_string_append_printf(l_str_out, "Count OUT_COND: %i \n", l_list_out_cond_items_len); - dap_list_free(l_list_out_cond_items); - //find OUT_EXT - dap_list_t *l_list_out_ext_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_EXT, NULL); - unsigned int l_list_out_ext_items_len = dap_list_length(l_list_out_ext_items); - dap_string_append_printf(l_str_out, "Count OUT_EXIT: %i \n", l_list_out_ext_items_len); - dap_list_free(l_list_out_ext_items); - //find RECEIPT - dap_list_t *l_list_receipt_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_RECEIPT, NULL); - unsigned int l_list_receipt_items_len = dap_list_length(l_list_receipt_items); - dap_string_append_printf(l_str_out, "Count RECEIPT: %i \n", l_list_receipt_items_len); - dap_list_free(l_list_receipt_items); - //find TOKEN_EXT - dap_list_t *l_list_token_ext_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_TOKEN_EXT, NULL); - unsigned int l_list_token_ext_items_len = dap_list_length(l_list_token_ext_items); - dap_string_append_printf(l_str_out, "Count TOKEN_EXT: %i \n", l_list_token_ext_items_len); - dap_list_free(l_list_token_ext_items); - - dap_string_append_printf(l_str_out, "\n"); - - - - if(l_list_tx_token) - dap_list_free(l_list_tx_token); - if(l_list_out_items) - dap_list_free(l_list_out_items); - if(l_list_in_items) - dap_list_free(l_list_in_items); - l_tx_hash_found = true; - l_tx_num++;*/ } break; diff --git a/modules/net/include/dap_chain_net.h b/modules/net/include/dap_chain_net.h index bb7fe912de58ebdae8c405072b70b057d41b271f..e7e40be7532b8207727a0bd53802a41410b9b4cc 100644 --- a/modules/net/include/dap_chain_net.h +++ b/modules/net/include/dap_chain_net.h @@ -67,7 +67,7 @@ static const char * g_net_state_str[]={ typedef struct dap_chain_net{ struct { dap_chain_net_id_t id; - dap_chain_cell_id_t cell_id; // Cell where the node is connected to. {{0}} if not celled(sharder) blockchain + dap_chain_cell_id_t cell_id; // Cell where the node is connected to. {{0}} if not celled(sharded) blockchain char * name; char * gdb_groups_prefix; char * gdb_nodes_aliases; @@ -181,3 +181,4 @@ void dap_chain_net_sync_gdb_broadcast(void *a_arg, const char a_op_code, const c struct dap_chain_node_client * dap_chain_net_client_create_n_connect( dap_chain_net_t * a_net, struct dap_chain_node_info *a_link_info); struct dap_chain_node_client * dap_chain_net_client_create_n_connect_channels( dap_chain_net_t * a_net,struct dap_chain_node_info *a_link_info, const char * a_channels); +int dap_cert_chain_file_save(dap_chain_datum_t * l_datum, char * net_name); diff --git a/modules/net/include/dap_chain_node_cli_cmd.h b/modules/net/include/dap_chain_node_cli_cmd.h index 3c50d18e3cf46c7ee876bace88ced160ac5a2dab..0a35ddba34ef04ff885eb20ea877e1980f7d207d 100644 --- a/modules/net/include/dap_chain_node_cli_cmd.h +++ b/modules/net/include/dap_chain_node_cli_cmd.h @@ -144,3 +144,6 @@ int com_mempool_proc(int argc, char ** argv, char ** a_str_reply); * Place public CA into the mempool */ int com_mempool_add_ca( int a_argc, char ** a_argv, char ** a_str_reply); +int com_chain_ca_pub( int a_argc, char ** a_argv, char ** a_str_reply); +int com_chain_ca_copy( int a_argc, char ** a_argv, char ** a_str_reply); + diff --git a/modules/net/srv/CMakeLists.txt b/modules/net/srv/CMakeLists.txt index 25282398a7c21a93efeaa7679ba3afb0dcb5a976..b6661c7f1b94abb872d0e6f63babbdaa7a086a32 100644 --- a/modules/net/srv/CMakeLists.txt +++ b/modules/net/srv/CMakeLists.txt @@ -7,12 +7,17 @@ file(GLOB DAP_CHAIN_NET_SRV_HEADERS include/*.h libmaxminddb/*.h) add_library(${PROJECT_NAME} STATIC ${DAP_CHAIN_NET_SRV_SRCS} ${DAP_CHAIN_NET_SRV_HEADERS}) +set(NET_SRV_LIBS dap_chain_net_srv dap_core dap_crypto dap_chain dap_chain_net dap_chain_wallet) + if (CELLFRAME_MODULES MATCHES "modules-dynamic") - target_link_libraries(dap_chain_net_srv dap_core dap_crypto dap_chain dap_chain_net dap_chain_wallet dap_modules_dynamic_cdb) -else() - target_link_libraries(dap_chain_net_srv dap_core dap_crypto dap_chain dap_chain_net dap_chain_wallet) + set(NET_SRV_LIBS ${NET_SRV_LIBS} dap_modules_dynamic_cdb) endif() +#if (CELLFRAME_MODULES MATCHES "srv-stake") +# set(NET_SRV_LIBS ${NET_SRV_LIBS} dap_chain_net_srv_stake) +#endif() + +target_link_libraries(${NET_SRV_LIBS}) target_include_directories(dap_chain_net_srv INTERFACE .) target_include_directories(${PROJECT_NAME} PUBLIC include) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../3rdparty/uthash/src) diff --git a/modules/net/srv/dap_chain_net_srv_order.c b/modules/net/srv/dap_chain_net_srv_order.c index 63ca0b5b78a8139dc6d8254e8b706ded8ecdc4a4..56cdef9d0ebdbfaf3be0e9342f8573e6e9dfae25 100644 --- a/modules/net/srv/dap_chain_net_srv_order.c +++ b/modules/net/srv/dap_chain_net_srv_order.c @@ -30,12 +30,6 @@ #include "dap_enc_base58.h" #include "dap_chain_global_db.h" #include "dap_chain_net_srv_countries.h" -#if DAP_SRV_STAKE_USED -#include "dap_chain_net_srv_stake.h" -#else -static bool dap_chain_net_srv_stake_key_delegated(dap_chain_addr_t *a_addr) { UNUSED(a_addr); return false; } -#endif -//#include "dap_chain_net_srv_geoip.h" #define LOG_TAG "dap_chain_net_srv_order" @@ -544,7 +538,7 @@ static void s_srv_order_callback_notify(void *a_arg, const char a_op_code, const DAP_DELETE(l_gdb_group_str); return; } - dap_chain_hash_fast_t l_pkey_hash; + /*dap_chain_hash_fast_t l_pkey_hash; if (!dap_sign_get_pkey_hash(l_sign, &l_pkey_hash)) { dap_chain_global_db_gr_del(dap_strdup(a_key), a_group); DAP_DELETE(l_gdb_group_str); @@ -557,7 +551,7 @@ static void s_srv_order_callback_notify(void *a_arg, const char a_op_code, const uint64_t l_solvency = dap_chain_uint256_to(l_balance); if (l_solvency < l_order->price && !dap_chain_net_srv_stake_key_delegated(&l_addr)) { dap_chain_global_db_gr_del(dap_strdup(a_key), a_group); - } + }*/ } DAP_DELETE(l_gdb_group_str); } diff --git a/modules/service/stake/CMakeLists.txt b/modules/service/stake/CMakeLists.txt index e50be120ada65584254d16bd4a764594052e0722..e6217cf00995e909380b99444018ef70a5235501 100644 --- a/modules/service/stake/CMakeLists.txt +++ b/modules/service/stake/CMakeLists.txt @@ -9,4 +9,4 @@ add_library(${PROJECT_NAME} STATIC ${DAP_SRV_STAKE_SRCS} ${DAP_SRV_STAKE_HEADERS target_include_directories(dap_chain_crypto INTERFACE .) target_include_directories(${PROJECT_NAME} PUBLIC include) -target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_chain dap_chain_crypto dap_chain_net dap_chain_net_srv) +target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_chain dap_chain_crypto dap_chain_net dap_chain_net_srv dap_chain_cs_dag_poa dap_chain_cs_block_poa) diff --git a/modules/service/stake/dap_chain_net_srv_stake.c b/modules/service/stake/dap_chain_net_srv_stake.c index 31a05d446cc7980f4aff9c7f2121cf544d53f7e1..62f1e2522a39545a5ea08ddf00ad37c73f195e56 100644 --- a/modules/service/stake/dap_chain_net_srv_stake.c +++ b/modules/service/stake/dap_chain_net_srv_stake.c @@ -29,13 +29,15 @@ #include "dap_chain_common.h" #include "dap_chain_mempool.h" #include "dap_chain_net_srv_common.h" +#include "dap_chain_cs_block_poa.h" +#include "dap_chain_cs_dag_poa.h" #include "dap_chain_net_srv_stake.h" #define LOG_TAG "dap_chain_net_srv_stake" static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply); -static dap_chain_net_srv_stake_t *s_srv_stake; +static dap_chain_net_srv_stake_t *s_srv_stake = NULL; /** * @brief dap_stream_ch_vpn_init Init actions for VPN stream channel @@ -46,22 +48,27 @@ static dap_chain_net_srv_stake_t *s_srv_stake; int dap_chain_net_srv_stake_init() { dap_chain_node_cli_cmd_item_create("srv_stake", s_cli_srv_stake, "Delegated stake service commands", - "srv_stake order create -net <net name> -from_addr <addr> -token <ticker> -coins <value> -cert <name> -fee_percent <value>\n" - "\tCreate a new order with specified amount of datoshi to delegate it to the specified address." - "The fee with specified percent with this delagation will be returned to the fee address pointed by delegator\n" - "srv_stake order remove -net <net name> -order <order hash> [-H hex|base58(default)]\n" + "srv_stake order create -net <net name> -addr_hldr <addr> -token <ticker> -coins <value> -cert <name> -fee_percent <value>\n" + "\tCreate a new order with specified amount of datoshi to delegate specified cert from the specified address.\n" + "\tThe fee with specified percent with this delagation will be returned to the fee address pointed by delegator\n" + "srv_stake order declare -net <net name> -wallet <name> -token <ticker> -coins <value> -fee_percent <value>" + "\tCreate a new order with specified amount of datoshi and fee which holder is ready to stake.\n" + "srv_stake order remove -net <net name> -order <order hash> [-H <hex | base58(default)>]\n" "\tRemove order with specified hash\n" - "srv_stake order update -net <net name> -order <order hash> -cert <name> [-H hex|base58(default)]" - "{-from_addr <addr> | -token <ticker> -coins <value> | -fee_percent <value>}\n" + "srv_stake order update -net <net name> -order <order hash> {-cert <name> | -wallet <name>} [-H <hex | base58(default)>]" + "{[-addr_hldr <addr>] [-token <ticker>] [-coins <value>] [-fee_percent <value>] |" + " | [-token <ticker>] [-coins <value>] -fee_percent <value>]\n" "\tUpdate order with specified hash\n" "srv_stake order list -net <net name>\n" "\tGet the stake orders list within specified net name\n" - "srv_stake delegate -order <order hash> -net <net name> -wallet <wallet_name> -fee_addr <addr>\n" + "srv_stake delegate -order <order hash> -net <net name> -wallet <name> -fee_addr <addr>\n" "\tDelegate tokens with specified order within specified net name. Specify fee address\n" + "srv_stake approve -net <net name> -tx <transaction hash> -cert <root cert name>\n" + "\tApprove stake transaction by root node certificate within specified net name.\n" "srv_stake transactions -net <net name> {-addr <addr from>}\n" - "\tShow the list of active stake transactions (optional delegated from addr)\n" + "\tShow the list of requested, active and canceled stake transactions (optional delegated from addr)\n" "srv_stake invalidate -net <net name> -tx <transaction hash> -wallet <wallet name>\n" - "\tInvalidate stake transaction by hash within net name and return stake to specified wallet\n" + "\tInvalidate requested stake transaction by hash within net name and return stake to specified wallet\n" ); s_srv_stake = DAP_NEW_Z(dap_chain_net_srv_stake_t); uint16_t l_net_count; @@ -73,6 +80,16 @@ int dap_chain_net_srv_stake_init() dap_chain_tx_out_cond_t *l_out_cond; int l_out_cond_idx; char l_token[DAP_CHAIN_TICKER_SIZE_MAX]; + size_t l_auth_certs_count = 0; + dap_cert_t **l_auth_certs = NULL; + for (dap_chain_t *l_chain = l_net_list[i]->pub.chains; l_chain; l_chain = l_chain->next) { + l_auth_certs = dap_chain_cs_dag_poa_get_auth_certs(l_chain, &l_auth_certs_count); + if (l_auth_certs) + break; + l_auth_certs = dap_chain_cs_block_poa_get_auth_certs(l_chain, &l_auth_certs_count); + if (l_auth_certs) + break; + } // Find all stake transactions do { l_tx_tmp = dap_chain_ledger_tx_cache_find_out_cond(l_ledger, &l_tx_cur_hash, &l_out_cond, &l_out_cond_idx, l_token); @@ -83,24 +100,36 @@ int dap_chain_net_srv_stake_init() continue; if (dap_chain_ledger_tx_hash_is_used_out_item(l_ledger, &l_tx_cur_hash, l_out_cond_idx)) continue; + dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(l_tx_tmp, 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); + if (!l_sign) { + continue; + } // Create the stake item - dap_chain_net_srv_stake_item_t *l_stake = DAP_NEW_Z(dap_chain_net_srv_stake_item_t); + dap_chain_net_srv_stake_item_t *l_stake; + bool l_is_new = false; + HASH_FIND(hh, s_srv_stake->itemlist, &l_out_cond->params, sizeof(dap_chain_addr_t), l_stake); + if (!l_stake) { + l_stake = DAP_NEW_Z(dap_chain_net_srv_stake_item_t); + l_is_new = true; + } l_stake->net = l_net_list[i]; dap_stpcpy(l_stake->token, l_token); l_stake->value = l_out_cond->header.value; - dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(l_tx_tmp, 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); - dap_chain_hash_fast_t l_pkey_hash; - if (!dap_sign_get_pkey_hash(l_sign, &l_pkey_hash)) { - continue; + for (size_t i = 0; i < l_auth_certs_count; i++) { + if (!dap_cert_compare_with_sign(l_auth_certs[i], l_sign)) { + l_stake->is_active = true; + break; + } } - dap_chain_addr_fill(&l_stake->addr_from, l_sign->header.type, &l_pkey_hash, l_net_list[i]->pub.id); - memcpy(&l_stake->addr_to, l_out_cond->params, sizeof(dap_chain_addr_t)); + memcpy(&l_stake->signing_addr, &l_out_cond->params, sizeof(dap_chain_addr_t)); + memcpy(&l_stake->addr_hldr, &l_out_cond->subtype.srv_stake.hldr_addr, sizeof(dap_chain_addr_t)); memcpy(&l_stake->addr_fee, &l_out_cond->subtype.srv_stake.fee_addr, sizeof(dap_chain_addr_t)); l_stake->fee_value = l_out_cond->subtype.srv_stake.fee_value; memcpy(&l_stake->tx_hash, &l_tx_cur_hash, sizeof(dap_chain_hash_fast_t)); - HASH_ADD(hh, s_srv_stake->itemlist, tx_hash, sizeof(dap_chain_hash_fast_t), l_stake); + if (l_is_new) + HASH_ADD(hh, s_srv_stake->itemlist, signing_addr, sizeof(dap_chain_addr_t), l_stake); } while (l_tx_tmp); } DAP_DELETE(l_net_list); @@ -115,20 +144,106 @@ void dap_chain_net_srv_stake_deinit() HASH_DEL(s_srv_stake->itemlist, l_stake); DAP_DELETE(l_stake); } - DAP_DELETE(s_srv_stake); + DAP_DEL_Z(s_srv_stake); +} + +static void s_stake_update(dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx, bool a_authorized) +{ + dap_chain_net_srv_stake_item_t *l_stake; + if (a_cond) + HASH_FIND(hh, s_srv_stake->itemlist, &a_cond->params, sizeof(dap_chain_addr_t), l_stake); + else + l_stake = DAP_NEW_Z(dap_chain_net_srv_stake_item_t); + assert(l_stake); + dap_chain_tx_out_cond_t *l_out_cond = (dap_chain_tx_out_cond_t *)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_OUT_COND, NULL); + if (!l_out_cond || l_out_cond->header.subtype != DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE) { + // Stake tx is used out + HASH_DEL(s_srv_stake->itemlist, l_stake); + DAP_DELETE(l_stake); + return; + } + // Update stake parameters + if (!a_cond) { + // New stake transaction + memcpy(&l_stake->signing_addr, &l_out_cond->params, sizeof(dap_chain_addr_t)); + HASH_ADD(hh, s_srv_stake->itemlist, signing_addr, sizeof(dap_chain_addr_t), l_stake); + } else if (memcmp(&a_cond->params, &l_out_cond->params, sizeof(dap_chain_addr_t))) { + HASH_DEL(s_srv_stake->itemlist, l_stake); + dap_chain_net_srv_stake_item_t *l_stake_cur = NULL; + HASH_FIND(hh, s_srv_stake->itemlist, &l_out_cond->params, sizeof(dap_chain_addr_t), l_stake_cur); + if (l_stake_cur) { + DAP_DELETE(l_stake); + l_stake = l_stake_cur; + } + memcpy(&l_stake->signing_addr, &l_out_cond->params, sizeof(dap_chain_addr_t)); + if (l_stake_cur) + HASH_ADD(hh, s_srv_stake->itemlist, signing_addr, sizeof(dap_chain_addr_t), l_stake); + } + if (a_authorized) + l_stake->is_active = true; + memcpy(&l_stake->addr_hldr, &l_out_cond->subtype.srv_stake.hldr_addr, sizeof(dap_chain_addr_t)); + memcpy(&l_stake->addr_fee, &l_out_cond->subtype.srv_stake.fee_addr, sizeof(dap_chain_addr_t)); + l_stake->fee_value = l_out_cond->subtype.srv_stake.fee_value; + dap_hash_fast(a_tx, dap_chain_datum_tx_get_size(a_tx), &l_stake->tx_hash); } -bool dap_chain_net_srv_stake_verificator(dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx) +static bool s_stake_conditions_calc(dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx, bool a_owner, bool a_update) { - UNUSED(a_cond); - UNUSED(a_tx); + dap_chain_tx_out_cond_t *l_out_cond = NULL; + if (!a_cond) { + // New stake tx + l_out_cond = (dap_chain_tx_out_cond_t *)dap_chain_datum_tx_item_get(a_tx, NULL, TX_ITEM_TYPE_OUT_COND, NULL); + } else + l_out_cond = a_cond; + dap_chain_net_id_t l_cur_net_id = l_out_cond->subtype.srv_stake.hldr_addr.net_id; + dap_chain_net_t *l_net = dap_chain_net_by_id(l_cur_net_id); + if (!l_net) + return false; + size_t l_auth_certs_count = 0; + dap_cert_t **l_auth_certs = NULL; + for (dap_chain_t *l_chain = l_net->pub.chains; l_chain; l_chain = l_chain->next) { + l_auth_certs = dap_chain_cs_dag_poa_get_auth_certs(l_chain, &l_auth_certs_count); + if (l_auth_certs) + break; + l_auth_certs = dap_chain_cs_block_poa_get_auth_certs(l_chain, &l_auth_certs_count); + if (l_auth_certs) + break; + } + if (!l_auth_certs || !l_auth_certs_count) // Can't validate stake tx authority for this net + return false; + 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); + if (!l_sign) + return false; + for (size_t i = 0; i < l_auth_certs_count; i++) { + if (!dap_cert_compare_with_sign(l_auth_certs[i], l_sign)) { + if (a_update) + s_stake_update(a_cond, a_tx, true); + return true; + } + } + if (a_owner) { + if (a_update) + s_stake_update(a_cond, a_tx, false); + return true; + } return false; } +bool dap_chain_net_srv_stake_verificator(dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx, bool a_owner) +{ + return s_stake_conditions_calc(a_cond, a_tx, a_owner, false); +} + +bool dap_chain_net_srv_stake_updater(dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx, bool a_owner) +{ + return s_stake_conditions_calc(a_cond, a_tx, a_owner, true); +} + bool dap_chain_net_srv_stake_key_delegated(dap_chain_addr_t *a_addr) { if (!s_srv_stake) { - return true; + return false; } while (!s_srv_stake->initialized); @@ -137,35 +252,38 @@ bool dap_chain_net_srv_stake_key_delegated(dap_chain_addr_t *a_addr) } dap_chain_net_srv_stake_item_t *l_stake = NULL; HASH_FIND(hh, s_srv_stake->itemlist, a_addr, sizeof(dap_chain_addr_t), l_stake); - if (l_stake) { // public key delegated for this network + if (l_stake && l_stake->is_active) { // public key delegated for this network return true; } return false; } -bool dap_chain_net_srv_stake_validator(dap_chain_addr_t *a_addr, dap_chain_datum_tx_t *a_tx) +bool dap_chain_net_srv_stake_validator(dap_chain_addr_t *a_addr, dap_chain_datum_t *a_datum) { - if (!s_srv_stake) { - return true; + if (!s_srv_stake) { // Drop all atoms if stake service inactivated + return false; } while (!s_srv_stake->initialized); - if (!a_addr || !a_tx) { + if (!a_addr || !a_datum) { return false; } dap_chain_net_srv_stake_item_t *l_stake = NULL; HASH_FIND(hh, s_srv_stake->itemlist, a_addr, sizeof(dap_chain_addr_t), l_stake); - if (l_stake == NULL) { // public key not delegated for this network - return true; + if (!l_stake || !l_stake->is_active) { // public key not delegated for this network + return false; } - 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); + if (a_datum->header.type_id != DAP_CHAIN_DATUM_TX) + return true; + dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)a_datum->data; + dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(l_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); dap_chain_hash_fast_t l_pkey_hash = {}; dap_sign_get_pkey_hash(l_sign, &l_pkey_hash); dap_chain_addr_t l_owner_addr = {}; dap_chain_addr_fill(&l_owner_addr, l_sign->header.type, &l_pkey_hash, a_addr->net_id); uint64_t l_outs_sum = 0, l_fee_sum = 0; - dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_OUT_ALL, NULL); + dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_OUT_ALL, NULL); uint32_t l_out_idx_tmp = 0; // current index of 'out' item for (dap_list_t *l_list_tmp = l_list_out_items; l_list_tmp; l_list_tmp = dap_list_next(l_list_tmp), l_out_idx_tmp++) { dap_chain_tx_item_type_t l_type = *(uint8_t *)l_list_tmp->data; @@ -195,7 +313,7 @@ bool dap_chain_net_srv_stake_validator(dap_chain_addr_t *a_addr, dap_chain_datum static dap_chain_datum_tx_t *s_stake_tx_create(dap_chain_net_srv_stake_item_t *a_stake, dap_chain_wallet_t *a_wallet) { - if (!a_stake || !a_stake->net || !a_stake->addr_to.addr_ver || !a_stake->addr_from.addr_ver || + if (!a_stake || !a_stake->net || !a_stake->signing_addr.addr_ver || !a_stake->addr_hldr.addr_ver || !a_stake->addr_fee.addr_ver || !*a_stake->token || !a_wallet) { return NULL; } @@ -205,7 +323,7 @@ static dap_chain_datum_tx_t *s_stake_tx_create(dap_chain_net_srv_stake_item_t *a dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(a_stake->net->pub.name); dap_chain_addr_t *l_owner_addr = (dap_chain_addr_t *)dap_chain_wallet_get_addr(a_wallet, a_stake->net->pub.id); - if (memcmp(l_owner_addr, &a_stake->addr_from, sizeof(dap_chain_addr_t))) { + if (memcmp(l_owner_addr, &a_stake->addr_hldr, sizeof(dap_chain_addr_t))) { log_it(L_WARNING, "Odrer and wallet address do not match"); return NULL; } @@ -233,8 +351,9 @@ static dap_chain_datum_tx_t *s_stake_tx_create(dap_chain_net_srv_stake_item_t *a // add 'out_cond' & 'out' items { dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_STAKE_ID }; - dap_chain_tx_out_cond_t *l_tx_out = dap_chain_datum_tx_item_out_cond_create_srv_stake(l_uid, a_stake->value, a_stake->fee_value, &a_stake->addr_fee, - (void *)&a_stake->addr_to, sizeof(dap_chain_addr_t)); + dap_chain_tx_out_cond_t *l_tx_out = dap_chain_datum_tx_item_out_cond_create_srv_stake(l_uid, a_stake->value, a_stake->fee_value, + &a_stake->addr_fee, &a_stake->addr_hldr, + (void *)&a_stake->signing_addr, sizeof(dap_chain_addr_t)); if (!l_tx_out) { dap_chain_datum_tx_delete(l_tx); DAP_DELETE(l_owner_addr); @@ -285,6 +404,59 @@ static bool s_stake_tx_put(dap_chain_datum_tx_t *a_tx, dap_chain_net_t *a_net) return true; } +static dap_chain_datum_tx_t *s_stake_tx_approve(dap_chain_net_srv_stake_item_t *a_stake, dap_cert_t *a_cert) +{ + // create empty transaction + dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create(); + + dap_ledger_t *l_ledger = dap_chain_ledger_by_net_name(a_stake->net->pub.name); + + // create and add reciept + dap_chain_net_srv_price_unit_uid_t l_unit = { .uint32 = SERV_UNIT_UNDEFINED}; + dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_STAKE_ID }; + dap_chain_datum_tx_receipt_t *l_receipt = dap_chain_datum_tx_receipt_create(l_uid, l_unit, 0, a_stake->value, NULL, 0); + dap_chain_datum_tx_add_item(&l_tx, (byte_t *)l_receipt); + DAP_DELETE(l_receipt); + + // add 'in' item to buy from conditional transaction + dap_chain_datum_tx_t *l_cond_tx = dap_chain_ledger_tx_find_by_hash(l_ledger, &a_stake->tx_hash); + if (!l_cond_tx) { + log_it(L_WARNING, "Requested conditional transaction not found"); + return NULL; + } + int l_prev_cond_idx; + dap_chain_tx_out_cond_t *l_tx_out_cond = dap_chain_datum_tx_out_cond_get(l_cond_tx, &l_prev_cond_idx); + if (dap_chain_ledger_tx_hash_is_used_out_item(l_ledger, &a_stake->tx_hash, l_prev_cond_idx)) { + log_it(L_WARNING, "Requested conditional transaction is already used out"); + return NULL; + } + assert(l_tx_out_cond->header.value == a_stake->value); + dap_chain_datum_tx_add_in_cond_item(&l_tx, &a_stake->tx_hash, l_prev_cond_idx, 0); + + // add 'out_cond' item + { + dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_STAKE_ID }; + dap_chain_tx_out_cond_t *l_tx_out = dap_chain_datum_tx_item_out_cond_create_srv_stake(l_uid, a_stake->value, a_stake->fee_value, + &a_stake->addr_fee, &a_stake->addr_hldr, + (void *)&a_stake->signing_addr, sizeof(dap_chain_addr_t)); + if (!l_tx_out) { + dap_chain_datum_tx_delete(l_tx); + log_it(L_ERROR, "Can't compose the transaction conditional output"); + return NULL; + } + dap_chain_datum_tx_add_item(&l_tx, (const uint8_t *)l_tx_out); + DAP_DELETE(l_tx_out); + } + + // add 'sign' items + if(dap_chain_datum_tx_add_sign_item(&l_tx, a_cert->enc_key) != 1) { + dap_chain_datum_tx_delete(l_tx); + log_it( L_ERROR, "Can't add sign output"); + return NULL; + } + return l_tx; +} + static bool s_stake_tx_invalidate(dap_chain_net_srv_stake_item_t *a_stake, dap_chain_wallet_t *a_wallet) { // create empty transaction @@ -339,15 +511,20 @@ static bool s_stake_tx_invalidate(dap_chain_net_srv_stake_item_t *a_stake, dap_c char *s_stake_order_create(dap_chain_net_srv_stake_item_t *a_item, dap_enc_key_t *l_key) { dap_chain_hash_fast_t l_tx_hash = {}; - dap_srv_stake_order_ext_t l_ext; - memcpy(&l_ext.addr_from, &a_item->addr_from, sizeof(dap_chain_addr_t)); - memcpy(&l_ext.addr_to, &a_item->addr_to, sizeof(dap_chain_addr_t)); + dap_srv_stake_order_ext_t l_ext = {}; + memcpy(&l_ext.addr_hldr, &a_item->addr_hldr, sizeof(dap_chain_addr_t)); + dap_chain_net_srv_order_direction_t l_dir = SERV_DIR_SELL; + if (memcmp(&a_item->signing_addr, &l_ext.signing_addr, sizeof(dap_chain_addr_t))) { + // Signing addr is not empty + l_dir = SERV_DIR_BUY; + memcpy(&l_ext.signing_addr, &a_item->signing_addr, sizeof(dap_chain_addr_t)); + } l_ext.fee_value = a_item->fee_value; uint32_t l_ext_size = sizeof(dap_srv_stake_order_ext_t); dap_chain_node_addr_t *l_node_addr = dap_chain_net_get_cur_addr(a_item->net); dap_chain_net_srv_price_unit_uid_t l_unit = { .uint32 = SERV_UNIT_UNDEFINED}; dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_STAKE_ID }; - char *l_order_hash_str = dap_chain_net_srv_order_create(a_item->net, SERV_DIR_BUY, l_uid, *l_node_addr, + char *l_order_hash_str = dap_chain_net_srv_order_create(a_item->net, l_dir, l_uid, *l_node_addr, l_tx_hash, a_item->value, l_unit, a_item->token, 0, (uint8_t *)&l_ext, l_ext_size, NULL, 0, l_key); return l_order_hash_str; @@ -370,12 +547,12 @@ dap_chain_net_srv_stake_item_t *s_stake_item_from_order(dap_chain_net_t *a_net, dap_chain_addr_t l_cert_addr; dap_chain_addr_fill(&l_cert_addr, l_sign->header.type, &l_pkey_hash, a_net->pub.id); dap_chain_net_srv_stake_item_t *l_item = DAP_NEW_Z(dap_chain_net_srv_stake_item_t); - if (memcmp(&l_cert_addr, &l_ext->addr_to, sizeof(dap_chain_addr_t))) { - log_it(L_WARNING, "Order sign addr & addr_to are different"); + if (memcmp(&l_cert_addr, &l_ext->signing_addr, sizeof(dap_chain_addr_t))) { + log_it(L_WARNING, "Order sign addr & signing_addr are different"); return NULL; } - memcpy(&l_item->addr_from, &l_ext->addr_from, sizeof(dap_chain_addr_t)); - memcpy(&l_item->addr_to, &l_ext->addr_to, sizeof(dap_chain_addr_t)); + memcpy(&l_item->addr_hldr, &l_ext->addr_hldr, sizeof(dap_chain_addr_t)); + memcpy(&l_item->signing_addr, &l_ext->signing_addr, sizeof(dap_chain_addr_t)); l_item->fee_value = l_ext->fee_value; l_item->net = a_net; l_item->value = a_order->price; @@ -386,7 +563,7 @@ dap_chain_net_srv_stake_item_t *s_stake_item_from_order(dap_chain_net_t *a_net, static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, char **a_str_reply, const char *a_hash_out_type) { enum { - CMD_NONE, CMD_CREATE, CMD_REMOVE, CMD_LIST, CMD_UPDATE + CMD_NONE, CMD_CREATE, CMD_DECLARE, CMD_REMOVE, CMD_LIST, CMD_UPDATE }; int l_cmd_num = CMD_NONE; if(dap_chain_node_cli_find_option_val(a_argv, a_arg_index, min(a_argc, a_arg_index + 1), "create", NULL)) { @@ -405,7 +582,7 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, cha switch (l_cmd_num) { case CMD_CREATE: { const char *l_net_str = NULL, *l_token_str = NULL, *l_coins_str = NULL; - const char *l_addr_from_str = NULL, *l_cert_str = NULL, *l_fee_str = NULL; + const char *l_addr_hldr_str = NULL, *l_cert_str = NULL, *l_fee_str = NULL; dap_chain_net_t *l_net = NULL; dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str); if (!l_net_str) { @@ -431,18 +608,18 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, cha dap_chain_node_cli_set_reply_text(a_str_reply, "Command 'order create' required parameter -coins"); return -7; } - uint64_t l_value = strtoull(l_coins_str, NULL, 10); + uint64_t l_value = strtoull(l_coins_str, NULL, 10); // TODO add possibility to work with 256-bit format if (!l_value) { dap_chain_node_cli_set_reply_text(a_str_reply, "Format -coins <unsigned long long>"); return -8; } - dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-addr_from", &l_addr_from_str); - if (!l_addr_from_str) { - dap_chain_node_cli_set_reply_text(a_str_reply, "Command 'order create' required parameter -addr_from"); + dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-addr_hldr", &l_addr_hldr_str); + if (!l_addr_hldr_str) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Command 'order create' required parameter -addr_hldr"); return -9; } - dap_chain_addr_t *l_addr_from = dap_chain_addr_from_str(l_addr_from_str); - if (!l_addr_from) { + dap_chain_addr_t *l_addr_hldr = dap_chain_addr_from_str(l_addr_hldr_str); + if (!l_addr_hldr) { dap_chain_node_cli_set_reply_text(a_str_reply, "Wrong address format"); return -10; } @@ -463,7 +640,7 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, cha } long double l_fee = strtold(l_fee_str, NULL); if (!l_fee) { - dap_chain_node_cli_set_reply_text(a_str_reply, "Format -fee_percent <long double> %"); + dap_chain_node_cli_set_reply_text(a_str_reply, "Format -fee_percent <long double>(%)"); return -12; } // Create the stake item @@ -471,11 +648,11 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, cha l_stake->net = l_net; dap_stpcpy(l_stake->token, l_token_str); l_stake->value = l_value; - memcpy(&l_stake->addr_from, l_addr_from, sizeof(dap_chain_addr_t)); - dap_chain_addr_t *l_addr_to = dap_cert_to_addr(l_cert, l_net->pub.id); - memcpy(&l_stake->addr_to, l_addr_to, sizeof(dap_chain_addr_t)); - DAP_DELETE(l_addr_from); - DAP_DELETE(l_addr_to); + memcpy(&l_stake->addr_hldr, l_addr_hldr, sizeof(dap_chain_addr_t)); + dap_chain_addr_t *l_signing_addr = dap_cert_to_addr(l_cert, l_net->pub.id); + memcpy(&l_stake->signing_addr, l_signing_addr, sizeof(dap_chain_addr_t)); + DAP_DELETE(l_addr_hldr); + DAP_DELETE(l_signing_addr); l_stake->fee_value = l_fee; // Create the order & put it to GDB char *l_order_hash_str = s_stake_order_create(l_stake, l_cert->enc_key); @@ -489,6 +666,85 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, cha return -15; } } break; + case CMD_DECLARE: { + const char *l_net_str = NULL, *l_token_str = NULL, *l_coins_str = NULL; + const char *l_wallet_str = NULL, *l_fee_str = NULL; + dap_chain_net_t *l_net = NULL; + dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str); + if (!l_net_str) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Command 'order declare' required parameter -net"); + return -3; + } + l_net = dap_chain_net_by_name(l_net_str); + if (!l_net) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Network %s not found", l_net_str); + return -4; + } + dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-token", &l_token_str); + if (!l_token_str) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Command 'order declare' required parameter -token"); + return -5; + } + if (!dap_chain_ledger_token_ticker_check(l_net->pub.ledger, l_token_str)) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Token ticker %s not found", l_token_str); + return -6; + } + dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-coins", &l_coins_str); + if (!l_coins_str) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Command 'order declare' required parameter -coins"); + return -7; + } + uint64_t l_value = strtoull(l_coins_str, NULL, 10); // TODO add possibility to work with 256-bit format + if (!l_value) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Format -coins <unsigned long long>"); + return -8; + } + dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-wallet", &l_wallet_str); + if (!l_wallet_str) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Command 'order declare' required parameter -wallet"); + return -9; + } + dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_str, dap_chain_wallet_get_path(g_config)); + if (!l_wallet) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Specified wallet not found"); + return -18; + } + dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-fee_percent", &l_fee_str); + if (!l_fee_str) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Command 'order declare' required parameter -fee_percent"); + return -11; + } + long double l_fee = strtold(l_fee_str, NULL); + if (!l_fee) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Format -fee_percent <long double>(%)"); + return -12; + } + uint64_t l_balance = dap_chain_uint256_to(dap_chain_wallet_get_balance(l_wallet, l_net->pub.id, l_token_str)); + if (l_balance < l_value) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Insufficient coins for token %s in wallet '%s'", l_token_str, l_wallet_str); + return -13; + } + // Create the stake item + dap_chain_net_srv_stake_item_t *l_stake = DAP_NEW_Z(dap_chain_net_srv_stake_item_t); + l_stake->net = l_net; + dap_stpcpy(l_stake->token, l_token_str); + l_stake->value = l_value; + dap_chain_addr_t *l_addr_hldr = dap_chain_wallet_get_addr(l_wallet, l_net->pub.id); + memcpy(&l_stake->addr_hldr, l_addr_hldr, sizeof(dap_chain_addr_t)); + DAP_DELETE(l_addr_hldr); + l_stake->fee_value = l_fee; + // Create the order & put it to GDB + char *l_order_hash_str = s_stake_order_create(l_stake, dap_chain_wallet_get_key(l_wallet, 0)); + if (l_order_hash_str) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Successfully created order %s", l_order_hash_str); + DAP_DELETE(l_order_hash_str); + DAP_DELETE(l_stake); + } else { + dap_chain_node_cli_set_reply_text(a_str_reply, "Can't compose the order"); + DAP_DELETE(l_stake); + return -15; + } + } break; case CMD_REMOVE: { const char *l_net_str = NULL, *l_order_hash_str = NULL; dap_chain_net_t *l_net = NULL; @@ -531,9 +787,10 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, cha } break; case CMD_UPDATE: { const char *l_net_str = NULL, *l_token_str = NULL, *l_coins_str = NULL; - const char *l_addr_from_str = NULL, *l_cert_str = NULL, *l_fee_str = NULL; - char *l_order_hash_str = NULL; + const char *l_addr_hldr_str = NULL, *l_cert_str = NULL, *l_fee_str = NULL; + const char *l_order_hash_str = NULL, *l_wallet_str = NULL; dap_chain_net_t *l_net = NULL; + dap_enc_key_t *l_key = NULL; dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str); if (!l_net_str) { dap_chain_node_cli_set_reply_text(a_str_reply, "Command 'order update' required parameter -net"); @@ -569,16 +826,6 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, cha dap_chain_node_cli_set_reply_text(a_str_reply, "Can't find order %s\n", l_order_hash_base58_str); return -14; } - dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-wallet", &l_cert_str); - if (!l_cert_str) { - dap_chain_node_cli_set_reply_text(a_str_reply, "Command 'order update' required parameter -cert"); - return -9; - } - dap_cert_t *l_cert = dap_cert_find_by_name(l_cert_str); - if (!l_cert) { - dap_chain_node_cli_set_reply_text(a_str_reply, "Can't load cert %s", l_cert_str); - return -10; - } dap_chain_net_srv_stake_item_t *l_stake = s_stake_item_from_order(l_net, l_order); dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-token", &l_token_str); if (l_token_str) { @@ -591,7 +838,7 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, cha } dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-coins", &l_coins_str); if (l_coins_str) { - uint64_t l_value = strtoull(l_coins_str, NULL, 10); + uint64_t l_value = strtoull(l_coins_str, NULL, 10); // TODO add possibility to work with 256-bit format if (!l_value) { dap_chain_node_cli_set_reply_text(a_str_reply, "Format -coins <unsigned long long>"); DAP_DELETE(l_stake); @@ -608,19 +855,60 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, cha return -12; } } - if (!l_token_str && !l_coins_str && !l_addr_from_str && !l_fee_str) { + dap_chain_addr_t l_empty_addr = {}; + if (memcmp(&l_stake->signing_addr, &l_empty_addr, sizeof(dap_chain_addr_t))) { + // It's a buying order + dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-cert", &l_cert_str); + if (!l_cert_str) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Command 'order update' requires parameter -cert for buying orders"); + return -9; + } + dap_cert_t *l_cert = dap_cert_find_by_name(l_cert_str); + if (!l_cert) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Can't load cert %s", l_cert_str); + DAP_DELETE(l_stake); + return -10; + } + l_key = l_cert->enc_key; + dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-addr_hldr", &l_addr_hldr_str); + if (l_addr_hldr_str) { + dap_chain_addr_t *l_addr_hldr = dap_chain_addr_from_str(l_addr_hldr_str); + if (!l_addr_hldr) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Wrong address format"); + DAP_DELETE(l_stake); + return -14; + } + memcpy(&l_stake->addr_hldr, l_addr_hldr, sizeof(dap_chain_addr_t)); + DAP_DELETE(l_addr_hldr); + } + } else { // It's a selling order + dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-wallet", &l_wallet_str); + if (!l_wallet_str) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Command 'order update' requires parameter -wallet for selling orders"); + return -7; + } + dap_chain_wallet_t *l_wallet = dap_chain_wallet_open(l_wallet_str, dap_chain_wallet_get_path(g_config)); + if (!l_wallet) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Specified wallet not found"); + return -18; + } + uint64_t l_balance = dap_chain_uint256_to(dap_chain_wallet_get_balance(l_wallet, l_net->pub.id, l_stake->token)); + if (l_balance < l_stake->value) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Insufficient coins for token %s in wallet '%s'", l_token_str, l_wallet_str); + return -11; + } + l_key = dap_chain_wallet_get_key(l_wallet, 0); + } + if (!l_token_str && !l_coins_str && !l_addr_hldr_str && !l_fee_str) { dap_chain_node_cli_set_reply_text(a_str_reply, "At least one of updating parameters is mandatory"); DAP_DELETE(l_stake); return -16; } - dap_chain_addr_t *l_addr_to = dap_cert_to_addr(l_cert, l_net->pub.id); - memcpy(&l_stake->addr_to, l_addr_to, sizeof(dap_chain_addr_t)); - DAP_DELETE(l_addr_to); // Create the order & put it to GDB dap_chain_net_srv_order_delete_by_hash_str(l_net, l_order_hash_hex_str); DAP_DELETE(l_order_hash_hex_str); DAP_DELETE(l_order_hash_base58_str); - l_order_hash_hex_str = s_stake_order_create(l_stake, l_cert->enc_key); + l_order_hash_hex_str = s_stake_order_create(l_stake, l_key); if(l_order_hash_hex_str) { if(!dap_strcmp(a_hash_out_type, "hex")) { dap_chain_node_cli_set_reply_text(a_str_reply, "Successfully created order %s", l_order_hash_hex_str); @@ -662,7 +950,7 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, cha continue; // TODO add filters to list (token, address, etc.) l_stake = s_stake_item_from_order(l_net, l_order); - char *l_addr = dap_chain_addr_to_str(&l_stake->addr_to); + char *l_addr = dap_chain_addr_to_str(&l_stake->signing_addr); dap_string_append_printf(l_reply_str, "%s %"DAP_UINT64_FORMAT_U" %s %s %Lf\n", l_orders[i].key, l_stake->value, l_stake->token, l_addr, l_stake->fee_value); DAP_DELETE(l_addr); @@ -686,19 +974,18 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, cha static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply) { enum { - CMD_NONE, CMD_ORDER, CMD_DELEGATE, CMD_TX, CMD_INVALIDATE + CMD_NONE, CMD_ORDER, CMD_DELEGATE, CMD_APPROVE, CMD_TX, CMD_INVALIDATE }; int l_arg_index = 1; const char * l_hash_out_type = NULL; dap_chain_node_cli_find_option_val(a_argv, l_arg_index, min(a_argc, l_arg_index + 1), "-H", &l_hash_out_type); 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")) { + l_hash_out_type = "base58"; + if(dap_strcmp(l_hash_out_type," hex") && dap_strcmp(l_hash_out_type, "base58")) { dap_chain_node_cli_set_reply_text(a_str_reply, "invalid parameter -H, valid values: -H <hex | base58>"); return -1; } - int l_cmd_num = CMD_NONE; if (dap_chain_node_cli_find_option_val(a_argv, l_arg_index, min(a_argc, l_arg_index + 1), "order", NULL)) { l_cmd_num = CMD_ORDER; @@ -706,6 +993,9 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply) else if (dap_chain_node_cli_find_option_val(a_argv, l_arg_index, min(a_argc, l_arg_index + 1), "delegate", NULL)) { l_cmd_num = CMD_DELEGATE; } + else if (dap_chain_node_cli_find_option_val(a_argv, l_arg_index, min(a_argc, l_arg_index + 1), "approve", NULL)) { + l_cmd_num = CMD_APPROVE; + } else if (dap_chain_node_cli_find_option_val(a_argv, l_arg_index, min(a_argc, l_arg_index + 1), "transactions", NULL)) { l_cmd_num = CMD_TX; } @@ -764,15 +1054,16 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply) } memcpy(&l_stake->addr_fee, l_addr_fee, sizeof(dap_chain_addr_t)); DAP_DELETE(l_addr_fee); + dap_chain_addr_t *l_hldr_addr = dap_chain_wallet_get_addr(l_wallet, l_net->pub.id); + memcpy(&l_stake->addr_hldr, l_hldr_addr, sizeof(dap_chain_addr_t)); + DAP_DELETE(l_hldr_addr); // Create conditional transaction dap_chain_datum_tx_t *l_tx = s_stake_tx_create(l_stake, l_wallet); dap_chain_wallet_close(l_wallet); - if (l_tx) { - dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_stake->tx_hash); - if (s_stake_tx_put(l_tx, l_net)) { - // TODO send request to order owner to delete it - dap_chain_net_srv_order_delete_by_hash_str(l_net, l_order_hash_str); - } + if (l_tx && s_stake_tx_put(l_tx, l_net)) { + dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_stake->tx_hash); + // TODO send request to order owner to delete it + dap_chain_net_srv_order_delete_by_hash_str(l_net, l_order_hash_str); } DAP_DELETE(l_order); dap_chain_node_cli_set_reply_text(a_str_reply, l_tx ? "Stake transaction has done" : @@ -781,13 +1072,65 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply) DAP_DELETE(l_stake); return -19; } - HASH_ADD(hh, s_srv_stake->itemlist, addr_to, sizeof(dap_chain_addr_t), l_stake); + HASH_ADD(hh, s_srv_stake->itemlist, signing_addr, sizeof(dap_chain_addr_t), l_stake); } else { DAP_DELETE(l_addr_fee); dap_chain_node_cli_set_reply_text(a_str_reply, "Specified order not found"); return -14; } } break; + case CMD_APPROVE: { + const char *l_net_str = NULL, *l_tx_hash_str = NULL, *l_cert_str = NULL; + l_arg_index++; + dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str); + if (!l_net_str) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Command 'approve' required parameter -net"); + return -3; + } + dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str); + if (!l_net) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Network %s not found", l_net_str); + return -4; + } + dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-cert", &l_cert_str); + if (!l_cert_str) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Command 'approve' required parameter -cert"); + return -17; + } + dap_cert_t *l_cert = dap_cert_find_by_name(l_cert_str); + if (!l_cert) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Specified certificate not found"); + return -18; + } + dap_chain_node_cli_find_option_val(a_argv, l_arg_index, a_argc, "-tx", &l_tx_hash_str); + if (!l_tx_hash_str) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Command 'delegate' required parameter -tx"); + return -13; + } + dap_chain_hash_fast_t l_tx_hash = {}; + int l_result = dap_chain_hash_fast_from_str(l_tx_hash_str, &l_tx_hash); + if (l_result) + l_result = dap_enc_base58_decode(l_tx_hash_str, &l_tx_hash) - sizeof(dap_chain_hash_fast_t); + if (l_result) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Invalid transaction hash format"); + return -14; + } + dap_chain_net_srv_stake_item_t *l_stake = NULL, *l_tmp; + HASH_ITER(hh, s_srv_stake->itemlist, l_stake, l_tmp) { + if (!memcmp(&l_stake->tx_hash, &l_tx_hash, sizeof(dap_chain_hash_fast_t))) { + break; + } + } + if (!l_stake) { + dap_chain_node_cli_set_reply_text(a_str_reply, "Transaction %s not found", l_tx_hash_str); + return -20; + } + dap_chain_datum_tx_t *l_tx = s_stake_tx_approve(l_stake, l_cert); + if (l_tx && s_stake_tx_put(l_tx, l_net)) { + dap_hash_fast(l_tx, dap_chain_datum_tx_get_size(l_tx), &l_stake->tx_hash); + l_stake->is_active = true; + } + } break; case CMD_TX: { const char *l_net_str = NULL; l_arg_index++; @@ -808,15 +1151,15 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, char **a_str_reply) continue; } char *l_tx_hash_str = dap_chain_hash_fast_to_str_new(&l_stake->tx_hash); - char *l_addr_from_str = dap_chain_addr_to_str(&l_stake->addr_from); - char *l_addr_to_str = dap_chain_addr_to_str(&l_stake->addr_to); + char *l_addr_hldr_str = dap_chain_addr_to_str(&l_stake->addr_hldr); + char *l_signing_addr_str = dap_chain_addr_to_str(&l_stake->signing_addr); char *l_addr_fee_str = dap_chain_addr_to_str(&l_stake->addr_fee); dap_string_append_printf(l_reply_str, "%s %s %"DAP_UINT64_FORMAT_U" %s %s %s %Lf\n", l_tx_hash_str, l_stake->token, - l_stake->value, l_addr_from_str, l_addr_to_str, + l_stake->value, l_addr_hldr_str, l_signing_addr_str, l_addr_fee_str, l_stake->fee_value); DAP_DELETE(l_tx_hash_str); - DAP_DELETE(l_addr_from_str); - DAP_DELETE(l_addr_to_str); + DAP_DELETE(l_addr_hldr_str); + DAP_DELETE(l_signing_addr_str); DAP_DELETE(l_addr_fee_str); } if (!l_reply_str->len) { diff --git a/modules/service/stake/include/dap_chain_net_srv_stake.h b/modules/service/stake/include/dap_chain_net_srv_stake.h index 4a89391531b1a3fa7881344ba2ce6fc53f405750..c539cee32af31515178a85a6355857e404ee3e55 100644 --- a/modules/service/stake/include/dap_chain_net_srv_stake.h +++ b/modules/service/stake/include/dap_chain_net_srv_stake.h @@ -27,15 +27,16 @@ #include "dap_chain_net_srv.h" #include "dap_chain_net_srv_order.h" -#define DAP_CHAIN_NET_SRV_STAKE_ID 0x3 +#define DAP_CHAIN_NET_SRV_STAKE_ID 0x13 typedef struct dap_chain_net_srv_stake_item { + bool is_active; dap_chain_net_t *net; char token[DAP_CHAIN_TICKER_SIZE_MAX]; uint64_t value; - dap_chain_addr_t addr_from; - dap_chain_addr_t addr_to; + dap_chain_addr_t addr_hldr; dap_chain_addr_t addr_fee; + dap_chain_addr_t signing_addr; long double fee_value; dap_chain_hash_fast_t tx_hash; dap_chain_hash_fast_t order_hash; @@ -43,8 +44,8 @@ typedef struct dap_chain_net_srv_stake_item { } dap_chain_net_srv_stake_item_t; typedef struct dap_srv_stake_order_ext { - dap_chain_addr_t addr_from; - dap_chain_addr_t addr_to; + dap_chain_addr_t addr_hldr; + dap_chain_addr_t signing_addr; long double fee_value; } dap_srv_stake_order_ext_t; @@ -55,6 +56,7 @@ typedef struct dap_chain_net_srv_stake { int dap_chain_net_srv_stake_init(); void dap_chain_net_srv_stake_deinit(); -bool dap_chain_net_srv_stake_verificator(dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx); -bool dap_chain_net_srv_stake_validator(dap_chain_addr_t *a_addr, dap_chain_datum_tx_t *a_tx); +bool dap_chain_net_srv_stake_verificator(dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx, bool a_owner); +bool dap_chain_net_srv_stake_updater(dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx, bool a_owner); +bool dap_chain_net_srv_stake_validator(dap_chain_addr_t *a_addr, dap_chain_datum_t *a_datum); bool dap_chain_net_srv_stake_key_delegated(dap_chain_addr_t *a_addr); diff --git a/modules/service/xchange/dap_chain_net_srv_xchange.c b/modules/service/xchange/dap_chain_net_srv_xchange.c index 6f6154136eb8e49461bc94eb68563ce1c820c741..e38168e51a839f904d87819a86c4899d8bc28dff 100644 --- a/modules/service/xchange/dap_chain_net_srv_xchange.c +++ b/modules/service/xchange/dap_chain_net_srv_xchange.c @@ -101,8 +101,10 @@ void dap_chain_net_srv_xchange_deinit() DAP_DELETE(s_srv_xchange); } -bool dap_chain_net_srv_xchange_verificator(dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx) +bool dap_chain_net_srv_xchange_verificator(dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx, bool a_owner) { + if (a_owner) + return true; /* Check the condition for verification success * a_cond.srv_xchange.rate >= a_tx.out.rate */ 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 f59791fea9c51326e5026278a59de60c0de0078a..0e098f7c67445ac7dfcca10a0ef964fc24feb3e8 100644 --- a/modules/service/xchange/include/dap_chain_net_srv_xchange.h +++ b/modules/service/xchange/include/dap_chain_net_srv_xchange.h @@ -71,4 +71,4 @@ typedef struct dap_chain_net_srv_xchange { int dap_chain_net_srv_xchange_init(); void dap_chain_net_srv_xchange_deinit(); -bool dap_chain_net_srv_xchange_verificator(dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx); +bool dap_chain_net_srv_xchange_verificator(dap_chain_tx_out_cond_t *a_cond, dap_chain_datum_tx_t *a_tx, bool a_owner); diff --git a/modules/type/blocks/dap_chain_block.c b/modules/type/blocks/dap_chain_block.c index e9a6836f5f1f3b59eab751fe1a38c93505be62e4..4bc564e15eb26fe7d0e5691dfaf8902ae829b98a 100644 --- a/modules/type/blocks/dap_chain_block.c +++ b/modules/type/blocks/dap_chain_block.c @@ -25,7 +25,7 @@ #include "dap_common.h" #include "dap_config.h" #include "dap_hash.h" - +#include "dap_chain_net.h" #include "dap_chain_block.h" #include "dap_chain_block_cache.h" @@ -58,7 +58,7 @@ void dap_chain_block_deinit() * @param a_prev_block * @return */ -dap_chain_block_t * dap_chain_block_new(dap_chain_hash_fast_t * a_prev_block ) +dap_chain_block_t *dap_chain_block_new(dap_chain_hash_fast_t *a_prev_block, size_t *a_block_size) { dap_chain_block_t * l_block = DAP_NEW_Z_SIZE (dap_chain_block_t,sizeof(l_block->hdr)); if( l_block == NULL){ @@ -68,16 +68,18 @@ dap_chain_block_t * dap_chain_block_new(dap_chain_hash_fast_t * a_prev_block ) l_block->hdr.signature = DAP_CHAIN_BLOCK_SIGNATURE; l_block->hdr.version = 1; l_block->hdr.ts_created = time(NULL); - size_t l_block_size = sizeof (l_block->hdr); + size_t l_block_size = sizeof(l_block->hdr); if( a_prev_block ){ - l_block_size = dap_chain_block_meta_add(&l_block, l_block_size, DAP_CHAIN_BLOCK_META_PREV,a_prev_block,sizeof (*a_prev_block) ); + l_block_size = dap_chain_block_meta_add(&l_block, l_block_size, DAP_CHAIN_BLOCK_META_PREV, + a_prev_block, sizeof(*a_prev_block)); }else{ + l_block_size = dap_chain_block_meta_add(&l_block, l_block_size, DAP_CHAIN_BLOCK_META_GENESIS, NULL, 0); log_it(L_INFO, "Genesis block produced"); } + if (a_block_size) + *a_block_size = l_block_size; return l_block; } - - } /** @@ -89,7 +91,7 @@ dap_chain_block_t * dap_chain_block_new(dap_chain_hash_fast_t * a_prev_block ) size_t s_block_get_datum_offset (dap_chain_block_t * a_block, size_t a_block_size) { if( a_block_size < sizeof(a_block->hdr) ){ - log_it(L_ERROR,"Meta add: Corrupted block size %zd thats smaller then block header size %zd ", a_block_size, sizeof (a_block->hdr)); + log_it(L_ERROR, "Can't get datum offset: corrupted block size %zu / header size %zu", a_block_size, sizeof (a_block->hdr)); } size_t l_offset = 0; dap_chain_block_meta_t * l_meta=NULL; @@ -136,28 +138,22 @@ size_t dap_chain_block_meta_add(dap_chain_block_t ** a_block_ptr, size_t a_block return 0; } - size_t l_offset = s_block_get_datum_offset(l_block,a_block_size); - size_t l_datum_n_sign_copy_size = (a_block_size-sizeof (l_block->hdr)) - l_offset; - if (l_datum_n_sign_copy_size){ - byte_t * l_meta_end = l_block->meta_n_datum_n_sign +l_offset; - byte_t * l_datum_n_sign_copy = DAP_NEW_SIZE(byte_t, l_datum_n_sign_copy_size); - memcpy(l_datum_n_sign_copy, l_meta_end,l_datum_n_sign_copy_size); - *a_block_ptr = l_block = DAP_REALLOC(l_block,a_block_size +sizeof (l_meta->hdr) +a_data_size ); - l_meta= (dap_chain_block_meta_t*) (l_block->meta_n_datum_n_sign +l_offset); // Update data end in reallocated block - l_meta->hdr.data_size = a_data_size; - l_meta->hdr.type = a_meta_type; - l_offset += a_data_size; - l_offset += sizeof(l_meta->hdr); - if (a_data_size) - memcpy(l_meta->data, a_data, a_data_size); - l_meta_end= l_block->meta_n_datum_n_sign +l_offset; // Update meta end - memcpy(l_meta_end, l_datum_n_sign_copy, l_datum_n_sign_copy_size); - l_offset += l_datum_n_sign_copy_size; - l_block->hdr.meta_n_datum_n_signs_size = l_offset; - l_block->hdr.meta_count++; - DAP_DELETE(l_datum_n_sign_copy); + size_t l_add_size = sizeof(l_meta->hdr) + a_data_size; + *a_block_ptr = l_block = DAP_REALLOC(l_block, a_block_size + l_add_size); + size_t l_offset = s_block_get_datum_offset(l_block, a_block_size); + size_t l_datum_n_sign_copy_size = a_block_size - sizeof(l_block->hdr) - l_offset; + if (l_datum_n_sign_copy_size) { + byte_t *l_meta_end = l_block->meta_n_datum_n_sign + l_offset; + memmove(l_meta_end + l_add_size, l_meta_end, l_datum_n_sign_copy_size); } - return l_offset+sizeof (l_block->hdr); + l_meta = (dap_chain_block_meta_t *)(l_block->meta_n_datum_n_sign + l_offset); // Update data end in reallocated block + l_meta->hdr.data_size = a_data_size; + l_meta->hdr.type = a_meta_type; + if (a_data_size) + memcpy(l_meta->data, a_data, a_data_size); + l_block->hdr.meta_n_datum_n_signs_size = l_offset + l_datum_n_sign_copy_size; + l_block->hdr.meta_count++; + return a_block_size + l_add_size; } /** @@ -199,14 +195,14 @@ size_t dap_chain_block_datum_add(dap_chain_block_t ** a_block_ptr, size_t a_bloc log_it(L_ERROR,"Offset %zd is bigger than block size %zd (without header)", l_offset, (a_block_size-sizeof (l_block->hdr))); return a_block_size; } - if (UINT32_MAX - l_block->hdr.meta_n_datum_n_signs_size < a_datum_size && l_block->hdr.datum_count<UINT16_MAX ){ + if (a_datum_size + l_block->hdr.meta_n_datum_n_signs_size < UINT32_MAX && l_block->hdr.datum_count < UINT16_MAX) { // If were signs - they would be deleted after because signed should be all the block filled - *a_block_ptr = l_block = DAP_REALLOC(l_block,l_offset +a_datum_size); - memcpy(l_block->meta_n_datum_n_sign + l_offset, a_datum,a_datum_size); + *a_block_ptr = l_block = DAP_REALLOC(l_block, sizeof(l_block->hdr) + l_offset + a_datum_size); + memcpy(l_block->meta_n_datum_n_sign + l_offset, a_datum, a_datum_size); l_offset += a_datum_size; l_block->hdr.datum_count++; l_block->hdr.meta_n_datum_n_signs_size = l_offset; - return l_offset+sizeof (l_block->hdr); + return l_offset + sizeof(l_block->hdr); }else{ //log_it(L_ERROR,""); return a_block_size; @@ -279,12 +275,12 @@ size_t dap_chain_block_datum_del_by_hash(dap_chain_block_t ** a_block_ptr, size_ * @param a_block_size * @return */ -static size_t s_block_get_sign_offset(dap_chain_block_t * a_block, size_t a_block_size) +size_t dap_chain_block_get_sign_offset(dap_chain_block_t *a_block, size_t a_block_size) { assert(a_block); assert(a_block_size); - if(a_block_size>=sizeof (a_block->hdr)){ - log_it(L_ERROR, "Corrupted block, block size %zd is lesser than block header size %zd", a_block_size,sizeof (a_block->hdr)); + if (a_block_size <= sizeof(a_block->hdr)) { + log_it(L_ERROR, "Get sign: corrupted block, block size %zd is lesser than block header size %zd", a_block_size,sizeof (a_block->hdr)); return 0; } @@ -309,7 +305,7 @@ static size_t s_block_get_sign_offset(dap_chain_block_t * a_block, size_t a_bloc l_datum =(dap_chain_datum_t *) (a_block->meta_n_datum_n_sign + l_offset); } if (l_offset> (a_block_size-sizeof (a_block->hdr))){ - log_it(L_ERROR,"Offset %zd with block header %zd is bigger than block size %zd ", l_offset,sizeof (a_block->hdr),a_block_size); + log_it(L_ERROR,"Offset %zd with block header %zu is bigger than block size %zu", l_offset,sizeof (a_block->hdr),a_block_size); return a_block_size; } @@ -323,17 +319,19 @@ static size_t s_block_get_sign_offset(dap_chain_block_t * a_block, size_t a_bloc * @param a_cert * @return */ -size_t dap_chain_block_sign_add( dap_chain_block_t ** a_block_ptr, size_t a_block_size, dap_cert_t * a_cert ) +size_t dap_chain_block_sign_add(dap_chain_block_t **a_block_ptr, size_t a_block_size, dap_enc_key_t *a_key) { assert(a_block_ptr); - dap_chain_block_t * l_block = *a_block_ptr; - size_t l_offset = s_block_get_sign_offset(l_block,a_block_size); - dap_sign_t * l_block_sign = dap_cert_sign(a_cert,l_block,l_offset+sizeof (l_block->hdr),0); + dap_chain_block_t *l_block = *a_block_ptr; + size_t l_offset = dap_chain_block_get_sign_offset(l_block, a_block_size); + dap_sign_t *l_block_sign = dap_sign_create(a_key, l_block, l_offset + sizeof(l_block->hdr), 0); size_t l_block_sign_size = dap_sign_get_size(l_block_sign); + if (!l_block_sign_size) + return 0; *a_block_ptr = l_block = DAP_REALLOC(l_block, l_block_sign_size + a_block_size); - memcpy( ((byte_t *)l_block) +a_block_size,l_block_sign, l_block_sign_size ); + memcpy(((byte_t *)l_block) + a_block_size, l_block_sign, l_block_sign_size); DAP_DELETE(l_block_sign); - return a_block_size+l_block_sign_size; + return a_block_size + l_block_sign_size; } /** @@ -346,25 +344,47 @@ size_t dap_chain_block_sign_add( dap_chain_block_t ** a_block_ptr, size_t a_bloc dap_sign_t *dap_chain_block_sign_get ( dap_chain_block_t * a_block, size_t a_block_size, uint16_t a_sign_num ) { assert(a_block); - size_t l_offset = s_block_get_sign_offset(a_block,a_block_size); - uint16_t l_sign_cur=0; - dap_sign_t * l_sign = (dap_sign_t*) a_block->meta_n_datum_n_sign+l_offset; - while( l_sign_cur <a_sign_num){ + size_t l_offset = dap_chain_block_get_sign_offset(a_block, a_block_size); + uint16_t l_sign_cur = 0; + dap_sign_t *l_sign = (dap_sign_t *)(a_block->meta_n_datum_n_sign + l_offset); + while (l_sign_cur < a_sign_num) { size_t l_sign_size = dap_sign_get_size(l_sign); - if (!l_sign){ + if (!l_sign_size){ log_it(L_ERROR, "Empty sign #%u", l_sign_cur ); return NULL; } if (l_sign_size > a_block_size- l_offset - sizeof (a_block->hdr) ){ - log_it(L_ERROR, "Corrupted sign #%u size %zd", l_sign_cur, l_sign_size ); + log_it(L_ERROR, "Corrupted sign #%u size %zu", l_sign_cur, l_sign_size ); return NULL; } l_offset += l_sign_size; l_sign_cur++; l_sign = (dap_sign_t*) a_block->meta_n_datum_n_sign+l_offset; } - return l_sign_cur == a_sign_num? l_sign : NULL; + return l_sign_cur == a_sign_num ? l_sign : NULL; +} + +size_t dap_chain_block_get_signs_count(dap_chain_block_t * a_block, size_t a_block_size) +{ + assert(a_block); + assert(a_block_size); + uint16_t l_sign_count = 0; + size_t l_offset = dap_chain_block_get_sign_offset(a_block,a_block_size); + for ( ; l_offset < a_block_size; l_sign_count++) { + dap_sign_t *l_sign = (dap_sign_t *)a_block->meta_n_datum_n_sign + l_offset; + size_t l_sign_size = dap_sign_get_size(l_sign); + if (!l_sign_size){ + log_it(L_WARNING, "Empty sign #%hu", l_sign_count); + return l_sign_count; + } + if (l_sign_size > a_block_size - l_offset - sizeof(a_block->hdr)) { + log_it(L_ERROR, "Corrupted sign #%hu size %zu", l_sign_count, l_sign_size); + return l_sign_count; + } + l_offset += l_sign_size; + } + return l_sign_count; } /** @@ -379,11 +399,11 @@ dap_chain_datum_t** dap_chain_block_get_datums(dap_chain_block_t * a_block, size assert(a_block); assert(a_block_size); if( a_block_size<sizeof (a_block->hdr)){ - log_it(L_ERROR,"Corrupted block size %zd lesser than block header size %zd", a_block_size, sizeof (a_block->hdr)); + log_it(L_ERROR, "Get datums: corrupted block size %zd lesser than block header size %zd", a_block_size, sizeof (a_block->hdr)); return NULL; } - assert(a_datums_count); - *a_datums_count = a_block->hdr.datum_count; + if (a_datums_count) + *a_datums_count = 0; if (a_block->hdr.datum_count == 0) return NULL; size_t l_offset = s_block_get_datum_offset(a_block,a_block_size); @@ -405,11 +425,11 @@ dap_chain_datum_t** dap_chain_block_get_datums(dap_chain_block_t * a_block, size return l_ret; } l_ret[n] = l_datum; - (*a_datums_count)++; + if (a_datums_count) + (*a_datums_count)++; // Update current datum pointer and offset l_offset += l_datum_size; l_datum =(dap_chain_datum_t *) (a_block->meta_n_datum_n_sign + l_offset); - } if (l_offset> (a_block_size-sizeof (a_block->hdr))){ log_it(L_ERROR,"Offset %zd is bigger than block size %zd (without header)", l_offset, (a_block_size-sizeof (a_block->hdr))); @@ -428,10 +448,11 @@ dap_chain_datum_t** dap_chain_block_get_datums(dap_chain_block_t * a_block, size dap_chain_block_meta_t** dap_chain_block_get_meta(dap_chain_block_t * a_block, size_t a_block_size,size_t * a_meta_count ) { if( a_block_size < sizeof(a_block->hdr) ){ - log_it(L_ERROR,"Meta add: Corrupted block size %zu thats smaller then block header size %zu ", a_block_size, sizeof (a_block->hdr)); + log_it(L_ERROR,"Get meta: corrupted block size %zu thats smaller then block header size %zu", a_block_size, sizeof (a_block->hdr)); } - *a_meta_count = a_block->hdr.meta_count; - if (a_block->hdr.meta_count ==0) // no meta - nothing to return + if (a_meta_count) + *a_meta_count = 0; + if (a_block->hdr.meta_count == 0) // no meta - nothing to return return NULL; size_t l_offset = 0; dap_chain_block_meta_t * l_meta=NULL; @@ -443,11 +464,13 @@ dap_chain_block_meta_t** dap_chain_block_get_meta(dap_chain_block_t * a_block, s size_t l_meta_data_size = l_meta->hdr.data_size; if (l_meta_data_size + sizeof (l_meta->hdr) + l_offset <= (a_block_size-sizeof (a_block->hdr)) ){ l_ret[i] = l_meta; - (*a_meta_count)++; - l_offset += sizeof (l_meta->hdr); - l_offset += l_meta_data_size; - }else - l_offset = (a_block_size-sizeof (a_block->hdr)); + if (a_meta_count) + (*a_meta_count)++; + l_offset += sizeof(l_meta->hdr) + l_meta_data_size; + }else { + log_it(L_WARNING, "Get meta: corrupted block, can read only %zu from %hu metas", i, a_block->hdr.meta_count); + return l_ret; + } } return l_ret; } @@ -465,6 +488,7 @@ dap_chain_block_meta_t** dap_chain_block_get_meta(dap_chain_block_t * a_block, s void dap_chain_block_meta_extract(dap_chain_block_meta_t ** a_meta, size_t a_meta_count, 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, size_t *a_block_links_count, bool * a_is_genesis, @@ -472,12 +496,15 @@ void dap_chain_block_meta_extract(dap_chain_block_meta_t ** a_meta, size_t a_met uint64_t *a_nonce2 ) { + if (!a_meta || !a_meta_count) + return; // Check for meta that could be faced only once bool l_was_prev = false; bool l_was_genesis = false; bool l_was_anchor = false; bool l_was_nonce = false; bool l_was_nonce2 = false; + bool l_was_merkle = false; // Init links parsing size_t l_links_count_max = 5; if (a_block_links_count) @@ -563,7 +590,20 @@ void dap_chain_block_meta_extract(dap_chain_block_meta_t ** a_meta, size_t a_met if (l_meta->hdr.data_size == sizeof (*a_nonce2 ) ) memcpy(a_nonce2, l_meta->data, l_meta->hdr.data_size); else - log_it(L_WARNING, "NONCE2 meta #%zd has wrong size %hu when expecting %zu",i, l_meta->hdr.data_size, sizeof (*a_nonce2)); + log_it(L_WARNING, "NONCE2 meta #%zu has wrong size %hu when expecting %zu",i, l_meta->hdr.data_size, sizeof (*a_nonce2)); + } + break; + case DAP_CHAIN_BLOCK_META_MERKLE: + if(l_was_merkle){ + log_it(L_WARNING, "Merckle root could be only one in the block, meta #%zu is ignored ", i); + break; + } + l_was_merkle = true; + if (a_merkle) { + if (l_meta->hdr.data_size == sizeof(*a_merkle)) + memcpy(a_merkle, l_meta->data, l_meta->hdr.data_size); + else + log_it(L_WARNING, "Merkle root meta #%zu has wrong size %hu when expecting %zu", i, l_meta->hdr.data_size, sizeof (*a_nonce2)); } break; default: { log_it(L_WARNING, "Unknown meta #%zu type 0x%02hx (size %hu), possible corrupted block or you need to upgrade your software", diff --git a/modules/type/blocks/dap_chain_block_cache.c b/modules/type/blocks/dap_chain_block_cache.c index 685e736fca54f309a9857a905949908f484545b6..49eaa19c068c53cadb3121d7e915c795889e453a 100644 --- a/modules/type/blocks/dap_chain_block_cache.c +++ b/modules/type/blocks/dap_chain_block_cache.c @@ -53,7 +53,7 @@ void dap_chain_block_cache_deinit() * @param a_block_size * @return */ -dap_chain_block_cache_t * dap_chain_block_cache_new(dap_chain_block_t * a_block, size_t a_block_size) +dap_chain_block_cache_t * dap_chain_block_cache_new(dap_chain_cs_blocks_t *a_blocks, dap_chain_block_t * a_block, size_t a_block_size) { if (! a_block) return NULL; @@ -61,8 +61,12 @@ dap_chain_block_cache_t * dap_chain_block_cache_new(dap_chain_block_t * a_block, dap_chain_block_cache_t * l_block_cache = DAP_NEW_Z(dap_chain_block_cache_t); l_block_cache->block = a_block; l_block_cache->block_size= a_block_size; - dap_chain_block_cache_update(l_block_cache); - + l_block_cache->_inheritor = a_blocks; + if (dap_chain_block_cache_update(l_block_cache)) { + log_it(L_WARNING, "Block cache can't be created, possible cause corrupted block inside"); + DAP_DELETE(l_block_cache); + return NULL; + } log_it(L_DEBUG,"Block cache created"); return l_block_cache; } @@ -84,26 +88,35 @@ dap_chain_block_cache_t * dap_chain_block_cache_dup(dap_chain_block_cache_t * a_ * @brief dap_chain_block_cache_update * @param a_block_cache */ -void dap_chain_block_cache_update(dap_chain_block_cache_t * a_block_cache) +int dap_chain_block_cache_update(dap_chain_block_cache_t * a_block_cache) { assert(a_block_cache); assert(a_block_cache->block); dap_hash_fast(a_block_cache->block, a_block_cache->block_size, &a_block_cache->block_hash); + if (a_block_cache->meta) + DAP_DELETE(a_block_cache->meta); if (a_block_cache->datum) DAP_DELETE(a_block_cache->datum); - a_block_cache->datum = dap_chain_block_get_datums( a_block_cache->block, a_block_cache->block_size, &a_block_cache->datum_count ); - a_block_cache->meta = dap_chain_block_get_meta (a_block_cache->block, a_block_cache->block_size, &a_block_cache->meta_count); - + a_block_cache->meta = dap_chain_block_get_meta(a_block_cache->block, a_block_cache->block_size, &a_block_cache->meta_count); + if (a_block_cache->meta_count != a_block_cache->block->hdr.meta_count) { + DAP_DELETE(a_block_cache->meta); + return -1; + } dap_chain_block_meta_extract( a_block_cache->meta,a_block_cache->meta_count, &a_block_cache->prev_hash, &a_block_cache->anchor_hash, + &a_block_cache->merkle_root, &a_block_cache->links_hash, &a_block_cache->links_hash_count, &a_block_cache->is_genesis, &a_block_cache->nonce, &a_block_cache->nonce2 ); - + a_block_cache->datum = dap_chain_block_get_datums( a_block_cache->block, a_block_cache->block_size, &a_block_cache->datum_count ); + if (a_block_cache->datum_count != a_block_cache->block->hdr.datum_count) { + DAP_DELETE(a_block_cache->datum); + return -2; + } for (size_t i = 0; i< a_block_cache->datum_count; i++){ dap_chain_datum_t * l_datum = a_block_cache->datum[i]; if ( l_datum && l_datum->header.data_size && l_datum->header.type_id == DAP_CHAIN_DATUM_TX){ @@ -119,6 +132,7 @@ void dap_chain_block_cache_update(dap_chain_block_cache_t * a_block_cache) } } } + return 0; } /** @@ -143,4 +157,3 @@ void dap_chain_block_cache_delete(dap_chain_block_cache_t * a_block_cache) DAP_DELETE(a_block_cache); log_it(L_DEBUG,"Block cache deleted"); } - diff --git a/modules/type/blocks/dap_chain_block_chunk.c b/modules/type/blocks/dap_chain_block_chunk.c index 4661144d4cee82461ff92dd7e30e642f65beff43..76a2a15f4562531ec96ff25b408ad3ba46133506 100644 --- a/modules/type/blocks/dap_chain_block_chunk.c +++ b/modules/type/blocks/dap_chain_block_chunk.c @@ -44,7 +44,7 @@ dap_chain_block_chunks_t * dap_chain_block_chunks_create(dap_chain_cs_blocks_t * size_t l_objs_count =0; dap_global_db_obj_t * l_objs= dap_chain_global_db_gr_load(l_ret->gdb_group, &l_objs_count); for(size_t n=0; n< l_objs_count; n++){ - dap_chain_block_cache_t * l_block_cache = dap_chain_block_cache_new((dap_chain_block_t*) l_objs[n].value,l_objs[n].value_len); + dap_chain_block_cache_t *l_block_cache = dap_chain_block_cache_new(a_blocks, (dap_chain_block_t*)l_objs[n].value, l_objs[n].value_len); dap_chain_block_chunks_add(l_ret, l_block_cache ); } dap_chain_global_db_objs_delete(l_objs,l_objs_count); @@ -84,6 +84,8 @@ void dap_chain_block_chunks_delete(dap_chain_block_chunks_t * a_chunks) */ void dap_chain_block_chunks_add(dap_chain_block_chunks_t * a_chunks,dap_chain_block_cache_t * a_block_cache) { + if (!a_block_cache) + return; dap_chain_block_cache_hash_t * l_chunk_cache_hash = NULL; // Parse block and produce cache object dap_chain_block_t *l_block = a_block_cache->block; diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c index 8481850c919ce9a7159b4ab216e8807c51242eb3..618969208652eee19363d1b5f9352ca44b76809c 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -26,12 +26,13 @@ #include "dap_common.h" #include "dap_enc_base58.h" #include "dap_chain.h" +#include "dap_chain_cell.h" #include "dap_chain_cs.h" #include "dap_chain_cs_blocks.h" #include "dap_chain_block.h" #include "dap_chain_block_cache.h" #include "dap_chain_block_chunk.h" - +#include "dap_timerfd.h" #include "dap_chain_node_cli.h" #include "dap_chain_node_cli_cmd.h" #define LOG_TAG "dap_chain_cs_blocks" @@ -59,7 +60,7 @@ typedef struct dap_chain_cs_blocks_pvt dap_chain_tx_block_index_t * tx_block_index; // To find block hash by tx hash - // General lins + // General links dap_chain_block_cache_t * block_cache_first; // Mapped area start dap_chain_block_cache_t * block_cache_last; // Last block in mapped area dap_chain_hash_fast_t genesis_block_hash; @@ -71,6 +72,10 @@ typedef struct dap_chain_cs_blocks_pvt size_t block_size_maximum; // Maximum block size bool is_celled; + dap_timerfd_t *fill_timer; + pthread_rwlock_t datums_lock; + uint64_t fill_timeout; + } dap_chain_cs_blocks_pvt_t; typedef struct dap_chain_cs_blocks_iter @@ -79,7 +84,7 @@ typedef struct dap_chain_cs_blocks_iter dap_chain_block_cache_t * cache; } dap_chain_cs_blocks_iter_t; -#define PVT(a) ((dap_chain_cs_blocks_pvt_t *) a->_pvt ) +#define PVT(a) ((dap_chain_cs_blocks_pvt_t *)(a)->_pvt ) #define ITER_PVT(a) ((dap_chain_cs_blocks_iter_t *) a->_inheritor ) @@ -122,9 +127,9 @@ static dap_chain_atom_ptr_t *s_callback_atom_iter_get_lasts( dap_chain_atom_iter // Delete iterator static void s_callback_atom_iter_delete(dap_chain_atom_iter_t * a_atom_iter ); // Get the fisrt block -static size_t s_callback_add_datums(dap_chain_t * a_chain, dap_chain_datum_t ** a_datums, size_t a_datums_size); +static size_t s_callback_add_datums(dap_chain_t * a_chain, dap_chain_datum_t ** a_datums, size_t a_datums_count); -bool s_seed_mode=false; +static bool s_seed_mode=false; /** @@ -181,6 +186,7 @@ int dap_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); a_chain->_inheritor = l_cs_blocks; + l_cs_blocks->chain = a_chain; a_chain->callback_delete = s_callback_delete; @@ -209,8 +215,8 @@ int dap_chain_cs_blocks_new(dap_chain_t * a_chain, dap_config_t * a_chain_config dap_chain_cs_blocks_pvt_t *l_cs_blocks_pvt = DAP_NEW_Z(dap_chain_cs_blocks_pvt_t); l_cs_blocks->_pvt = l_cs_blocks_pvt; - a_chain->_pvt = l_cs_blocks_pvt; pthread_rwlock_init(&l_cs_blocks_pvt->rwlock,NULL); + pthread_rwlock_init(&l_cs_blocks_pvt->datums_lock, NULL); const char * l_genesis_blocks_hash_str = dap_config_get_item_str_default(a_chain_config,"blocks","genesis_block",NULL); if ( l_genesis_blocks_hash_str ){ @@ -222,15 +228,10 @@ int dap_chain_cs_blocks_new(dap_chain_t * a_chain, dap_config_t * a_chain_config l_cs_blocks_pvt->is_celled = dap_config_get_item_bool_default(a_chain_config,"blocks","is_celled",false); l_cs_blocks_pvt->chunks = dap_chain_block_chunks_create(l_cs_blocks); -// dap_chain_node_role_t l_net_role= dap_chain_net_get_role( dap_chain_net_by_id(a_chain->net_id) ); - // Datum operations callbacks -/* - a_chain->callback_datum_iter_create = s_chain_callback_datum_iter_create; // Datum iterator create - a_chain->callback_datum_iter_delete = s_chain_callback_datum_iter_delete; // Datum iterator delete - a_chain->callback_datum_iter_get_first = s_chain_callback_datum_iter_get_first; // Get the fisrt datum from chain - a_chain->callback_datum_iter_get_next = s_chain_callback_datum_iter_get_next; // Get the next datum from chain from the current one -*/ + l_cs_blocks_pvt->block_size_maximum = 10 * 1024 * 1024; // 10 Mb + l_cs_blocks_pvt->fill_timeout = dap_config_get_item_uint64_default(a_chain_config, "blocks", "fill_timeout", 60) * 1000; // 1 min + return 0; } @@ -240,8 +241,7 @@ int dap_chain_cs_blocks_new(dap_chain_t * a_chain, dap_config_t * a_chain_config */ void dap_chain_cs_blocks_delete(dap_chain_t * a_chain) { - pthread_rwlock_destroy(&PVT( DAP_CHAIN_CS_BLOCKS(a_chain) )->rwlock ); - dap_chain_block_chunks_delete(PVT(DAP_CHAIN_CS_BLOCKS(a_chain))->chunks ); + s_callback_delete(a_chain); } /** @@ -381,8 +381,9 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply) pthread_rwlock_wrlock( &PVT(l_blocks)->rwlock ); if ( l_blocks->block_new ) DAP_DELETE( l_blocks->block_new ); - l_blocks->block_new = dap_chain_block_new( PVT(l_blocks)->block_cache_last? &PVT(l_blocks)->block_cache_last->block_hash: NULL ); - l_blocks->block_new_size = sizeof (l_blocks->block_new->hdr); + l_blocks->block_new = dap_chain_block_new(PVT(l_blocks)->block_cache_last ? + &PVT(l_blocks)->block_cache_last->block_hash : NULL, + &l_blocks->block_new_size); pthread_rwlock_unlock( &PVT(l_blocks)->rwlock ); } break; @@ -476,7 +477,7 @@ static int s_cli_blocks(int a_argc, char ** a_argv, char **a_str_reply) dap_chain_block_meta_t * l_meta = l_block_cache->meta[i]; switch (l_meta->hdr.type) { case DAP_CHAIN_BLOCK_META_GENESIS:{ - dap_string_append_printf(l_str_tmp,"\t\tGENESIS\n"); + dap_string_append_printf(l_str_tmp, "\t\tGENESIS\n"); }break; case DAP_CHAIN_BLOCK_META_PREV:{ s_cli_meta_hash_print(l_str_tmp, "PREV", l_meta); @@ -594,6 +595,8 @@ static void s_callback_delete(dap_chain_t * a_chain) DAP_DELETE(l_blocks->_pvt); pthread_rwlock_unlock(&PVT(l_blocks)->rwlock); pthread_rwlock_destroy(&PVT(l_blocks)->rwlock); + pthread_rwlock_destroy(&PVT(l_blocks)->datums_lock); + dap_chain_block_chunks_delete(PVT(l_blocks)->chunks ); log_it(L_INFO,"callback_delete() called"); } @@ -679,9 +682,7 @@ static int s_add_atom_to_blocks(dap_chain_cs_blocks_t * a_blocks, dap_ledger_t * pthread_rwlock_unlock( &PVT(a_blocks)->rwlock ); res = s_add_atom_to_ledger(a_blocks, a_ledger, a_block_cache); if (res) { - pthread_rwlock_rdlock( &PVT(a_blocks)->rwlock ); log_it(L_INFO,"Block %s checked, but ledger declined", a_block_cache->block_hash_str ); - pthread_rwlock_unlock( &PVT(a_blocks)->rwlock ); return res; } //All correct, no matter for result @@ -689,7 +690,8 @@ static int s_add_atom_to_blocks(dap_chain_cs_blocks_t * a_blocks, dap_ledger_t * HASH_ADD(hh, PVT(a_blocks)->blocks,block_hash,sizeof (a_block_cache->block_hash), a_block_cache); if (! (PVT(a_blocks)->block_cache_first ) ) PVT(a_blocks)->block_cache_first = a_block_cache; - PVT(a_blocks)->block_cache_last->next = a_block_cache; + if (PVT(a_blocks)->block_cache_last) + PVT(a_blocks)->block_cache_last->next = a_block_cache; a_block_cache->prev = PVT(a_blocks)->block_cache_last; PVT(a_blocks)->block_cache_last = a_block_cache; @@ -782,7 +784,11 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da log_it(L_DEBUG, "... already present in blocks %s",l_block_cache->block_hash_str); return ATOM_PASS; } else { - l_block_cache = dap_chain_block_cache_new( l_block, l_block_size); + l_block_cache = dap_chain_block_cache_new(l_blocks, l_block, l_block_size); + if (!l_block_cache) { + log_it(L_DEBUG, "... corrupted block"); + return ATOM_REJECT; + } log_it(L_DEBUG, "... new block %s",l_block_cache->block_hash_str); ret = ATOM_ACCEPT; } @@ -790,7 +796,8 @@ static dap_chain_atom_verify_res_t s_callback_atom_add(dap_chain_t * a_chain, da // verify hashes and consensus if(ret == ATOM_ACCEPT){ ret = s_callback_atom_verify (a_chain, a_atom, a_atom_size); - log_it(L_DEBUG, "Verified atom %p: code %d", a_atom, ret); + log_it(L_DEBUG, "Verified atom %p: %s", a_atom, ret == ATOM_ACCEPT ? "accepted" : + (ret == ATOM_REJECT ? "rejected" : "thresholded")); } if( ret == ATOM_ACCEPT){ @@ -850,6 +857,7 @@ static dap_chain_atom_verify_res_t s_callback_atom_verify(dap_chain_t * a_chain, &l_block_anchor_hash, NULL, NULL, + NULL, &l_is_genesis, &l_nonce, &l_nonce2 ) ; @@ -866,7 +874,7 @@ static dap_chain_atom_verify_res_t s_callback_atom_verify(dap_chain_t * a_chain, log_it(L_NOTICE,"Accepting new genesis block"); return ATOM_ACCEPT; }else if(s_seed_mode){ - log_it(L_WARNING,"Cant accept genesis blockt: already present data in blockchain"); + log_it(L_WARNING,"Cant accept genesis block: already present data in blockchain"); return ATOM_REJECT; } }else{ @@ -918,7 +926,8 @@ static dap_chain_atom_iter_t* s_callback_atom_iter_create_from(dap_chain_t * a_c dap_hash_fast(a_atom, a_atom_size, &l_atom_hash); dap_chain_atom_iter_t * l_atom_iter = s_callback_atom_iter_create(a_chain); if (l_atom_iter){ - l_atom_iter->cur_item =ITER_PVT(l_atom_iter)->cache = dap_chain_block_cache_get_by_hash(l_atom_hash); + dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain); + l_atom_iter->cur_item = ITER_PVT(l_atom_iter)->cache = dap_chain_block_cs_cache_get_by_hash(l_blocks, &l_atom_hash); l_atom_iter->cur = a_atom; l_atom_iter->cur_size = a_atom_size; return l_atom_iter; @@ -964,7 +973,7 @@ static dap_chain_datum_tx_t* s_callback_atom_iter_find_by_tx_hash(dap_chain_t * dap_chain_tx_block_index_t * l_tx_block_index = NULL; HASH_FIND(hh, PVT(l_cs_blocks)->tx_block_index,a_tx_hash, sizeof (*a_tx_hash), l_tx_block_index); if (l_tx_block_index){ - dap_chain_block_cache_t * l_block_cache = dap_chain_block_cache_get_by_hash( l_tx_block_index->block_hash ); + dap_chain_block_cache_t *l_block_cache = dap_chain_block_cs_cache_get_by_hash(l_cs_blocks, &l_tx_block_index->block_hash); if ( l_block_cache){ return dap_chain_block_cache_get_tx_by_hash(l_block_cache, a_tx_hash); }else @@ -1053,7 +1062,8 @@ static dap_chain_atom_ptr_t *s_callback_atom_iter_get_links( dap_chain_atom_iter *a_links_size = l_block_cache->links_hash_count; dap_chain_atom_ptr_t * l_ret = DAP_NEW_Z_SIZE(dap_chain_atom_ptr_t, l_block_cache->links_hash_count *sizeof (dap_chain_atom_ptr_t) ); for (size_t i = 0; i< l_block_cache->links_hash_count; i ++){ - dap_chain_block_cache_t * l_link = dap_chain_block_cache_get_by_hash(l_block_cache->links_hash[i]); + dap_chain_cs_blocks_t *l_cs_blocks = (dap_chain_cs_blocks_t *)l_block_cache->_inheritor; + dap_chain_block_cache_t *l_link = dap_chain_block_cs_cache_get_by_hash(l_cs_blocks, &l_block_cache->links_hash[i]); assert(l_link); (*a_links_size_ptr)[i] = l_link->block_size; l_ret[i] = l_link->block; @@ -1101,6 +1111,35 @@ static void s_callback_atom_iter_delete(dap_chain_atom_iter_t * a_atom_iter ) DAP_DELETE(a_atom_iter); } +static int s_new_block_complete(dap_chain_cs_blocks_t *a_blocks) +{ + dap_hash_fast_t l_merkle_root = {}; // TODO compute the merkle root of block's datums + a_blocks->block_new_size = dap_chain_block_meta_add(&a_blocks->block_new, a_blocks->block_new_size, + DAP_CHAIN_BLOCK_META_MERKLE, &l_merkle_root, sizeof(l_merkle_root)); + size_t l_signed_size = a_blocks->callback_block_sign(a_blocks, &a_blocks->block_new, a_blocks->block_new_size); + if (l_signed_size) + a_blocks->block_new_size = l_signed_size; + else { + log_it(L_WARNING, "Block signing failed"); + return -1; + } + dap_chain_atom_verify_res_t l_res = s_callback_atom_add(a_blocks->chain, a_blocks->block_new, a_blocks->block_new_size); + DAP_DEL_Z(a_blocks->block_new); + if (l_res == ATOM_ACCEPT) + return 0; + return -2; +} + +static bool s_callback_datums_timer(void *a_arg) +{ + dap_chain_cs_blocks_pvt_t *l_blocks_pvt = PVT((dap_chain_cs_blocks_t *)a_arg); + pthread_rwlock_wrlock(&l_blocks_pvt->datums_lock); + s_new_block_complete((dap_chain_cs_blocks_t *)a_arg); + pthread_rwlock_unlock(&l_blocks_pvt->datums_lock); + l_blocks_pvt->fill_timer = NULL; + return false; +} + /** * @brief s_callback_datums_pool_proc * @param a_chain @@ -1108,13 +1147,31 @@ static void s_callback_atom_iter_delete(dap_chain_atom_iter_t * a_atom_iter ) * @param a_datums_size * @return */ -static size_t s_callback_add_datums(dap_chain_t * a_chain, dap_chain_datum_t ** a_datums, size_t a_datums_size) +static size_t s_callback_add_datums(dap_chain_t *a_chain, dap_chain_datum_t **a_datums, size_t a_datums_count) { - // IMPORTANT - all datums on input should be checket before for curruption because datum size is taken from datum's header - for (size_t i = 0; i < a_datums_size; i++) { - DAP_CHAIN_CS_BLOCKS(a_chain)->block_new_size = dap_chain_block_datum_add( &DAP_CHAIN_CS_BLOCKS(a_chain)->block_new, - DAP_CHAIN_CS_BLOCKS(a_chain)->block_new_size, - a_datums[i],dap_chain_datum_size(a_datums[i]) ); + dap_chain_cs_blocks_t *l_blocks = DAP_CHAIN_CS_BLOCKS(a_chain); + dap_chain_cs_blocks_pvt_t *l_blocks_pvt = PVT(l_blocks); + // IMPORTANT - all datums on input should be checked before for curruption because datum size is taken from datum's header + pthread_rwlock_wrlock(&l_blocks_pvt->datums_lock); + if (!l_blocks->block_new) { + l_blocks->block_new = dap_chain_block_new(&l_blocks_pvt->block_cache_last->block_hash, &l_blocks->block_new_size); + dap_chain_net_t *l_net = dap_chain_net_by_id(l_blocks->chain->net_id); + l_blocks->block_new->hdr.cell_id.uint64 = l_net->pub.cell_id.uint64; + l_blocks->block_new->hdr.chain_id.uint64 = l_blocks->chain->id.uint64; + } + for (size_t i = 0; i < a_datums_count; i++) { + size_t l_datum_size = dap_chain_datum_size(a_datums[i]); + if (l_blocks->block_new_size + l_datum_size > l_blocks_pvt->block_size_maximum) { + s_new_block_complete(l_blocks); + pthread_rwlock_unlock(&l_blocks_pvt->datums_lock); + s_callback_add_datums(a_chain, &a_datums[i], a_datums_count - i); + pthread_rwlock_wrlock(&l_blocks_pvt->datums_lock); + } + l_blocks->block_new_size = dap_chain_block_datum_add(&l_blocks->block_new, l_blocks->block_new_size, + a_datums[i], l_datum_size); } - return DAP_CHAIN_CS_BLOCKS(a_chain)->block_new_size; + if (!l_blocks_pvt->fill_timer) + l_blocks_pvt->fill_timer = dap_timerfd_start(l_blocks_pvt->fill_timeout, s_callback_datums_timer, l_blocks); + pthread_rwlock_unlock(&l_blocks_pvt->datums_lock); + return l_blocks->block_new_size; } diff --git a/modules/type/blocks/include/dap_chain_block.h b/modules/type/blocks/include/dap_chain_block.h index 6364350205650328e7e49866169e9280b064cc9d..bcb81167a6f6fcb9b1df12d2d1347583c544c14b 100644 --- a/modules/type/blocks/include/dap_chain_block.h +++ b/modules/type/blocks/include/dap_chain_block.h @@ -69,6 +69,7 @@ typedef struct dap_chain_block_meta{ #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 /** @@ -86,7 +87,7 @@ int dap_chain_block_init(); void dap_chain_block_deinit(); // Create new block -dap_chain_block_t * dap_chain_block_new(dap_chain_hash_fast_t * a_prev_block ); +dap_chain_block_t *dap_chain_block_new(dap_chain_hash_fast_t *a_prev_block, size_t *a_block_size); // Add metadata in block size_t dap_chain_block_meta_add(dap_chain_block_t ** a_block_ptr, size_t a_block_size, uint8_t a_meta_type, const void * a_data, size_t a_data_size); @@ -96,8 +97,10 @@ size_t dap_chain_block_datum_add(dap_chain_block_t ** a_block_ptr, size_t a_bloc size_t dap_chain_block_datum_del_by_hash(dap_chain_block_t ** a_block_ptr, size_t a_block_size, dap_chain_hash_fast_t* a_datum_hash); // Add sign in block -size_t dap_chain_block_sign_add( dap_chain_block_t ** a_block_ptr, size_t a_block_size, dap_cert_t * a_cert ); +size_t dap_chain_block_sign_add(dap_chain_block_t ** a_block_ptr, size_t a_block_size, dap_enc_key_t *a_key); dap_sign_t *dap_chain_block_sign_get ( dap_chain_block_t * a_block_ptr, size_t a_block_size, uint16_t a_sign_num ); +size_t dap_chain_block_get_signs_count(dap_chain_block_t * a_block, size_t a_block_size); +size_t dap_chain_block_get_sign_offset(dap_chain_block_t *a_block, size_t a_block_size); // Create and return datums list dap_chain_datum_t** dap_chain_block_get_datums(dap_chain_block_t * a_block, size_t a_block_size,size_t * a_datums_count ); @@ -108,6 +111,7 @@ dap_chain_block_meta_t** dap_chain_block_get_meta(dap_chain_block_t * a_block, s void dap_chain_block_meta_extract(dap_chain_block_meta_t ** a_meta, size_t a_meta_count, 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, size_t *a_block_links_count, bool * a_is_genesis, diff --git a/modules/type/blocks/include/dap_chain_block_cache.h b/modules/type/blocks/include/dap_chain_block_cache.h index f89199984f8150814f3e84d932d5729a5ca1566c..01f0a8d3b616edc569d6b42c0cf186c8bdb95c0b 100644 --- a/modules/type/blocks/include/dap_chain_block_cache.h +++ b/modules/type/blocks/include/dap_chain_block_cache.h @@ -27,6 +27,8 @@ #include "dap_hash.h" #include "uthash.h" +typedef struct dap_chain_cs_blocks dap_chain_cs_blocks_t; + typedef struct dap_chain_block_cache_tx_index { dap_chain_hash_fast_t tx_hash; @@ -55,6 +57,7 @@ typedef struct dap_chain_block_cache{ // Extracted metadata dap_chain_hash_fast_t prev_hash; dap_chain_hash_fast_t anchor_hash; + dap_chain_hash_fast_t merkle_root; dap_chain_hash_fast_t* links_hash; size_t links_hash_count; @@ -83,10 +86,9 @@ typedef struct dap_chain_block_cache{ int dap_chain_block_cache_init(); void dap_chain_block_cache_deinit(); -dap_chain_block_cache_t * dap_chain_block_cache_get_by_hash(dap_chain_hash_fast_t a_block_hash); -dap_chain_block_cache_t * dap_chain_block_cache_new(dap_chain_block_t * a_block, size_t a_block_size); +dap_chain_block_cache_t * dap_chain_block_cache_new(dap_chain_cs_blocks_t *a_blocks, dap_chain_block_t * a_block, size_t a_block_size); dap_chain_block_cache_t * dap_chain_block_cache_dup(dap_chain_block_cache_t * a_block); -void dap_chain_block_cache_update(dap_chain_block_cache_t * a_block_cache); +int dap_chain_block_cache_update(dap_chain_block_cache_t * a_block_cache); void dap_chain_block_cache_delete(dap_chain_block_cache_t * a_block_cache); dap_chain_datum_tx_t* dap_chain_block_cache_get_tx_by_hash (dap_chain_block_cache_t * a_block_cache, dap_chain_hash_fast_t * a_tx_hash); diff --git a/modules/type/blocks/include/dap_chain_cs_blocks.h b/modules/type/blocks/include/dap_chain_cs_blocks.h index a60432337e1c28e84feaf742dad563eaccb9c7c7..87c662785ea28ca3abd1a8ca0a83e5b54c1df8bd 100644 --- a/modules/type/blocks/include/dap_chain_cs_blocks.h +++ b/modules/type/blocks/include/dap_chain_cs_blocks.h @@ -30,7 +30,8 @@ typedef struct dap_chain_cs_blocks dap_chain_cs_blocks_t; typedef void (*dap_chain_cs_blocks_callback_t)(dap_chain_cs_blocks_t *); -typedef int (*dap_chain_cs_blocks_callback_block_t)(dap_chain_cs_blocks_t *, dap_chain_block_t *,size_t); +typedef int (*dap_chain_cs_blocks_callback_block_t)(dap_chain_cs_blocks_t *, dap_chain_block_t *, size_t); +typedef size_t (*dap_chain_cs_blocks_callback_block_sign_t)(dap_chain_cs_blocks_t *, dap_chain_block_t **, size_t); @@ -50,6 +51,7 @@ typedef struct dap_chain_cs_blocks dap_chain_cs_blocks_callback_t callback_delete; dap_chain_cs_blocks_callback_block_create_t callback_block_create; dap_chain_cs_blocks_callback_block_t callback_block_verify; + dap_chain_cs_blocks_callback_block_sign_t callback_block_sign; void * _pvt; void * _inheritor; } dap_chain_cs_blocks_t; diff --git a/modules/type/dag/dap_chain_cs_dag.c b/modules/type/dag/dap_chain_cs_dag.c index 5ffbea96fa6549b834710ae45423e4b83afa77cf..9434252e15801975b59a977971da968163a505a7 100644 --- a/modules/type/dag/dap_chain_cs_dag.c +++ b/modules/type/dag/dap_chain_cs_dag.c @@ -331,6 +331,11 @@ static int s_dap_chain_add_atom_to_ledger(dap_chain_cs_dag_t * a_dag, dap_ledger } } break; + case DAP_CHAIN_DATUM_CA: { + dap_cert_chain_file_save(l_datum, a_dag->chain->net_name); + return DAP_CHAIN_DATUM_CA; + } + break; default: return -1; } @@ -397,7 +402,8 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_add(dap_chain_t * a_cha case ATOM_ACCEPT: ret = s_chain_callback_atom_verify(a_chain, a_atom, a_atom_size); if(s_debug_more) - log_it(L_DEBUG, "Verified atom %p: code %d", a_atom, ret); + log_it(L_DEBUG, "Verified atom %p: %s", a_atom, ret == ATOM_ACCEPT ? "accepted" : + (ret == ATOM_REJECT ? "rejected" : "thresholded")); break; case ATOM_PASS: if(s_debug_more) { @@ -438,6 +444,11 @@ static dap_chain_atom_verify_res_t s_chain_callback_atom_add(dap_chain_t * a_cha log_it(L_DEBUG, "... tresholded"); ret = ATOM_MOVE_TO_THRESHOLD; break; + case DAP_CHAIN_DATUM_CA: + ret = ATOM_ACCEPT; + if(s_debug_more) + log_it(L_DEBUG, "... DATUM_CA"); + break; default: if (s_debug_more) { l_event_hash_str = dap_chain_hash_fast_to_str_new(&l_event_item->hash);