Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • cellframe/cellframe-sdk
  • MIKA83/cellframe-sdk
2 results
Show changes
Commits on Source (31)
Showing
with 1257 additions and 424 deletions
......@@ -2,7 +2,7 @@ project(cellframe-sdk C)
cmake_minimum_required(VERSION 2.8)
set(CMAKE_C_STANDARD 11)
set(CELLFRAME_SDK_NATIVE_VERSION "2.7-3")
set(CELLFRAME_SDK_NATIVE_VERSION "2.7-4")
add_definitions ("-DCELLFRAME_SDK_VERSION=\"${CELLFRAME_SDK_NATIVE_VERSION}\"")
......
Subproject commit a83c88fcd1a9d89a825d9513d58beac200d3433a
......@@ -57,6 +57,11 @@ if (CELLFRAME_MODULES MATCHES "cs-dag-pos")
add_subdirectory(consensus/dag-pos)
endif()
# Blocks PoA
if (CELLFRAME_MODULES MATCHES "cs-blocks-poa")
add_subdirectory(consensus/block-poa)
endif()
# Service App
if (CELLFRAME_MODULES MATCHES "srv-app")
add_subdirectory(service/app)
......
cmake_minimum_required(VERSION 2.8)
project (dap_chain_cs_block_poa)
file(GLOB DAP_CHAIN_BLOCK_CS_POA_SRCS *.c)
file(GLOB DAP_CHAIN_BLOCK_CS_POA_HEADERS include/*.h)
add_library(${PROJECT_NAME} STATIC ${DAP_CHAIN_BLOCK_CS_POA_SRCS} ${DAP_CHAIN_BLOCK_CS_POA_HEADERS})
add_definitions ("-DDAP_CHAIN_BLOCK_CS_POA")
target_link_libraries(dap_chain_cs_block_poa dap_core dap_crypto dap_chain dap_chain_cs_block )
target_link_libraries(dap_chain_cs_block_poa dap_core dap_crypto dap_chain dap_chain_cs_blocks dap_chain_net_srv_stake)
target_include_directories(dap_chain_cs_block_poa INTERFACE .)
target_include_directories(${PROJECT_NAME} PUBLIC include)
/*
* Authors:
* Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
* DeM Labs Inc. https://demlabs.net
* Kelvin Project https://github.com/kelvinblockchain
* Copyright (c) 2017-2018
* DeM Labs Limited https://demlabs.net
* DAP SDK https://gitlab.demlabs.net/dap/dap-sdk
* Copyright (c) 2017
* All rights reserved.
This file is part of DAP (Deus Applications Prototypes) the open source project
This file is part of DAP SDK the open source project
DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
DAP SDK is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DAP is distributed in the hope that it will be useful,
DAP SDK is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with any DAP based project. If not, see <http://www.gnu.org/licenses/>.
along with any DAP SDK based project. If not, see <http://www.gnu.org/licenses/>.
*/
#include "dap_common.h"
#include "dap_chain_cs_block_poa.h"
#include "dap_strfuncs.h"
#include "dap_enc_base58.h"
#include "dap_cert.h"
#include "dap_chain.h"
#include "dap_chain_block.h"
#include "dap_chain_block_cache.h"
#include "dap_chain_cs_blocks.h"
#include "dap_chain_cs_block_poa.h"
#include "dap_chain_net.h"
#include "dap_chain_node_cli.h"
#include "dap_chain_node_cli_cmd.h"
#include "dap_chain_global_db.h"
#include "dap_chain_cs.h"
#include "dap_chain_cs_blocks.h"
#include "dap_chain_net_srv_stake.h"
#define LOG_TAG "dap_chain_cs_block_poa"
dap_chain_t *s_callback_chain_new();
void s_callback_delete(dap_chain_t * );
void s_callback_blocks(dap_chain_cs_blocks_t *, dap_chain_block_t * );
int dap_chain_cs_block_poa_init()
typedef struct dap_chain_cs_dag_poa_pvt
{
// dap_chain_block_cs_add
dap_cert_t * sign_cert;
dap_cert_t ** auth_certs;
char * auth_certs_prefix;
uint16_t auth_certs_count;
uint16_t auth_certs_count_verify; // Number of signatures, needed for event verification
dap_chain_callback_new_cfg_t prev_callback_created; // global network config init
} dap_chain_cs_block_poa_pvt_t;
#define PVT(a) ((dap_chain_cs_block_poa_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);
// CLI commands
static int s_cli_block_poa(int argc, char ** argv, void *arg_func, char **str_reply);
static bool s_seed_mode = false;
/**
* @brief dap_chain_cs_block_poa_init
* @return
*/
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"
"\tSign new block with certificate <cert name> or withs own PoA certificate\n\n");
return 0;
}
void dap_chain_cs_block_poa_deinit()
/**
* @brief dap_chain_cs_block_poa_deinit
*/
void dap_chain_cs_block_poa_deinit(void)
{
}
/**
* @brief s_cli_block_poa
* @param argc
* @param argv
* @param arg_func
* @param str_reply
* @return
*/
static int s_cli_block_poa(int argc, char ** argv, void *arg_func, char **a_str_reply)
{
(void) arg_func;
int ret = -666;
int arg_index = 1;
dap_chain_net_t * l_chain_net = NULL;
dap_chain_t * l_chain = NULL;
const char * l_hash_out_type = NULL;
dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-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")) {
dap_chain_node_cli_set_reply_text(a_str_reply, "invalid parameter -H, valid values: -H <hex | base58>");
return -1;
}
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);
// Load cert to sign if its present
if (l_cert_str)
l_cert = dap_cert_find_by_name( l_cert_str);
// block hash may be in hex or base58 format
char *l_block_hash_hex_str;
char *l_event_hash_base58_str;
if(!dap_strncmp(l_block_hash_str, "0x", 2) || !dap_strncmp(l_block_hash_str, "0X", 2)) {
l_block_hash_hex_str = dap_strdup(l_block_hash_str);
l_event_hash_base58_str = dap_enc_base58_from_hex_str_to_str(l_block_hash_str);
}
else {
l_block_hash_hex_str = dap_enc_base58_to_hex_str_from_str(l_block_hash_str);
l_event_hash_base58_str = dap_strdup(l_block_hash_str);
}
// Parse block ccmd
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 );
//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);
}
}
return ret;
}
/**
* @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_create(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 );
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);
l_poa_pvt->auth_certs_count_verify = dap_config_get_item_uint16_default(a_chain_cfg,"block-poa","auth_certs_number_verify",0);
l_poa_pvt->auth_certs_prefix = strdup ( dap_config_get_item_str(a_chain_cfg,"block-poa","auth_certs_prefix") );
if (l_poa_pvt->auth_certs_count && l_poa_pvt->auth_certs_count_verify ) {
l_poa_pvt->auth_certs = DAP_NEW_Z_SIZE ( dap_cert_t *, l_poa_pvt->auth_certs_count * sizeof(dap_cert_t));
char l_cert_name[512];
for (size_t i = 0; i < l_poa_pvt->auth_certs_count ; i++ ){
dap_snprintf(l_cert_name,sizeof(l_cert_name),"%s.%lu",l_poa_pvt->auth_certs_prefix, i);
if ( (l_poa_pvt->auth_certs[i] = dap_cert_find_by_name( l_cert_name)) != NULL ) {
log_it(L_NOTICE, "Initialized auth cert \"%s\"", l_cert_name);
} else{
log_it(L_ERROR, "Can't find cert \"%s\"", l_cert_name);
return -1;
}
}
}
}
log_it(L_NOTICE,"Initialized Block-PoA consensus with %u/%u minimum consensus",l_poa_pvt->auth_certs_count,l_poa_pvt->auth_certs_count_verify);
// Save old callback if present and set the call of its own (chain callbacks)
l_poa_pvt->prev_callback_created = l_blocks->chain->callback_created;
l_blocks->chain->callback_created = s_callback_created;
return 0;
}
/**
* @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_poa_t * l_poa = DAP_CHAIN_CS_BLOCK_POA( l_blocks );
// Call previous callback if present. So the first called is the first in
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);
}
return 0;
}
/**
* @brief s_chain_cs_dag_callback_delete
* @param a_dag
*/
static void s_callback_delete(dap_chain_cs_blocks_t * a_blocks)
{
dap_chain_cs_block_poa_t * l_poa = DAP_CHAIN_CS_BLOCK_POA ( a_blocks );
if ( l_poa->_pvt ) {
dap_chain_cs_block_poa_pvt_t * l_poa_pvt = PVT ( l_poa );
if ( l_poa_pvt->auth_certs )
DAP_DELETE ( l_poa_pvt->auth_certs);
if ( l_poa_pvt->auth_certs_prefix )
DAP_DELETE( l_poa_pvt->auth_certs_prefix );
DAP_DELETE ( l_poa->_pvt);
}
if ( l_poa->_inheritor ) {
DAP_DELETE ( l_poa->_inheritor );
}
}
/**
* @brief s_callbac_block_verify
* @param a_blocks
* @param a_block
* @param a_block_size
* @return
*/
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_poa_pvt_t * l_poa_pvt = PVT ( DAP_CHAIN_CS_BLOCK_POA( a_blocks ) );
uint16_t l_signs_verified_count = 0;
// Check for first signature
dap_sign_t * l_sign = dap_chain_block_sign_get(a_block,a_block_size,0);
if (! l_sign){
log_it(L_ERROR, "No any signatures at all for block");
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_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;
}
// 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;
}
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){
l_signs_verified_count++;
break;
}
}
}
return l_signs_verified_count >= l_poa_pvt->auth_certs_count_verify ? 0 : -1;
}
/*
* Authors:
* Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
* DeM Labs Inc. https://demlabs.net
* Kelvin Project https://github.com/kelvinblockchain
* Copyright (c) 2017-2018
* DeM Labs Limited https://demlabs.net
* DAP SDK https://gitlab.demlabs.net/dap/dap-sdk
* Copyright (c) 2017
* All rights reserved.
This file is part of DAP (Deus Applications Prototypes) the open source project
This file is part of DAP SDK the open source project
DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
DAP SDK is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DAP is distributed in the hope that it will be useful,
DAP SDK is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with any DAP based project. If not, see <http://www.gnu.org/licenses/>.
along with any DAP SDK based project. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#pragma once
#include "dap_chain_cs_blocks.h"
typedef struct dap_chain_cs_block_poa
{
dap_chain_t * chain;
dap_chain_cs_blocks_t * blocks;
void * _pvt;
void * _inheritor;
} dap_chain_cs_block_poa_t;
#define DAP_CHAIN_CS_BLOCK_POA(a) ( (dap_chain_cs_block_poa_t *) (a)->_inheritor)
int dap_chain_cs_block_poa_init();
void dap_chain_cs_block_poa_deinit();
int dap_chain_cs_block_poa_init(void);
void dap_chain_cs_block_poa_deinit(void);
/*
* Authors:
* Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
* DeM Labs Inc. https://demlabs.net
* Kelvin Project https://github.com/kelvinblockchain
* Copyright (c) 2017-2019
* DeM Labs Limited https://demlabs.net
* CellFrame SDK https://cellframe.net
* Copyright (c) 2019
* All rights reserved.
This file is part of DAP (Deus Applications Prototypes) the open source project
This file is part of CellFrame SDK the open source project
DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
CellFrame SDK is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DAP is distributed in the hope that it will be useful,
CellFrame SDK is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with any DAP based project. If not, see <http://www.gnu.org/licenses/>.
along with any DAP SDK based project. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
......
/*
* Authors:
* Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net>
* DeM Labs Inc. https://demlabs.net
* Kelvin Project https://github.com/kelvinblockchain
* Copyright (c) 2017-2019
* DeM Labs Limited https://demlabs.net
* CellFrame SDK https://cellframe.net
* Copyright (c) 2019
* All rights reserved.
This file is part of DAP (Deus Applications Prototypes) the open source project
This file is part of CellFrame SDK the open source project
DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify
CellFrame SDK is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DAP is distributed in the hope that it will be useful,
CellFrame SDK is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with any DAP based project. If not, see <http://www.gnu.org/licenses/>.
along with any DAP SDK based project. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "dap_chain_cs_dag.h"
......
......@@ -491,8 +491,7 @@ static int s_net_states_proc(dap_chain_net_t *a_net)
dap_chain_node_client_t *l_node_client = dap_chain_node_client_connect(l_link_info);
if (l_node_client) {
// wait connected
int timeout_ms = 5000; //5 sec = 5000 ms
int res = dap_chain_node_client_wait(l_node_client, NODE_CLIENT_STATE_CONNECTED, timeout_ms);
int res = dap_chain_node_client_wait(l_node_client, NODE_CLIENT_STATE_CONNECTED, 10000 );
if (res == 0 ) {
log_it(L_DEBUG, "Established connection with "NODE_ADDR_FP_STR, NODE_ADDR_FP_ARGS_S(l_link_info->hdr.address));
l_pvt_net->links = dap_list_append(l_pvt_net->links, l_node_client);
......
......@@ -551,7 +551,7 @@ int dap_chain_node_client_wait(dap_chain_node_client_t *a_client, int a_waited_s
#ifndef _WIN32
// prepare for signal waiting
struct timespec l_cond_timeout;
uint32_t l_timeout_s = dap_config_get_item_uint32_default(g_config,"chain_net","status_wait_timeout",10);
uint32_t l_timeout_s = a_timeout_ms/1000;// dap_config_get_item_uint32_default(g_config,"chain_net","status_wait_timeout",10);
clock_gettime( CLOCK_MONOTONIC, &l_cond_timeout);
l_cond_timeout.tv_sec += l_timeout_s;
#else
......
......@@ -37,6 +37,13 @@
#include <io.h>
#endif
#if defined (DAP_OS_LINUX) && !defined (__ANDROID__)
#include <dlfcn.h>
#endif
#include <json-c/json.h>
#include <json-c/json_object.h>
#include <pthread.h>
#include <dirent.h>
......@@ -101,7 +108,12 @@ int dap_chain_net_srv_init(dap_config_t * a_cfg)
" -price_unit <Price Unit> -price_token <Token ticker> [-node_addr <Node Address>] [-tx_cond <TX Cond Hash>] \\\n"
" [-expires <Unix time when expires>] [-ext <Extension with params>]\\\n"
" [-cert <cert name to sign order>]\\\n"
"\tOrder create\n" );
"\tOrder create\n"
"net_srv -net <chain net name> order static [save | delete]\\\n"
"\tStatic nodelist create/delete\n"
"net_srv -net <chain net name> order recheck\\\n"
"\tCheck the availability of orders\n"
);
s_load_all();
return 0;
......@@ -167,6 +179,28 @@ void dap_chain_net_srv_deinit(void)
}
static void* get_cdb_func(const char *func_name)
{
void *l_ref_func = NULL;
// find func from dynamic library
#if defined (DAP_OS_LINUX) && !defined (__ANDROID__)
const char * s_default_path_modules = "var/modules";
const char * l_cdb_so_name = "libcellframe-node-cdb.so";
char *l_lib_path = dap_strdup_printf("%s/%s/%s", g_sys_dir_path, s_default_path_modules, l_cdb_so_name);
void* l_cdb_handle = NULL;
l_cdb_handle = dlopen(l_lib_path, RTLD_NOW);
DAP_DELETE(l_lib_path);
if(!l_cdb_handle) {
log_it(L_ERROR, "Can't load %s module: %s", l_cdb_so_name, dlerror());
}
else {
l_ref_func = dlsym(l_cdb_handle, func_name);
dlclose(l_cdb_handle);
}
#endif
return l_ref_func;
}
/**
* @brief s_cli_net_srv
* @param argc
......@@ -195,7 +229,7 @@ static int s_cli_net_srv( int argc, char **argv, void *arg_func, char **a_str_re
dap_string_t *l_string_ret = dap_string_new("");
const char *l_order_str = NULL;
dap_chain_node_cli_find_option_val(argv, arg_index, argc, "order", &l_order_str);
int l_order_arg_pos = dap_chain_node_cli_find_option_val(argv, arg_index, argc, "order", &l_order_str);
// Order direction
const char *l_direction_str = NULL;
......@@ -518,9 +552,59 @@ static int s_cli_net_srv( int argc, char **argv, void *arg_func, char **a_str_re
dap_string_append_printf( l_string_ret, "Missed some required params\n");
ret=-5;
}
}else if( dap_strcmp( l_order_str, "recheck" ) == 0 ){
//int dap_chain_net_srv_vpn_cdb_server_list_check_orders(dap_chain_net_t *a_net);
int (*dap_chain_net_srv_vpn_cdb_server_list_check_orders)(dap_chain_net_t *a_net) = NULL;
*(void **) (&dap_chain_net_srv_vpn_cdb_server_list_check_orders) = get_cdb_func("dap_chain_net_srv_vpn_cdb_server_list_check_orders");
int l_init_res = dap_chain_net_srv_vpn_cdb_server_list_check_orders ? (*dap_chain_net_srv_vpn_cdb_server_list_check_orders)(l_net) : -5;
//int l_init_res = dap_chain_net_srv_vpn_cdb_server_list_check_orders(l_net);
ret = -10;
}else if( dap_strcmp( l_order_str, "static" ) == 0 ){
// find the subcommand directly after the 'order' command
int l_subcmd_save = dap_chain_node_cli_find_option_val(argv, l_order_arg_pos + 1, l_order_arg_pos + 2, "save", NULL);
int l_subcmd_del = dap_chain_node_cli_find_option_val(argv, l_order_arg_pos + 1, l_order_arg_pos + 2, "delete", NULL) |
dap_chain_node_cli_find_option_val(argv, l_order_arg_pos + 1, l_order_arg_pos + 2, "del", NULL);
int (*dap_chain_net_srv_vpn_cdb_server_list_static_create)(dap_chain_net_t *a_net) = NULL;
int (*dap_chain_net_srv_vpn_cdb_server_list_static_delete)(dap_chain_net_t *a_net) = NULL;
// find func from dinamic library
if(l_subcmd_save || l_subcmd_del) {
*(void **) (&dap_chain_net_srv_vpn_cdb_server_list_static_create) = get_cdb_func("dap_chain_net_srv_vpn_cdb_server_list_static_create");
*(void **) (&dap_chain_net_srv_vpn_cdb_server_list_static_delete) = get_cdb_func("dap_chain_net_srv_vpn_cdb_server_list_static_delete");
}
if(l_subcmd_save) {
int l_init_res = dap_chain_net_srv_vpn_cdb_server_list_static_create ? (*dap_chain_net_srv_vpn_cdb_server_list_static_create)(l_net) : -5;
//int l_init_res = dap_chain_net_srv_vpn_cdb_server_list_static_create(l_net);
if(l_init_res >= 0){
dap_string_append_printf(l_string_ret, "Static node list saved, %d orders in list\n", l_init_res);
ret = 0;
}
else{
dap_string_append_printf(l_string_ret, "Static node list not saved, error code %d\n", l_init_res);
ret = -11;
}
} else if(l_subcmd_del) {
int l_init_res = dap_chain_net_srv_vpn_cdb_server_list_static_delete ? (*dap_chain_net_srv_vpn_cdb_server_list_static_delete)(l_net) : -5;
//int l_init_res = dap_chain_net_srv_vpn_cdb_server_list_static_delete(l_net);
if(!l_init_res){
dap_string_append_printf(l_string_ret, "Static node list deleted\n");
ret = 0;
}
else if(l_init_res > 0){
dap_string_append_printf(l_string_ret, "Static node list already deleted\n");
ret = -12;
}
else
dap_string_append_printf(l_string_ret, "Static node list not deleted, error code %d\n", l_init_res);
} else {
dap_string_append(l_string_ret, "not found subcommand 'save' or 'delete'\n");
ret = -13;
}
} else {
dap_string_append_printf( l_string_ret, "Unknown subcommand \n");
ret=-3;
dap_string_append_printf(l_string_ret, "Unknown subcommand '%s'\n", l_order_str);
ret = -3;
}
dap_chain_node_cli_set_reply_text(a_str_reply, l_string_ret->str);
dap_string_free(l_string_ret, true);
......@@ -551,13 +635,13 @@ dap_chain_net_srv_t* dap_chain_net_srv_add(dap_chain_net_srv_uid_t a_uid,dap_cha
l_srv = DAP_NEW_Z(dap_chain_net_srv_t);
l_srv->uid.uint64 = a_uid.uint64;
l_srv->callback_requested = a_callback_request;
l_srv->callback_receipt_first_success = a_callback_response_success;
l_srv->callback_response_success = a_callback_response_success;
l_srv->callback_response_error = a_callback_response_error;
l_srv->callback_receipt_next_success = a_callback_receipt_next_success;
pthread_mutex_init(&l_srv->banlist_mutex, NULL);
l_sdata = DAP_NEW_Z(service_list_t);
memcpy(&l_sdata->uid, &l_uid, sizeof(l_uid));
l_sdata->srv = l_srv;//DAP_NEW(dap_chain_net_srv_t);
//memcpy(l_sdata->srv, l_srv, sizeof(dap_chain_net_srv_t));
l_sdata->srv = l_srv;
HASH_ADD(hh, s_srv_list, uid, sizeof(l_srv->uid), l_sdata);
}else{
log_it(L_ERROR, "Already present service with 0x%016llX ", a_uid.uint64);
......@@ -617,8 +701,10 @@ void dap_chain_net_srv_del(dap_chain_net_srv_t * a_srv)
pthread_mutex_lock(&s_srv_list_mutex);
HASH_FIND(hh, s_srv_list, a_srv, sizeof(dap_chain_net_srv_uid_t), l_sdata);
if(l_sdata) {
DAP_DELETE(l_sdata);
HASH_DEL(s_srv_list, l_sdata);
pthread_mutex_destroy(&a_srv->banlist_mutex);
DAP_DELETE(a_srv);
DAP_DELETE(l_sdata);
}
pthread_mutex_unlock(&s_srv_list_mutex);
}
......@@ -679,8 +765,10 @@ void dap_chain_net_srv_del_all(void)
pthread_mutex_lock(&s_srv_list_mutex);
HASH_ITER(hh, s_srv_list , l_sdata, l_sdata_tmp)
{
DAP_DELETE(l_sdata);
HASH_DEL(s_srv_list, l_sdata);
pthread_mutex_destroy(&l_sdata->srv->banlist_mutex);
DAP_DELETE(l_sdata->srv);
DAP_DELETE(l_sdata);
}
pthread_mutex_unlock(&s_srv_list_mutex);
}
......
......@@ -134,21 +134,21 @@ bool dap_chain_net_srv_order_set_continent_region(dap_chain_net_srv_order_t **a_
* @param a_continent_num [out]
* @param a_region [out]
*/
bool dap_chain_net_srv_order_get_continent_region(dap_chain_net_srv_order_t *a_order, uint8_t *a_continent_num, char **a_region)
bool dap_chain_net_srv_order_get_continent_region(dap_chain_net_srv_order_t *a_order_static, uint8_t *a_continent_num, char **a_region)
{
if(!a_order || !a_order->ext_size || a_order->ext[0]!=0x52)
if(!a_order_static || !a_order_static->ext_size || a_order_static->ext[0]!=0x52)
return false;
if(a_continent_num) {
if((uint8_t)a_order->ext[1]!=0xff)
memcpy(a_continent_num, a_order->ext + 1, sizeof(uint8_t));
if((uint8_t)a_order_static->ext[1]!=0xff)
memcpy(a_continent_num, a_order_static->ext + 1, sizeof(uint8_t));
else
a_continent_num = 0;
}
if(a_region) {
size_t l_size = a_order->ext_size - sizeof(uint8_t) - 1;
size_t l_size = a_order_static->ext_size - sizeof(uint8_t) - 1;
if(l_size > 0) {
*a_region = DAP_NEW_SIZE(char, l_size);
memcpy(*a_region, a_order->ext + 1 + sizeof(uint8_t), l_size);
memcpy(*a_region, a_order_static->ext + 1 + sizeof(uint8_t), l_size);
}
else
*a_region = NULL;
......@@ -203,9 +203,12 @@ const char* dap_chain_net_srv_order_continent_to_str(int8_t a_num)
int8_t dap_chain_net_srv_order_continent_to_num(const char *a_continent_str)
{
int8_t l_count = dap_chain_net_srv_order_continents_count();
// convert to to upper case
char *l_continent_str = dap_strup(a_continent_str, -1);
for(int8_t i = 1; i < l_count; i++) {
// convert to to upper case
char *l_server_continents = dap_strup(s_server_continents[i], -1);
// compare strings in upper case
if(!dap_strcmp(l_continent_str, l_server_continents)) {
DAP_DELETE(l_server_continents);
DAP_DELETE(l_continent_str);
......@@ -214,7 +217,8 @@ int8_t dap_chain_net_srv_order_continent_to_num(const char *a_continent_str)
DAP_DELETE(l_server_continents);
}
DAP_DELETE(l_continent_str);
return -1;
// none
return 0;
}
char * dap_chain_net_srv_order_create(
......
......@@ -36,18 +36,30 @@ typedef int (*dap_chain_net_srv_callback_data_t)(dap_chain_net_srv_t *, uint32_t
typedef int (*dap_chain_net_srv_callback_sign_request_t)(dap_chain_net_srv_t *, uint32_t, dap_chain_net_srv_client_t *, dap_chain_datum_tx_receipt_t **, size_t );
typedef void (*dap_chain_net_srv_callback_ch_t)(dap_chain_net_srv_t *, dap_stream_ch_t *);
typedef struct dap_chain_net_srv_banlist_item {
dap_chain_hash_fast_t client_pkey_hash;
pthread_mutex_t *ht_mutex;
struct dap_chain_net_srv_banlist_item **ht_head;
UT_hash_handle hh;
} dap_chain_net_srv_banlist_item_t;
typedef struct dap_chain_net_srv
{
dap_chain_net_srv_uid_t uid; // Unique ID for service.
dap_chain_net_srv_abstract_t srv_common;
dap_chain_net_srv_price_t *pricelist;
uint32_t grace_period;
pthread_mutex_t banlist_mutex;
dap_chain_net_srv_banlist_item_t *ban_list;
dap_chain_callback_trafic_t callback_trafic;
// Request for usage
dap_chain_net_srv_callback_data_t callback_requested;
// Receipt first sign successfull
dap_chain_net_srv_callback_data_t callback_receipt_first_success;
dap_chain_net_srv_callback_data_t callback_response_success;
// Response error
dap_chain_net_srv_callback_data_t callback_response_error;
......
......@@ -33,11 +33,7 @@
#include "dap_chain_ledger.h"
#include "dap_chain_net.h"
#include "dap_chain_wallet.h"
//Units of service
//#include "dap_chain_net_srv_stream_session.h"
//Service direction
......@@ -48,8 +44,6 @@ typedef enum dap_chain_net_srv_order_direction{
} dap_chain_net_srv_order_direction_t;
typedef struct dap_chain_net_srv_abstract
{
uint8_t class; //Class of service (once or permanent)
......@@ -89,7 +83,6 @@ typedef struct dap_chain_net_srv_price
struct dap_chain_net_srv_price * prev;
} dap_chain_net_srv_price_t;
// Ch pkt types
#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_REQUEST 0x01
#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_SIGN_REQUEST 0x10
......@@ -117,6 +110,7 @@ typedef struct dap_chain_net_srv_price
#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_RECEIPT_CANT_FIND 0x00000500
#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_RECEIPT_NO_SIGN 0x00000501
#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_RECEIPT_WRONG_PKEY_HASH 0x00000502
#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_RECEIPT_BANNED_PKEY_HASH 0x00000503
#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_PRICE_NOT_FOUND 0x00000600
#define DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_UNKNOWN 0xffffffff
......@@ -186,6 +180,15 @@ typedef struct dap_stream_ch_chain_net_srv_pkt_test{
uint8_t data[];
} DAP_ALIGN_PACKED dap_stream_ch_chain_net_srv_pkt_test_t;
typedef struct dap_chain_net_srv_usage dap_chain_net_srv_usage_t;
typedef struct dap_chain_net_srv_grace {
dap_stream_worker_t *stream_worker;
dap_stream_ch_t *ch;
dap_chain_net_srv_usage_t *usage;
dap_stream_ch_chain_net_srv_pkt_request_t *request;
size_t request_size;
} dap_chain_net_srv_grace_t;
DAP_STATIC_INLINE const char * dap_chain_net_srv_price_unit_uid_to_str( dap_chain_net_srv_price_unit_uid_t a_uid )
{
......
......@@ -124,3 +124,17 @@ DAP_STATIC_INLINE char * dap_chain_net_srv_order_get_gdb_group(dap_chain_net_t *
}
return NULL;
}
/**
* @brief dap_chain_net_srv_order_get_gdb_group_mempool
* @param l_chain
* @return
*/
DAP_STATIC_INLINE char * dap_chain_net_srv_order_get_nodelist_group(dap_chain_net_t * a_net)
{
if ( a_net ) {
const char c_srv_order_group_str[]="service.orders.static_nodelist";
return dap_strdup_printf("%s.%s",a_net->pub.gdb_groups_prefix,c_srv_order_group_str);
}
return NULL;
}
......@@ -37,6 +37,7 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic
#include "dap_chain_wallet.h"
typedef struct dap_chain_net_srv dap_chain_net_srv_t;
typedef struct dap_chain_net_srv_usage{
uint32_t id; // Usage id
pthread_rwlock_t rwlock;
......@@ -53,14 +54,14 @@ typedef struct dap_chain_net_srv_usage{
dap_chain_net_srv_client_t * client;
dap_chain_datum_tx_t * tx_cond;
dap_chain_hash_fast_t tx_cond_hash;
dap_chain_hash_fast_t client_pkey_hash;
char token_ticker[DAP_CHAIN_TICKER_SIZE_MAX];
bool is_active;
bool is_free;
bool is_grace;
UT_hash_handle hh; //
} dap_chain_net_srv_usage_t;
typedef void (*dap_response_success_callback_t) (dap_stream_ch_chain_net_srv_pkt_success_t*, void*);
typedef struct dap_net_stats{
uintmax_t bytes_sent;
uintmax_t bytes_recv;
......@@ -74,10 +75,10 @@ typedef struct dap_net_stats{
} dap_net_stats_t;
typedef struct dap_chain_net_srv_stream_session {
time_t ts_activated;
dap_stream_session_t * parent;
dap_chain_net_srv_usage_t * usages;
dap_chain_net_srv_usage_t * usage_active;
uintmax_t limits_bytes; // Bytes left
time_t limits_ts; // Timestamp until its activte
dap_chain_net_srv_price_unit_uid_t limits_units_type;
......@@ -85,12 +86,8 @@ typedef struct dap_chain_net_srv_stream_session {
// Some common stats
volatile dap_net_stats_t stats;
time_t ts_activated;
dap_sign_t* user_sign; // User's signature for auth if reconnect
dap_response_success_callback_t response_success_callback;
void *response_success_callback_data;
} dap_chain_net_srv_stream_session_t;
#define DAP_CHAIN_NET_SRV_STREAM_SESSION(a) ((dap_chain_net_srv_stream_session_t *) (a)->_inheritor )
......
......@@ -670,14 +670,13 @@ int s_vpn_service_create(dap_config_t * g_config){
l_srv->_inhertor = l_srv_vpn;
l_srv_vpn->parent = l_srv;
uint16_t l_pricelist_count = 0;
// Read if we need to dump all pkt operations
s_debug_more= dap_config_get_item_bool_default(g_config,"srv_vpn", "debug_more",false);
l_srv->grace_period = dap_config_get_item_uint32_default(g_config, "srv_vpn", "grace_period", 60);
//! IMPORTANT ! This fetch is single-action and cannot be further reused, since it modifies the stored config data
//! it also must NOT be freed within this module !
uint16_t l_pricelist_count = 0;
char **l_pricelist = dap_config_get_array_str(g_config, "srv_vpn", "pricelist", &l_pricelist_count); // must not be freed!
for (uint16_t i = 0; i < l_pricelist_count; i++) {
dap_chain_net_srv_price_t *l_price = DAP_NEW_Z(dap_chain_net_srv_price_t);
......@@ -1269,14 +1268,16 @@ void s_ch_packet_in(dap_stream_ch_t* a_ch, void* a_arg)
dap_chain_net_srv_usage_t * l_usage = dap_chain_net_srv_usage_find_unsafe(l_srv_session, l_ch_vpn->usage_id);
if ( ! l_usage){
log_it(L_NOTICE, "No active usage in list, possible disconnected. Send nothin on this channel");
log_it(L_NOTICE, "No active usage in list, possible disconnected. Send nothing on this channel");
dap_stream_ch_set_ready_to_write_unsafe(a_ch,false);
dap_stream_ch_set_ready_to_read_unsafe(a_ch,false);
return;
}
if ( ! l_usage->is_active ){
log_it(L_INFO, "Usage inactivation: switch off packet input channel");
log_it(L_INFO, "Usage inactivation: switch off packet input & output channels");
if (l_usage->client)
dap_stream_ch_pkt_write_unsafe( l_usage->client->ch , DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_NOTIFY_STOPPED , NULL, 0 );
dap_stream_ch_set_ready_to_write_unsafe(a_ch,false);
dap_stream_ch_set_ready_to_read_unsafe(a_ch,false);
return;
......@@ -1413,26 +1414,26 @@ static void s_ch_packet_out(dap_stream_ch_t* a_ch, void* a_arg)
dap_chain_net_srv_usage_t * l_usage = dap_chain_net_srv_usage_find_unsafe(l_srv_session, l_ch_vpn->usage_id);
if ( ! l_usage){
log_it(L_NOTICE, "No active usage in list, possible disconnected. Send nothin on this channel");
log_it(L_NOTICE, "No active usage in list, possible disconnected. Send nothing on this channel");
dap_stream_ch_set_ready_to_write_unsafe(a_ch,false);
dap_stream_ch_set_ready_to_read_unsafe(a_ch,false);
return;
}
if ( ! l_usage->is_active ){
log_it(L_INFO, "Usage inactivation: switch off packet output channel");
dap_stream_ch_set_ready_to_write_unsafe(a_ch,false);
dap_stream_ch_set_ready_to_read_unsafe(a_ch,false);
log_it(L_INFO, "Usage inactivation: switch off packet input & output channels");
if (l_usage->client)
dap_stream_ch_pkt_write_unsafe( l_usage->client->ch , DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_NOTIFY_STOPPED , NULL, 0 );
dap_stream_ch_set_ready_to_write_unsafe(a_ch,false);
dap_stream_ch_set_ready_to_read_unsafe(a_ch,false);
return;
}
if ( (! l_usage->is_free) && (! l_usage->receipt) ){
log_it(L_WARNING, "No active receipt, switching off");
dap_stream_ch_set_ready_to_write_unsafe(a_ch,false);
dap_stream_ch_set_ready_to_read_unsafe(a_ch,false);
if (l_usage->client)
dap_stream_ch_pkt_write_unsafe( l_usage->client->ch , DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_NOTIFY_STOPPED , NULL, 0 );
dap_stream_ch_set_ready_to_write_unsafe(a_ch,false);
dap_stream_ch_set_ready_to_read_unsafe(a_ch,false);
return;
}
// Check for empty buffer out here to prevent warnings in worker
......
......@@ -70,7 +70,7 @@ dap_chain_block_t * dap_chain_block_new(dap_chain_hash_fast_t * a_prev_block )
l_block->hdr.ts_created = time(NULL);
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{
log_it(L_INFO, "Genesis block produced");
}
......@@ -80,36 +80,376 @@ dap_chain_block_t * dap_chain_block_new(dap_chain_hash_fast_t * a_prev_block )
}
// Add metadata in block
size_t dap_chain_block_meta_add(dap_chain_block_t * a_block, size_t a_block_size, uint8_t a_meta_type, const void * a_data, size_t a_data_size)
/**
* @brief s_block_get_datum_offset
* @param a_block
* @param a_block_size
* @return
*/
size_t s_block_get_datum_offset (dap_chain_block_t * a_block, size_t a_block_size)
{
return 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));
}
size_t l_offset = 0;
dap_chain_block_meta_t * l_meta=NULL;
for( size_t i = 0; i< a_block->hdr.meta_count &&
l_offset < (a_block_size-sizeof (a_block->hdr)) &&
sizeof (l_meta->hdr) <= (a_block_size-sizeof (a_block->hdr)) - l_offset ; i++){
l_meta =(dap_chain_block_meta_t *) (a_block->meta_n_datum_n_sign +l_offset);
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_offset += sizeof (l_meta->hdr);
l_offset += l_meta_data_size;
}else
l_offset = (a_block_size-sizeof (a_block->hdr));
}
return l_offset;
}
//
/**
* @brief dap_chain_block_meta_add
* @details Add metadata in block
* @param a_block_ptr
* @param a_block_size
* @param a_meta_type
* @param a_data
* @param a_data_size
* @return
*/
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)
{
assert(a_block_ptr);
dap_chain_block_t * l_block = *a_block_ptr;
dap_chain_block_meta_t * l_meta = NULL;
if( a_block_size < sizeof(l_block->hdr) ){
log_it(L_ERROR,"Meta add: Corrupted block size %zd thats smaller then block header size %zd ", a_block_size, sizeof (l_block->hdr));
return 0;
}
if(l_block->hdr.meta_count == UINT16_MAX){
log_it(L_ERROR,"Meta add: Can't add more, maximum meta count %u is achieved", UINT16_MAX);
return 0;
}
if( UINT32_MAX - l_block->hdr.meta_n_datum_n_signs_size < a_data_size + sizeof (l_meta->hdr) ){
log_it(L_ERROR,"Meta add: Can't add more, maximum block data section size %zd achieved", UINT32_MAX);
return 0;
}
size_t dap_chain_block_datum_add(dap_chain_block_t * a_block, size_t a_block_size, dap_chain_datum_t * a_datum, size_t a_datum_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;
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);
}
return l_offset+sizeof (l_block->hdr);
}
/**
* @brief dap_chain_block_datum_add
* @param a_block_ptr
* @param a_block_size
* @param a_datum
* @param a_datum_size
* @return
*/
size_t dap_chain_block_datum_add(dap_chain_block_t ** a_block_ptr, size_t a_block_size, dap_chain_datum_t * a_datum, size_t a_datum_size)
{
if ( a_block) {
//
assert(a_block_ptr);
dap_chain_block_t * l_block = *a_block_ptr;
assert(l_block);
assert(a_datum_size);
size_t l_offset = s_block_get_datum_offset(l_block,a_block_size);
dap_chain_datum_t * l_datum =(dap_chain_datum_t *) (l_block->meta_n_datum_n_sign + l_offset);
// Pass all datums to the end
for(size_t n=0; n<l_block->hdr.datum_count && l_offset<(a_block_size-sizeof (l_block->hdr)) ; n++){
size_t l_datum_size = dap_chain_datum_size(l_datum);
// Check if size 0
if(! l_datum_size){
log_it(L_ERROR,"Datum size is 0, smth is corrupted in block");
return a_block_size;
}
// Check if size of of block size
if (l_datum_size+l_offset >(a_block_size-sizeof (l_block->hdr))){
log_it(L_ERROR,"Datum size is too big %zf thats with offset %zd is bigger than block size %zd (without header)", l_datum_size, l_offset,
(a_block_size-sizeof (l_block->hdr)));
return a_block_size;
}
// update offset and current datum pointer
l_offset += l_datum_size;
l_datum =(dap_chain_datum_t *) (l_block->meta_n_datum_n_sign + l_offset);
}
if (l_offset> (a_block_size-sizeof (l_block->hdr))){
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 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);
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);
}else{
log_it(L_ERROR, "Block is NULL");
log_it(L_ERROR,"");
return a_block_size;
}
}
/**
* @brief dap_chain_block_datum_del_by_hash
* @param a_block_ptr
* @param a_block_size
* @param a_datum_hash
* @return
*/
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)
{
assert(a_block_ptr);
dap_chain_block_t * l_block = *a_block_ptr;
assert(l_block);
assert(a_datum_hash);
if(a_block_size>=sizeof (l_block->hdr)){
log_it(L_ERROR, "Corrupted block, block size %zd is lesser than block header size %zd", a_block_size,sizeof (l_block->hdr));
return 0;
}
size_t l_offset = s_block_get_datum_offset(l_block,a_block_size);
dap_chain_datum_t * l_datum =(dap_chain_datum_t *) (l_block->meta_n_datum_n_sign + l_offset);
// Pass all datums to the end
for(size_t n=0; n<l_block->hdr.datum_count && l_offset<(a_block_size-sizeof (l_block->hdr)) ; n++){
size_t l_datum_size = dap_chain_datum_size(l_datum);
// Check if size 0
if(! l_datum_size){
log_it(L_ERROR,"Datum size is 0, smth is corrupted in block");
return a_block_size;
}
// Check if size of of block size
if (l_datum_size+l_offset >(a_block_size-sizeof (l_block->hdr))){
log_it(L_ERROR,"Datum size is too big %zf thats with offset %zd is bigger than block size %zd(without hdr)", l_datum_size, l_offset,
(a_block_size-sizeof (l_block->hdr)));
return a_block_size;
}
// Calc current datum hash
dap_chain_hash_fast_t l_datum_hash;
dap_hash_fast(l_datum,l_datum_size,&l_datum_hash);
// Check datum hash and delete if compares successfuly
if (dap_hash_fast_compare(&l_datum_hash,a_datum_hash)){
memmove(l_datum, (byte_t*)l_datum +l_datum_size,(a_block_size-sizeof (l_block->hdr))-l_offset-l_datum_size );
*a_block_ptr = l_block = DAP_REALLOC(l_block, a_block_size - l_datum_size);
l_block->hdr.datum_count--;
l_block->hdr.meta_n_datum_n_signs_size -= l_datum_size;
// here we don't update offset
}else{
// update offset
l_offset += l_datum_size;
}
// Updae current datum pointer, if it was deleted - we also need to update it after realloc
l_datum =(dap_chain_datum_t *) (l_block->meta_n_datum_n_sign + l_offset);
}
if (l_offset> (a_block_size-sizeof (l_block->hdr))){
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;
}
return l_offset;
}
/**
* @brief s_block_get_sign_offset
* @param a_block
* @param a_block_size
* @return
*/
static size_t s_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));
return 0;
}
size_t l_offset = s_block_get_datum_offset(a_block,a_block_size);
dap_chain_datum_t * l_datum =(dap_chain_datum_t *) (a_block->meta_n_datum_n_sign + l_offset);
// Pass all datums to the end
for(size_t n=0; n<a_block->hdr.datum_count && l_offset< (a_block_size-sizeof (a_block->hdr)) ; n++){
size_t l_datum_size = dap_chain_datum_size(l_datum);
// Check if size 0
if(! l_datum_size){
log_it(L_ERROR,"Datum size is 0, smth is corrupted in block");
return a_block_size;
}
// Check if size of of block size
if ( (l_datum_size+l_offset) > (a_block_size-sizeof (a_block->hdr)) ){
log_it(L_ERROR,"Datum size is too big %zf thats with offset %zd is bigger than block size %zd", l_datum_size, l_offset, a_block_size);
return a_block_size;
}
l_offset += l_datum_size;
// Updae current datum pointer, if it was deleted - we also need to update it after realloc
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);
return a_block_size;
}
return l_offset;
}
size_t dap_chain_block_datum_del_by_hash(dap_chain_block_t * a_block, size_t a_block_size, dap_chain_hash_fast_t* a_datum_hash)
/**
* @brief dap_chain_block_sign_add
* @param a_block_ptr
* @param a_block_size
* @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 )
{
return a_block_size;
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);
size_t l_block_sign_size = dap_sign_get_size(l_block_sign);
*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 );
DAP_DELETE(l_block_sign);
return a_block_size+l_block_sign_size;
}
/**
* @brief dap_chain_block_sign_get
* @param a_block
* @param a_block_size
* @param a_sign_num
* @return
*/
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_sign_size = dap_sign_get_size(l_sign);
if (!l_sign){
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 );
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;
}
/**
* @brief dap_chain_block_get_datums
* @param a_block
* @param a_block_size
* @param a_datums_count
* @return
*/
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 )
{
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));
return NULL;
}
assert(a_datums_count);
*a_datums_count = a_block->hdr.datum_count;
if (a_block->hdr.datum_count == 0)
return NULL;
size_t l_offset = s_block_get_datum_offset(a_block,a_block_size);
dap_chain_datum_t * l_datum =(dap_chain_datum_t *) (a_block->meta_n_datum_n_sign + l_offset);
dap_chain_datum_t ** l_ret =DAP_NEW_Z_SIZE( dap_chain_datum_t *, sizeof (dap_chain_datum_t *)* a_block->hdr.datum_count);
for(size_t n=0; n<a_block->hdr.datum_count && l_offset<(a_block_size-sizeof (a_block->hdr)) ; n++){
size_t l_datum_size = dap_chain_datum_size(l_datum);
// Check if size 0
if(! l_datum_size){
log_it(L_ERROR,"Datum size in block is 0");
return l_ret;
}
// Check if size of of block size
if (l_datum_size+l_offset >(a_block_size-sizeof (a_block->hdr))){
log_it(L_ERROR,"Datum size is too big %zf thats with offset %zd is bigger than block size %zd (without header)", l_datum_size, l_offset,
(a_block_size-sizeof (a_block->hdr)));
return l_ret;
}
l_ret[n] = l_datum;
(*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)));
}
return l_ret;
}
/**
* @brief dap_chain_block_get_meta
* @param a_block
* @param a_block_size
* @param a_meta_count
* @return
*/
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 %zd thats smaller then block header size %zd ", 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
return NULL;
size_t l_offset = 0;
dap_chain_block_meta_t * l_meta=NULL;
dap_chain_block_meta_t ** l_ret = DAP_NEW_Z_SIZE(dap_chain_block_meta_t *,sizeof (dap_chain_block_meta_t *)* a_block->hdr.meta_count );
for( size_t i = 0; i< a_block->hdr.meta_count &&
l_offset < (a_block_size-sizeof (a_block->hdr)) &&
sizeof (l_meta->hdr) <= (a_block_size-sizeof (a_block->hdr)) - l_offset ; i++){
l_meta =(dap_chain_block_meta_t *) (a_block->meta_n_datum_n_sign +l_offset);
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));
}
return l_ret;
}
/**
......@@ -163,10 +503,10 @@ void dap_chain_block_meta_extract(dap_chain_block_meta_t ** a_meta, size_t a_met
}
l_was_prev = true;
if (a_block_prev_hash){
if (l_meta->hdr.size == sizeof (*a_block_prev_hash) )
memcpy(a_block_prev_hash, l_meta->data, l_meta->hdr.size);
if (l_meta->hdr.data_size == sizeof (*a_block_prev_hash) )
memcpy(a_block_prev_hash, l_meta->data, l_meta->hdr.data_size);
else
log_it(L_WARNING, "Meta #%zd PREV has wrong size %zd when expecting %zd",i, l_meta->hdr.size, sizeof (*a_block_prev_hash));
log_it(L_WARNING, "Meta #%zd PREV has wrong size %zd when expecting %zd",i, l_meta->hdr.data_size, sizeof (*a_block_prev_hash));
}
break;
case DAP_CHAIN_BLOCK_META_ANCHOR:
......@@ -176,10 +516,10 @@ void dap_chain_block_meta_extract(dap_chain_block_meta_t ** a_meta, size_t a_met
}
l_was_anchor = true;
if ( a_block_anchor_hash){
if (l_meta->hdr.size == sizeof (*a_block_anchor_hash) )
memcpy(a_block_anchor_hash, l_meta->data, l_meta->hdr.size);
if (l_meta->hdr.data_size == sizeof (*a_block_anchor_hash) )
memcpy(a_block_anchor_hash, l_meta->data, l_meta->hdr.data_size);
else
log_it(L_WARNING, "Anchor meta #%zd has wrong size %zd when expecting %zd",i, l_meta->hdr.size, sizeof (*a_block_prev_hash));
log_it(L_WARNING, "Anchor meta #%zd has wrong size %zd when expecting %zd",i, l_meta->hdr.data_size, sizeof (*a_block_prev_hash));
}
break;
case DAP_CHAIN_BLOCK_META_LINK:
......@@ -192,11 +532,11 @@ void dap_chain_block_meta_extract(dap_chain_block_meta_t ** a_meta, size_t a_met
*a_block_links = DAP_REALLOC(*a_block_links, l_links_count_max);
}
if (l_meta->hdr.size == sizeof (**a_block_links) ){
memcpy(&a_block_links[*a_block_links_count], l_meta->data, l_meta->hdr.size);
if (l_meta->hdr.data_size == sizeof (**a_block_links) ){
memcpy(&a_block_links[*a_block_links_count], l_meta->data, l_meta->hdr.data_size);
(*a_block_links_count)++;
}else
log_it(L_WARNING, "Link meta #%zd has wrong size %zd when expecting %zd", i, l_meta->hdr.size, sizeof (*a_block_prev_hash));
log_it(L_WARNING, "Link meta #%zd has wrong size %zd when expecting %zd", i, l_meta->hdr.data_size, sizeof (*a_block_prev_hash));
}
break;
case DAP_CHAIN_BLOCK_META_NONCE:
......@@ -207,10 +547,10 @@ void dap_chain_block_meta_extract(dap_chain_block_meta_t ** a_meta, size_t a_met
l_was_nonce = true;
if ( a_nonce){
if (l_meta->hdr.size == sizeof (*a_nonce ) )
memcpy(a_nonce, l_meta->data, l_meta->hdr.size);
if (l_meta->hdr.data_size == sizeof (*a_nonce ) )
memcpy(a_nonce, l_meta->data, l_meta->hdr.data_size);
else
log_it(L_WARNING, "NONCE meta #%zd has wrong size %zd when expecting %zd",i, l_meta->hdr.size, sizeof (*a_nonce));
log_it(L_WARNING, "NONCE meta #%zd has wrong size %zd when expecting %zd",i, l_meta->hdr.data_size, sizeof (*a_nonce));
}
break;
case DAP_CHAIN_BLOCK_META_NONCE2:
......@@ -220,10 +560,10 @@ void dap_chain_block_meta_extract(dap_chain_block_meta_t ** a_meta, size_t a_met
}
l_was_nonce2 = true;
if ( a_nonce2){
if (l_meta->hdr.size == sizeof (*a_nonce2 ) )
memcpy(a_nonce2, l_meta->data, l_meta->hdr.size);
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 %zd when expecting %zd",i, l_meta->hdr.size, sizeof (*a_nonce2));
log_it(L_WARNING, "NONCE2 meta #%zd has wrong size %zd when expecting %zd",i, l_meta->hdr.data_size, sizeof (*a_nonce2));
}
break;
default: { log_it(L_WARNING, "Unknown meta #%zd type 0x%02x (size %zd), possible corrupted block or you need to upgrade your software",
......
......@@ -92,6 +92,46 @@ void dap_chain_block_cache_update(dap_chain_block_cache_t * a_block_cache)
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);
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->links_hash,
&a_block_cache->links_hash_count,
&a_block_cache->is_genesis,
&a_block_cache->nonce,
&a_block_cache->nonce2
);
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){
dap_chain_hash_fast_t l_tx_hash;
dap_chain_block_cache_tx_index_t * l_tx_index = NULL;
dap_hash_fast(l_datum->data,l_datum->header.data_size, &l_tx_hash);
HASH_FIND(hh, a_block_cache->tx_index, &l_tx_hash, sizeof (l_tx_hash), l_tx_index);
if ( ! l_tx_index ){
l_tx_index = DAP_NEW_Z(dap_chain_block_cache_tx_index_t);
memcpy(&l_tx_index->tx_hash,&l_tx_hash, sizeof (l_tx_hash) );
l_tx_index->tx =(dap_chain_datum_tx_t*) l_datum->data;
HASH_ADD(hh, a_block_cache->tx_index, tx_hash, sizeof (l_tx_hash), l_tx_index);
}
}
}
}
/**
* @brief dap_chain_block_cache_get_tx_by_hash
* @param a_block_cache
* @param a_tx_hash
* @return
*/
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)
{
dap_chain_block_cache_tx_index_t * l_tx_index = NULL;
HASH_FIND(hh, a_block_cache->tx_index, a_tx_hash,sizeof (*a_tx_hash), l_tx_index);
return l_tx_index? l_tx_index->tx : NULL;
}
/**
......@@ -103,3 +143,4 @@ 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");
}