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
Showing
with 863 additions and 660 deletions
/*
* Authors:
* Alexey V. Stratulat <alexey.stratulat@demlabs.net>
* Olzhas Zharasbaev <oljas.jarasbaev@demlabs.net>
* DeM Labs Inc. https://demlabs.net
* DeM Labs Open source community https://gitlab.demlabs.net/cellframe/cellframe-sdk
* Copyright (c) 2017-2023
* All rights reserved.
This file is part of DAP (Demlabs Application Protocol) the open source project
DAP (Demlabs Application Protocol) is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DAP is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with any DAP based project. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "dap_chain_datum_token.h"
#include "dap_json_rpc_errors.h"
json_object *dap_chain_datum_token_to_json(dap_chain_datum_token_t * a_token, size_t a_token_size);
json_object *dap_chain_datum_token_flags_to_json(uint16_t a_flags);
json_object *dap_chain_datum_emission_to_json(dap_chain_datum_token_emission_t *a_emission, size_t a_emission_size);
/*
* Authors:
* Alexey V. Stratulat <alexey.stratulat@demlabs.net>
* Olzhas Zharasbaev <oljas.jarasbaev@demlabs.net>
* DeM Labs Inc. https://demlabs.net
* DeM Labs Open source community https://gitlab.demlabs.net/cellframe/cellframe-sdk
* Copyright (c) 2017-2023
* All rights reserved.
This file is part of DAP (Demlabs Application Protocol) the open source project
DAP (Demlabs Application Protocol) is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DAP is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with any DAP based project. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "dap_chain_datum_tx.h"
#include "dap_json_rpc_errors.h"
json_object * dap_chain_datum_tx_to_json(dap_chain_datum_tx_t *a_tx, dap_chain_net_id_t *a_net_id);
/*
* Authors:
* Alexey V. Stratulat <alexey.stratulat@demlabs.net>
* Olzhas Zharasbaev <oljas.jarasbaev@demlabs.net>
* DeM Labs Inc. https://demlabs.net
* DeM Labs Open source community https://gitlab.demlabs.net/cellframe/cellframe-sdk
* Copyright (c) 2017-2023
* All rights reserved.
This file is part of DAP (Demlabs Application Protocol) the open source project
DAP (Demlabs Application Protocol) is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DAP is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with any DAP based project. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "dap_chain_datum_tx_items.h"
#include "dap_json_rpc_errors.h"
json_object *dap_chain_datum_tx_item_in_ems_to_json(const dap_chain_tx_in_ems_t *a_in_ems);
json_object* dap_chain_datum_tx_item_in_to_json(dap_chain_tx_in_t *a_in);
json_object* dap_chain_datum_tx_item_in_reward_to_json(dap_chain_tx_in_reward_t *a_in_reward);
json_object* dap_chain_datum_tx_item_tsd_to_json(dap_chain_tx_tsd_t *a_tsd);
json_object* dap_chain_datum_tx_item_in_cond_to_json(dap_chain_tx_in_cond_t *a_in_cond);
json_object* dap_chain_datum_tx_item_out_to_json(const dap_chain_tx_out_t *a_out);
json_object* dap_chain_datum_tx_item_out_ext_to_json(const dap_chain_tx_out_ext_t *a_out_ext);
json_object *dap_chain_datum_tx_item_out_cond_fee_to_json(dap_chain_tx_out_cond_t *a_fee);
json_object *dap_chain_datum_tx_item_out_cond_srv_pay_to_json(dap_chain_tx_out_cond_t *item);
json_object* dap_chain_datum_tx_item_out_cond_srv_xchange_to_json(dap_chain_tx_out_cond_t* a_srv_xchange);
json_object *dap_chain_datum_tx_item_out_cond_srv_stake_to_json(dap_chain_tx_out_cond_t* a_srv_stake);
json_object *dap_chain_net_srv_stake_lock_cond_out_to_json(dap_chain_tx_out_cond_t *a_stake_lock);
json_object* dap_chain_datum_tx_item_sig_to_json(const dap_chain_tx_sig_t *a_sig);
/*
* Authors:
* Alexey V. Stratulat <alexey.stratulat@demlabs.net>
* Olzhas Zharasbaev <oljas.jarasbaev@demlabs.net>
* DeM Labs Inc. https://demlabs.net
* DeM Labs Open source community https://gitlab.demlabs.net/cellframe/cellframe-sdk
* Copyright (c) 2017-2023
* All rights reserved.
This file is part of DAP (Demlabs Application Protocol) the open source project
DAP (Demlabs Application Protocol) is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DAP is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with any DAP based project. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "dap_chain_datum_tx_receipt.h"
#include "dap_json_rpc_errors.h"
json_object *dap_chain_receipt_info_to_json(dap_chain_receipt_info_t *a_info);
json_object *dap_chain_datum_tx_receipt_to_json(dap_chain_datum_tx_receipt_t *a_receipt);
\ No newline at end of file
cmake_minimum_required(VERSION 3.10)
project (dap_json_rpc_chain_mempool)
file(GLOB DAP_JSON_RPC_CHAIN_MEMPOOL_HEADERS include/*.h)
file(GLOB DAP_JSON_RPC_CHAIN_MEMPOOL_SRCS *.c)
add_library(${PROJECT_NAME} STATIC ${DAP_JSON_RPC_CHAIN_MEMPOOL_SRCS} ${DAP_JSON_RPC_CHAIN_MEMPOOL_HEADERS})
target_link_libraries(dap_json_rpc_chain_mempool dap_http_server dap_client dap_chain_net dap_global_db dap_core dap_chain_cs_blocks dap_chain_mempool dap_json_rpc_core dap_chain_btc_rpc)
target_include_directories(dap_json_rpc_chain_mempool PUBLIC include/ )
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <memory.h>
#ifdef _WIN32
#include <winsock2.h>
#include <windows.h>
#include <mswsock.h>
#include <ws2tcpip.h>
#include <io.h>
#include <time.h>
#include <pthread.h>
#endif
#include "dap_common.h"
#include "dap_hash.h"
#include "dap_http_client.h"
#include "dap_http_simple.h"
#include "dap_enc_base58.h"
#include "dap_enc_http.h"
#include "http_status_code.h"
#include "dap_chain_common.h"
#include "dap_chain_node.h"
#include "dap_global_db.h"
#include "dap_enc.h"
#include <dap_enc_http.h>
#include <dap_enc_key.h>
#include <dap_enc_ks.h>
#include "dap_chain_mempool.h"
#include "dap_common.h"
#include "dap_list.h"
#include "dap_chain.h"
#include "dap_chain_net.h"
#include "dap_chain_net_tx.h"
#include "dap_sign.h"
#include "dap_chain_datum_tx.h"
#include "dap_chain_datum_tx_items.h"
#include "dap_chain_net_srv.h"
#include "dap_chain_cs_blocks.h"
#include "dap_chain_mempool_rpc.h"
#include "dap_json_rpc_chain_datum.h"
#include "dap_json_rpc_request_handler.h"
#include "dap_json_rpc_response_handler.h"
#include "json.h"
#define LOG_TAG "dap_chain_mempool_rpc"
int dap_chain_mempool_rpc_init(void) {
dap_json_rpc_registration_request_handler("mempool_list", dap_chain_mempool_rpc_handler_list);
dap_json_rpc_registration_request_handler("memtest", dap_chain_mempool_rpc_handler_test);
return 0;
}
void dap_chain_mempool_rpc_handler_test(dap_json_rpc_params_t *a_params,
dap_json_rpc_response_t *a_response, const char *a_method) {
UNUSED(a_method);
char *l_tn = NULL;
// char *l_chain_str = NULL;
for (uint32_t i = 0; i < a_params->length; i++) {
dap_json_rpc_param_t *l_prm = a_params->params[i];
if (i == 0)
l_tn = l_prm->value_param;
}
if (dap_strcmp(l_tn, "NULL") == 0) {
a_response->type = TYPE_RESPONSE_NULL;
} else if (dap_strcmp(l_tn, "STRING") == 0) {
a_response->type = TYPE_RESPONSE_STRING;
a_response->result_string = dap_strdup("This test string");
} else if (dap_strcmp(l_tn, "INTEGER") == 0) {
a_response->type = TYPE_RESPONSE_INTEGER;
a_response->result_int = 4555745;
} else if (dap_strcmp(l_tn, "BOOLEAN") == 0) {
a_response->type = TYPE_RESPONSE_BOOLEAN;
a_response->result_boolean = true;
} else if (dap_strcmp(l_tn, "DOUBLE") == 0) {
a_response->type = TYPE_RESPONSE_DOUBLE;
a_response->result_double = 75.545;
} else if (dap_strcmp(l_tn, "JSON") == 0) {
a_response->type = TYPE_RESPONSE_JSON;
json_object *l_obj = json_object_new_object();
json_object *l_int = json_object_new_uint64(45577445);
json_object *l_boolean = json_object_new_boolean((json_bool)1);
json_object *l_double = json_object_new_double(457.74514);
json_object *l_arr = json_object_new_array();
for (int i = 1000; i < 1997; i++) {
json_object *l_cur = json_object_new_int(i);
json_object_array_add(l_arr, l_cur);
}
json_object_object_add(l_obj, "int", l_int);
json_object_object_add(l_obj, "boolean", l_boolean);
json_object_object_add(l_obj, "double", l_double);
json_object_object_add(l_obj, "array", l_arr);
a_response->result_json_object = json_object_get(l_obj);
json_object_put(l_obj);
} else {
//set ERR code
}
}
void dap_chain_mempool_rpc_handler_list(dap_json_rpc_params_t *a_params,
dap_json_rpc_response_t *a_response, const char *a_method) {
char *l_net_str = NULL;
char *l_chain_str = NULL;
for (uint32_t i = 0; i < a_params->length; i++) {
dap_json_rpc_param_t *l_prm = a_params->params[i];
if (i == 0)
l_net_str = l_prm->value_param;
if (i == 1)
l_chain_str = l_prm->value_param;
}
dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str);
dap_chain_t *l_chain = dap_chain_net_get_chain_by_name(l_net, l_chain_str);
a_response->type = TYPE_RESPONSE_STRING;
char * l_gdb_group_mempool = dap_chain_net_get_gdb_group_mempool_new(l_chain);
if(!l_gdb_group_mempool){
a_response->result_string = "{\"datums\":[]}";
return;
}
size_t l_objs_size = 0;
dap_global_db_obj_t *l_objs = dap_global_db_get_all_sync(l_gdb_group_mempool, &l_objs_size);
json_object *l_object = json_object_new_object();
json_object *l_object_array = json_object_new_array();
for(size_t i = 0; i < l_objs_size; i++) {
dap_chain_datum_t *l_datum = (dap_chain_datum_t *)l_objs[i].value;
//dap_time_t l_ts_create = (dap_time_t) l_datum->header.ts_create;
if (!l_datum->header.data_size || (l_datum->header.data_size > l_objs[i].value_len)) {
log_it(L_ERROR, "Trash datum in GDB %s.%s, key: %s data_size:%u, value_len:%zu",
l_net->pub.name, l_chain->name, l_objs[i].key, l_datum->header.data_size, l_objs[i].value_len);
dap_global_db_del(l_gdb_group_mempool, l_objs[i].key, NULL, NULL);
continue;
}
json_object *l_obj_datum = dap_chain_datum_to_json(l_datum);
json_object_array_add(l_object_array, l_obj_datum);
}
json_object_object_add(l_object, "datums", l_object_array);
a_response->type = TYPE_RESPONSE_JSON;
a_response->result_json_object = l_object;
DAP_DELETE(l_gdb_group_mempool);
}
#undef LOG_TAG
/*
* Authors:
* Alexey V. Stratulat <alexey.stratulat@demlabs.net>
* Olzhas Zharasbaev <oljas.jarasbaev@demlabs.net>
* DeM Labs Inc. https://demlabs.net
* DeM Labs Open source community https://gitlab.demlabs.net/cellframe/cellframe-sdk
* Copyright (c) 2017-2023
* All rights reserved.
This file is part of DAP (Demlabs Application Protocol) the open source project
DAP (Demlabs Application Protocol) is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DAP is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with any DAP based project. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "dap_json_rpc_errors.h"
#include "dap_json_rpc_response.h"
#include "dap_json_rpc_params.h"
int dap_chain_mempool_rpc_init(void);
void dap_chain_mempool_rpc_handler_list(dap_json_rpc_params_t *a_params,
dap_json_rpc_response_t *a_response, const char *a_method);
void dap_chain_mempool_rpc_handler_test(dap_json_rpc_params_t *a_params,
dap_json_rpc_response_t *a_response, const char *a_method);
......@@ -383,7 +383,7 @@ char *dap_chain_mempool_tx_coll_fee_create(dap_chain_cs_blocks_t *a_blocks, dap_
// Check and apply sovereign tax for this key
uint256_t l_value_tax = {};
dap_chain_net_srv_stake_item_t *l_key_item = dap_chain_net_srv_stake_check_pkey_hash(&l_sign_pkey_hash);
dap_chain_net_srv_stake_item_t *l_key_item = dap_chain_net_srv_stake_check_pkey_hash(l_chain->net_id, &l_sign_pkey_hash);
if (l_key_item && !IS_ZERO_256(l_key_item->sovereign_tax) &&
!dap_chain_addr_is_blank(&l_key_item->sovereign_addr)) {
MULT_256_COIN(l_value_out, l_key_item->sovereign_tax, &l_value_tax);
......@@ -512,7 +512,7 @@ char *dap_chain_mempool_tx_reward_create(dap_chain_cs_blocks_t *a_blocks, dap_en
}
// Check and apply sovereign tax for this key
uint256_t l_value_tax = {};
dap_chain_net_srv_stake_item_t *l_key_item = dap_chain_net_srv_stake_check_pkey_hash(&l_sign_pkey_hash);
dap_chain_net_srv_stake_item_t *l_key_item = dap_chain_net_srv_stake_check_pkey_hash(l_chain->net_id, &l_sign_pkey_hash);
if (l_key_item && !IS_ZERO_256(l_key_item->sovereign_tax) &&
!dap_chain_addr_is_blank(&l_key_item->sovereign_addr)) {
MULT_256_COIN(l_value_out, l_key_item->sovereign_tax, &l_value_tax);
......@@ -584,7 +584,7 @@ int dap_chain_mempool_tx_create_massive( dap_chain_t * a_chain, dap_enc_key_t *a
uint256_t l_value_need = {};
MULT_256_256(dap_chain_uint256_from(a_tx_num), l_single_val, &l_value_need);
uint256_t l_value_transfer = {}; // how many coins to transfer
char *l_balance; dap_uint256_to_char(l_value_need, &l_balance);
const char *l_balance; dap_uint256_to_char(l_value_need, &l_balance);
log_it(L_DEBUG, "Create %"DAP_UINT64_FORMAT_U" transactions, summary %s", a_tx_num, l_balance);
dap_ledger_t *l_ledger = dap_chain_net_by_id(a_chain->net_id)->pub.ledger;
dap_list_t *l_list_used_out = dap_ledger_get_list_tx_outs_with_val(l_ledger, a_token_ticker,
......@@ -627,7 +627,7 @@ int dap_chain_mempool_tx_create_massive( dap_chain_t * a_chain, dap_enc_key_t *a
if (compare256(l_value_to_items, l_single_val) == -1) {
char l_log_str[256] = { '\0' };
l_balance = dap_uint256_to_char(l_value_to_items, NULL);
dap_snprintf(l_log_str, sizeof(l_log_str),
snprintf(l_log_str, sizeof(l_log_str),
"Not enough values on output to produce enough inputs: %s when need ", l_balance);
strcat(l_log_str, dap_uint256_to_char(l_single_val, NULL));
log_it(L_ERROR, "%s", l_log_str);
......
......@@ -2,7 +2,9 @@
#include "dap_json_rpc.h"
int dap_chain_mempool_rpc_init(void);
void dap_chain_mempool_rpc_handler_list(dap_json_rpc_params_t *a_params,
dap_json_rpc_response_t *a_response, const char *a_method);
void dap_chain_mempool_rpc_handler_test(dap_json_rpc_params_t *a_params,
dap_json_rpc_response_t *a_response, const char *a_method);
......@@ -29,8 +29,8 @@ endif()
add_library(${PROJECT_NAME} STATIC ${DAP_CHAIN_NET_SRCS} ${DAP_CHAIN_NET_HEADERS} ${IPUTILS_SRCS} ${IPUTILS_HEADERS})
target_link_libraries(${PROJECT_NAME} dap_core dap_crypto dap_client dap_io dap_notify_srv dap_cli_server dap_chain dap_chain_wallet
dap_chain_net_srv dap_chain_mempool dap_global_db dap_chain_net_srv_xchange dap_chain_cs_none
dap_stream_ch_chain_net dap_chain_cs_esbocs dap_json_rpc dap_json_rpc_chain_common)
dap_chain_net_srv dap_chain_net_srv_voting dap_chain_mempool dap_global_db dap_chain_net_srv_xchange dap_chain_cs_none
dap_stream_ch_chain_net dap_chain_cs_esbocs dap_json_rpc )
if(LINUX)
target_link_libraries(${PROJECT_NAME} resolv)
endif()
......
......@@ -67,8 +67,18 @@ typedef struct dap_ledger_verificator {
UT_hash_handle hh;
} dap_ledger_verificator_t;
typedef struct dap_ledger_service_info {
dap_chain_net_srv_uid_t service_uid; // hash key
char tag_str[32]; // tag string name
dap_ledger_tag_check_callback_t callback; //callback for check if a tx for particular service
UT_hash_handle hh;
} dap_ledger_service_info_t;
static dap_ledger_verificator_t *s_verificators;
static dap_ledger_service_info_t *s_services;
static pthread_rwlock_t s_verificators_rwlock;
static pthread_rwlock_t s_services_rwlock;
static dap_chain_ledger_voting_callback_t s_voting_callback;
......@@ -211,6 +221,8 @@ typedef struct dap_ledger_tx_item {
byte_t multichannel;
dap_time_t ts_spent;
byte_t pad[7];
dap_chain_net_srv_uid_t tag; //tag (or service this tx is belong to)
dap_chain_tx_tag_action_type_t action;
// TODO dynamically allocates the memory in order not to limit the number of outputs in transaction
dap_chain_hash_fast_t tx_hash_spent_fast[MAX_OUT_ITEMS]; // spent outs list
} DAP_ALIGN_PACKED cache_data;
......@@ -359,6 +371,157 @@ static size_t s_threshold_free_timer_tick = 900000; // 900000 ms = 15 minutes.
struct json_object *wallet_info_json_collect(dap_ledger_t *a_ledger, dap_ledger_wallet_balance_t* a_bal);
//add a service declaration for tx tagging and more
static bool s_tag_check_block_reward(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_datum_tx_item_groups_t *a_items_grp, dap_chain_tx_tag_action_type_t *a_action)
{
//reward tag
if (a_items_grp->items_in_reward)
{
if (a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REGULAR;
return true;
}
return false;
}
dap_chain_tx_out_cond_t* dap_chain_ledger_get_tx_out_cond_linked_to_tx_in_cond(dap_ledger_t *a_ledger, dap_chain_tx_in_cond_t *a_in_cond)
{
dap_hash_fast_t *l_tx_prev_hash = &a_in_cond->header.tx_prev_hash;
uint32_t l_tx_prev_out_idx = a_in_cond->header.tx_out_prev_idx;
dap_chain_datum_tx_t *l_tx_prev = dap_ledger_tx_find_by_hash (a_ledger,l_tx_prev_hash);
if (!l_tx_prev) return NULL;
byte_t* l_item_res = dap_chain_datum_tx_item_get_nth(l_tx_prev, TX_ITEM_TYPE_OUT_ALL, l_tx_prev_out_idx);
dap_chain_tx_item_type_t l_type = *(uint8_t *)l_item_res;
if (l_type != TX_ITEM_TYPE_OUT_COND) return NULL;
return (dap_chain_tx_out_cond_t*)l_item_res;
}
static dap_chain_addr_t s_get_out_addr(byte_t *out_item) {
dap_chain_tx_item_type_t l_type = *(uint8_t *)out_item;
switch (l_type) {
case TX_ITEM_TYPE_OUT: {
dap_chain_tx_out_t *l_tx_out = (dap_chain_tx_out_t *)out_item;
return l_tx_out->addr;
} break;
case TX_ITEM_TYPE_OUT_EXT: { // 256
dap_chain_tx_out_ext_t *l_tx_out = (dap_chain_tx_out_ext_t *)out_item;
return l_tx_out->addr;
} break;
}
dap_chain_addr_t l_tx_out_to={0};
return l_tx_out_to;
}
static bool s_tag_check_transfer(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_datum_tx_item_groups_t *a_items_grp, dap_chain_tx_tag_action_type_t *a_action)
{
//crosschain transfer
//regular transfer
//comission transfer
// fee transfer: in_cond item linked to out_cond_fee
if (a_items_grp->items_in_cond)
{
for (dap_list_t *it = a_items_grp->items_in_cond; it; it = it->next) {
dap_chain_tx_in_cond_t *l_tx_in = it->data;
dap_chain_tx_out_cond_t *l_tx_out_cond = dap_chain_ledger_get_tx_out_cond_linked_to_tx_in_cond(a_ledger, l_tx_in);
if (l_tx_out_cond && l_tx_out_cond->header.subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE) {
if (a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_TRANSFER_COMISSION;
return true;
}
}
}
//crosschain transfer: outs destination net-id differs from current net-id
// to differ with wrong stakes -> no ems in required
if (!a_items_grp->items_in_ems)
{
dap_chain_addr_t addr_to = {0};
for (dap_list_t *it = a_items_grp->items_out_all; it; it = it->next) {
dap_chain_addr_t l_tx_out_to = s_get_out_addr(it->data);
//tag cross-chain _outputs_ transactions (recepient-tx is emission-based)
if (l_tx_out_to.net_id.uint64 != a_ledger->net->pub.id.uint64 && !dap_chain_addr_is_blank(&l_tx_out_to)) {
if (a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_TRANSFER_CROSSCHAIN;
return true;
}
}
}
//regular transfers
//have no other ins except regular in
//have no OUT_COND except fee
//have no vote
//no TSD!
//have any of those -> not regular transfer
if (a_items_grp->items_in_cond ||
a_items_grp->items_in_ems ||
a_items_grp->items_in_reward ) {
return false;
}
//have any of those -> not regular transfer
if (
a_items_grp->items_out_cond_srv_pay ||
a_items_grp->items_out_cond_srv_stake_lock ||
a_items_grp->items_out_cond_srv_stake_pos_delegate ||
a_items_grp->items_out_cond_srv_xchange)
{
return false;
}
//not voting or vote...
if (a_items_grp->items_vote || a_items_grp->items_voting || a_items_grp->items_tsd)
return false;
//not tsd sects (staking!)
if(a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REGULAR;
return true;
}
int dap_ledger_service_add(dap_chain_net_srv_uid_t a_uid, char *tag_str, dap_ledger_tag_check_callback_t a_callback)
{
dap_ledger_service_info_t *l_new_sinfo;
int l_tmp = a_uid.raw_ui64;
pthread_rwlock_rdlock(&s_services_rwlock);
HASH_FIND_INT(s_services, &l_tmp, l_new_sinfo);
pthread_rwlock_unlock(&s_services_rwlock);
if (l_new_sinfo) {
l_new_sinfo->callback = a_callback;
return 1;
}
l_new_sinfo = DAP_NEW(dap_ledger_service_info_t);
if (!l_new_sinfo) {
log_it(L_CRITICAL, "Memory allocation error");
return -1;
}
l_new_sinfo->service_uid = a_uid;
l_new_sinfo->callback = a_callback;
strcpy(l_new_sinfo->tag_str, tag_str);
pthread_rwlock_wrlock(&s_services_rwlock);
HASH_ADD_INT(s_services, service_uid.raw_ui64, l_new_sinfo);
pthread_rwlock_unlock(&s_services_rwlock);
log_it(L_NOTICE, "Successfully registered service tag %s with uid %02" DAP_UINT64_FORMAT_X, tag_str, a_uid.raw_ui64);
return 0;
}
/**
* @brief dap_ledger_init
* current function version set s_debug_more parameter, if it define in config, and returns 0
......@@ -367,7 +530,16 @@ struct json_object *wallet_info_json_collect(dap_ledger_t *a_ledger, dap_ledger_
int dap_ledger_init()
{
s_debug_more = dap_config_get_item_bool_default(g_config,"ledger","debug_more",false);
pthread_rwlock_init(&s_verificators_rwlock, NULL);
pthread_rwlock_init(&s_services_rwlock, NULL);
//register native ledger services
dap_chain_net_srv_uid_t l_uid_transfer = { .uint64 = DAP_CHAIN_NET_SRV_TRANSFER_ID };
dap_ledger_service_add(l_uid_transfer, "transfer", s_tag_check_transfer);
dap_chain_net_srv_uid_t l_uid_breward = { .uint64 = DAP_CHAIN_NET_SRV_BLOCK_REWARD_ID };
dap_ledger_service_add(l_uid_breward, "block_reward", s_tag_check_block_reward);
return 0;
}
......@@ -378,6 +550,7 @@ int dap_ledger_init()
void dap_ledger_deinit()
{
pthread_rwlock_destroy(&s_verificators_rwlock);
pthread_rwlock_destroy(&s_services_rwlock);
}
/**
......@@ -456,7 +629,7 @@ struct json_object *wallet_info_json_collect(dap_ledger_t *a_ledger, dap_ledger_
}
struct json_object *l_token = json_object_new_object();
json_object_object_add(l_token, "name", json_object_new_string(a_bal->token_ticker));
char *l_balance_coins, *l_balance_datoshi = dap_uint256_to_char(a_bal->balance, &l_balance_coins);
const char *l_balance_coins, *l_balance_datoshi = dap_uint256_to_char(a_bal->balance, &l_balance_coins);
json_object_object_add(l_token, "full_balance", json_object_new_string(l_balance_coins));
json_object_object_add(l_token, "datoshi", json_object_new_string(l_balance_datoshi));
json_object_object_add(l_network, "tokens", l_token);
......@@ -1041,7 +1214,7 @@ static bool s_ledger_token_supply_check_update(dap_ledger_t *a_ledger, dap_ledge
return false;
int l_overflow = SUBTRACT_256_256(a_token_item->current_supply, a_value, &a_token_item->current_supply);
assert(!l_overflow);
char *l_balance; dap_uint256_to_char(a_token_item->current_supply, &l_balance);
const char *l_balance; dap_uint256_to_char(a_token_item->current_supply, &l_balance);
log_it(L_NOTICE, "New current supply %s for token %s", l_balance, a_token_item->ticker);
s_ledger_token_cache_update(a_ledger, a_token_item);
return true;
......@@ -1218,7 +1391,7 @@ int dap_ledger_token_add(dap_ledger_t *a_ledger, dap_chain_datum_token_t *a_toke
}
int l_res_token_tsd_parse = 0;
char *l_balance_dbg = NULL;
const char *l_balance_dbg = NULL;
if (s_debug_more)
dap_uint256_to_char(l_token->total_supply, &l_balance_dbg);
......@@ -1775,6 +1948,9 @@ static int s_tsd_sign_apply(dap_ledger_t *a_ledger, dap_ledger_token_item_t *a_t
uint16_t l_tmp = 0;
a_token_item->auth_signs_valid = _dap_tsd_get_scalar(l_new_signs_valid, &l_tmp);
}
if (l_added_pkeys) dap_list_free(l_added_pkeys);
if (l_remove_pkeys) dap_list_free(l_remove_pkeys);
return 0;
}
......@@ -2902,7 +3078,7 @@ int dap_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emissi
// Add it to cache
s_ledger_emission_cache_update(a_ledger, l_token_emission_item);
if (s_debug_more) {
char *l_balance; dap_uint256_to_char(l_token_emission_item->datum_token_emission->hdr.value, &l_balance);
const char *l_balance; dap_uint256_to_char(l_token_emission_item->datum_token_emission->hdr.value, &l_balance);
log_it(L_NOTICE, "Added token emission datum to emissions cache: type=%s value=%s token=%s to_addr=%s ",
c_dap_chain_datum_token_emission_type_str[l_token_emission_item->datum_token_emission->hdr.type],
l_balance, c_token_ticker,
......@@ -2922,7 +3098,7 @@ int dap_ledger_token_emission_add(dap_ledger_t *a_ledger, byte_t *a_token_emissi
pthread_rwlock_unlock(&l_ledger_pvt->threshold_emissions_rwlock);
l_ret = -5;
if (s_debug_more) {
char *l_balance; dap_uint256_to_char(l_token_emission_item->datum_token_emission->hdr.value, &l_balance);
const char *l_balance; dap_uint256_to_char(l_token_emission_item->datum_token_emission->hdr.value, &l_balance);
log_it(L_NOTICE, "Added token emission datum to emissions threshold: type=%s value=%s token=%s to_addr=%s ",
c_dap_chain_datum_token_emission_type_str[l_token_emission_item->datum_token_emission->hdr.type],
l_balance, c_token_ticker,
......@@ -3211,7 +3387,7 @@ void dap_ledger_addr_get_token_ticker_all(dap_ledger_t *a_ledger, dap_chain_addr
return;
}
l_count = 0;
char *l_addr = dap_chain_addr_to_str(a_addr);
const char *l_addr = dap_chain_addr_to_str(a_addr);
pthread_rwlock_rdlock(&PVT(a_ledger)->balance_accounts_rwlock);
HASH_ITER(hh, PVT(a_ledger)->balance_accounts, wallet_balance, tmp) {
char **l_keys = dap_strsplit(wallet_balance->key, " ", -1);
......@@ -3229,7 +3405,11 @@ void dap_ledger_addr_get_token_ticker_all(dap_ledger_t *a_ledger, dap_chain_addr
}
}
const char *dap_ledger_get_description_by_ticker(dap_ledger_t *a_ledger, const char *a_token_ticker){
if (!a_ledger || !a_token_ticker)
return NULL;
return s_ledger_find_token(a_ledger, a_token_ticker)->description_token;
}
/**
* Get transaction in the cache by hash
......@@ -3506,14 +3686,148 @@ inline static bool s_ledger_check_token_ticker(const char *a_ticker)
return false;
}
/*
services we know now
0x01 - VPN
0x02 - xchange
0x03, 0x13 - pos_delegate
0x04 bridge
0x.05 - custom datum
0x06 voting
0x12 - stake_lock
*/
const char *dap_ledger_tx_action_str(dap_chain_tx_tag_action_type_t a_tag)
{
if (a_tag == DAP_CHAIN_TX_TAG_ACTION_UNKNOWN) return "unknown";
if (a_tag == DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REGULAR) return "regular";
if (a_tag == DAP_CHAIN_TX_TAG_ACTION_TRANSFER_COMISSION) return "comission";
if (a_tag == DAP_CHAIN_TX_TAG_ACTION_TRANSFER_CROSSCHAIN) return "crosschain";
if (a_tag == DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REWARD) return "reward";
if (a_tag == DAP_CHAIN_TX_TAG_ACTION_OPEN) return "open";
if (a_tag == DAP_CHAIN_TX_TAG_ACTION_USE) return "use";
if (a_tag == DAP_CHAIN_TX_TAG_ACTION_EXTEND) return "extend";
if (a_tag == DAP_CHAIN_TX_TAG_ACTION_CLOSE) return "close";
if (a_tag == DAP_CHAIN_TX_TAG_ACTION_CHANGE) return "change";
return "WTFSUBTAG";
}
dap_chain_tx_tag_action_type_t dap_ledger_tx_action_str_to_action_t(const char *a_str)
{
if (!a_str)
return DAP_CHAIN_TX_TAG_ACTION_UNKNOWN;
if (strcmp("unknown", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_UNKNOWN;
if (strcmp("regular", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REGULAR;
if (strcmp("comission", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_TRANSFER_COMISSION;
if (strcmp("crosschain", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_TRANSFER_CROSSCHAIN;
if (strcmp("reward", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REWARD;
if (strcmp("open", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_OPEN;
if (strcmp("use", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_USE;
if (strcmp("extend", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_EXTEND;
if (strcmp("close", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_CLOSE;
if (strcmp("change", a_str) == 0) return DAP_CHAIN_TX_TAG_ACTION_CHANGE;
return DAP_CHAIN_TX_TAG_ACTION_UNKNOWN;
}
bool dap_ledger_tx_service_info(dap_ledger_t *a_ledger, dap_hash_fast_t *a_tx_hash,
dap_chain_net_srv_uid_t *a_uid, char **a_service_name, dap_chain_tx_tag_action_type_t *a_action)
{
//find tx
dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
dap_chain_datum_tx_t *l_tx_ret = NULL;
dap_ledger_tx_item_t *l_tx_item;
pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock);
HASH_FIND(hh, l_ledger_pvt->ledger_items, a_tx_hash, sizeof(dap_chain_hash_fast_t), l_tx_item);
pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock);
if(l_tx_item) {
dap_ledger_service_info_t *l_sinfo;
pthread_rwlock_rdlock(&s_services_rwlock);
HASH_FIND_INT(s_services, &l_tx_item->cache_data.tag, l_sinfo);
pthread_rwlock_unlock(&s_services_rwlock);
if (l_sinfo)
{
if(a_uid) *a_uid = l_sinfo->service_uid;
if (a_service_name) *a_service_name = l_sinfo->tag_str;
if (a_action) *a_action = l_tx_item->cache_data.action;
return true;
}
}
if (a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_UNKNOWN;
return false;
}
bool dap_ledger_deduct_tx_tag(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_net_srv_uid_t *a_tag, dap_chain_tx_tag_action_type_t *a_action)
{
dap_ledger_service_info_t *l_sinfo_current, *l_sinfo_tmp;
dap_chain_datum_tx_item_groups_t l_items_groups = {0};
dap_chain_datum_tx_group_items(a_tx, &l_items_groups);
bool l_res = false;
int l_deductions_ok = 0;
pthread_rwlock_rdlock(&s_services_rwlock);
HASH_ITER(hh, s_services , l_sinfo_current, l_sinfo_tmp) {
dap_chain_tx_tag_action_type_t action = DAP_CHAIN_TX_TAG_ACTION_UNKNOWN;
if (l_sinfo_current->callback && l_sinfo_current->callback(a_ledger, a_tx, &l_items_groups, &action)){
if (a_tag) *a_tag = l_sinfo_current->service_uid;
if (a_action) *a_action = action;
l_res = true;
l_deductions_ok ++;
}
}
pthread_rwlock_unlock(&s_services_rwlock);
if (l_deductions_ok > 1)
{
char l_tx_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
dap_chain_hash_fast_t * l_tx_hash = dap_chain_node_datum_tx_calc_hash(a_tx);
dap_chain_hash_fast_to_str(l_tx_hash, l_tx_hash_str, sizeof(l_tx_hash_str));
log_it(L_WARNING, "Transaction %s identyfied by multiple services (%d):", l_tx_hash_str, l_deductions_ok);
pthread_rwlock_rdlock(&s_services_rwlock);
HASH_ITER(hh, s_services , l_sinfo_current, l_sinfo_tmp) {
dap_chain_tx_tag_action_type_t action = DAP_CHAIN_TX_TAG_ACTION_UNKNOWN;
if (l_sinfo_current->callback && l_sinfo_current->callback(a_ledger, a_tx, &l_items_groups,&action)) {
log_it(L_WARNING, "%s %s", l_sinfo_current->tag_str, dap_ledger_tx_action_str(action));
}
}
pthread_rwlock_unlock(&s_services_rwlock);
}
dap_chain_datum_tx_group_items_free(&l_items_groups);
return l_res;
}
/**
* Checking a new transaction before adding to the cache
*
* return 0 OK, otherwise error
*/
// Checking a new transaction before adding to the cache
int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash,
bool a_from_threshold, dap_list_t **a_list_bound_items, dap_list_t **a_list_tx_out, char **a_main_ticker)
int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger,
dap_chain_datum_tx_t *a_tx,
dap_hash_fast_t *a_tx_hash,
bool a_from_threshold,
dap_list_t **a_list_bound_items,
dap_list_t **a_list_tx_out,
char **a_main_ticker,
dap_chain_net_srv_uid_t *a_tag,
dap_chain_tx_tag_action_type_t *a_action)
{
if (!a_tx) {
log_it(L_DEBUG, "NULL transaction, check broken");
......@@ -3529,6 +3843,8 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx
char l_tx_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
dap_chain_hash_fast_to_str(a_tx_hash, l_tx_hash_str, sizeof(l_tx_hash_str));
log_it(L_WARNING, "Transaction %s already present in the cache", l_tx_hash_str);
if (a_tag) *a_tag = l_ledger_item->cache_data.tag;
if (a_action) *a_action = l_ledger_item->cache_data.action;
}
return DAP_LEDGER_TX_ALREADY_CACHED;
}
......@@ -3576,6 +3892,8 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx
dap_pkey_t *l_tx_first_sign_pkey = NULL;
bool l_girdled_ems_used = false;
uint256_t l_taxed_value = {};
if(a_tag) dap_ledger_deduct_tx_tag(a_ledger, a_tx, a_tag, a_action);
// find all previous transactions
for (dap_list_t *it = l_list_in; it; it = it->next) {
......@@ -3993,7 +4311,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx
if (!dap_chain_addr_is_blank(l_addr_from) && s_ledger_permissions_check(l_token_item,
DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_ALLOWED_ADD, l_addr_from,
sizeof(*l_addr_from)) != 0 ){
char *l_tmp_tx_in_from = dap_chain_addr_to_str(l_addr_from);
const char *l_tmp_tx_in_from = dap_chain_addr_to_str(l_addr_from);
debug_if(s_debug_more, L_WARNING, "No permission for addr %s", l_tmp_tx_in_from ? l_tmp_tx_in_from : "(null)");
l_err_num = DAP_LEDGER_PERMISSION_CHECK_FAILED;
break;
......@@ -4003,7 +4321,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx
(l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_SENDER_UNFROZEN ) ){ // in black list
if (s_ledger_permissions_check(l_token_item, DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_SENDER_BLOCKED_ADD, l_addr_from,
sizeof(*l_addr_from)) == 0 ){
char *l_tmp_tx_in_from = dap_chain_addr_to_str(l_addr_from);
const char *l_tmp_tx_in_from = dap_chain_addr_to_str(l_addr_from);
debug_if(s_debug_more, L_WARNING, "No permission for addr %s", l_tmp_tx_in_from ? l_tmp_tx_in_from : "(null)");
l_err_num = DAP_LEDGER_PERMISSION_CHECK_FAILED;
break;
......@@ -4145,7 +4463,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx
HASH_ADD_STR(l_values_from_cur_tx, token_ticker, l_value_cur);
}
dap_chain_net_srv_stake_item_t *l_key_item = dap_chain_net_srv_stake_check_pkey_hash(&l_tx_first_sign_pkey_hash);
dap_chain_net_srv_stake_item_t *l_key_item = dap_chain_net_srv_stake_check_pkey_hash(a_ledger->net->pub.id, &l_tx_first_sign_pkey_hash);
bool l_tax_check = l_key_item && !dap_chain_addr_is_blank(&l_key_item->sovereign_addr) && !IS_ZERO_256(l_key_item->sovereign_tax);
// find 'out' items
......@@ -4251,7 +4569,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx
(l_token_item->flags & DAP_CHAIN_DATUM_TOKEN_FLAG_ALL_RECEIVER_FROZEN) ){ // check if we're in white list
if(!dap_chain_addr_is_blank(&l_tx_out_to) && s_ledger_permissions_check(l_token_item, DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_ALLOWED_ADD,&l_tx_out_to ,
sizeof (l_tx_out_to)) != 0 ){
char * l_tmp_tx_out_to = dap_chain_addr_to_str(&l_tx_out_to);
const char *l_tmp_tx_out_to = dap_chain_addr_to_str(&l_tx_out_to);
debug_if(s_debug_more, L_WARNING, "No permission for addr %s", l_tmp_tx_out_to?l_tmp_tx_out_to:"(null)");
l_err_num = -20;
break;
......@@ -4262,7 +4580,7 @@ int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx
){ // If all is allowed - check if we're in black list
if(s_ledger_permissions_check(l_token_item, DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TX_RECEIVER_BLOCKED_ADD ,&l_tx_out_to,
sizeof (l_tx_out_to)) == 0 ){
char * l_tmp_tx_out_to = dap_chain_addr_to_str(&l_tx_out_to);
const char *l_tmp_tx_out_to = dap_chain_addr_to_str(&l_tx_out_to);
debug_if(s_debug_more, L_WARNING, "No permission for addr %s", l_tmp_tx_out_to?l_tmp_tx_out_to:"(null)");
l_err_num = -22;
break;
......@@ -4401,7 +4719,7 @@ int dap_ledger_tx_add_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx,
}
int l_ret_check = dap_ledger_tx_cache_check(a_ledger, a_tx, a_datum_hash,
false, NULL, NULL, NULL);
false, NULL, NULL, NULL, NULL, NULL);
if(s_debug_more) {
char l_tx_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE];
dap_chain_hash_fast_to_str(a_datum_hash, l_tx_hash_str, sizeof(l_tx_hash_str));
......@@ -4488,9 +4806,12 @@ int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ha
int l_ret_check;
l_item_tmp = NULL;
dap_chain_net_srv_uid_t l_tag = { .uint64 = 0 };
dap_chain_tx_tag_action_type_t l_action = DAP_CHAIN_TX_TAG_ACTION_UNKNOWN;
if( (l_ret_check = dap_ledger_tx_cache_check(a_ledger, a_tx, a_tx_hash, a_from_threshold,
&l_list_bound_items, &l_list_tx_out,
&l_main_token_ticker))) {
&l_main_token_ticker, &l_tag, &l_action))) {
if (l_ret_check == DAP_CHAIN_CS_VERIFY_CODE_TX_NO_PREVIOUS ||
l_ret_check == DAP_CHAIN_CS_VERIFY_CODE_TX_NO_EMISSION) {
if (!l_from_threshold) {
......@@ -4529,6 +4850,10 @@ int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ha
debug_if(s_debug_more, L_WARNING, "dap_ledger_tx_add() tx %s not passed the check: %s ", l_tx_hash_str,
dap_ledger_tx_check_err_str(l_ret_check));
}
if ( l_list_bound_items )
dap_list_free_full(l_list_bound_items, NULL);
return l_ret_check;
}
debug_if(s_debug_more, L_DEBUG, "dap_ledger_tx_add() check passed for tx %s", l_tx_hash_str);
......@@ -4605,7 +4930,7 @@ int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ha
case TX_ITEM_TYPE_IN: {
dap_ledger_wallet_balance_t *wallet_balance = NULL;
l_cur_token_ticker = l_bound_item->in.token_ticker;
char *l_addr_str = dap_chain_addr_to_str(&l_bound_item->in.addr_from);
const char *l_addr_str = dap_chain_addr_to_str(&l_bound_item->in.addr_from);
char *l_wallet_balance_key = dap_strjoin(" ", l_addr_str, l_cur_token_ticker, (char*)NULL);
pthread_rwlock_rdlock(&PVT(a_ledger)->balance_accounts_rwlock);
HASH_FIND_STR(PVT(a_ledger)->balance_accounts, l_wallet_balance_key, wallet_balance);
......@@ -4620,6 +4945,7 @@ int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ha
if(s_debug_more)
log_it(L_ERROR,"!!! Attempt to SPEND from some non-existent balance !!!: %s %s", l_addr_str, l_cur_token_ticker);
}
DAP_DELETE(l_wallet_balance_key);
} break;
......@@ -4718,7 +5044,7 @@ int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ha
else if (l_addr->net_id.uint64 != a_ledger->net->pub.id.uint64 &&
!dap_chain_addr_is_blank(l_addr))
l_cross_network = true;
char *l_addr_str = dap_chain_addr_to_str(l_addr);
const char *l_addr_str = dap_chain_addr_to_str(l_addr);
dap_ledger_wallet_balance_t *wallet_balance = NULL;
char *l_wallet_balance_key = dap_strjoin(" ", l_addr_str, l_cur_token_ticker, (char*)NULL);
debug_if(s_debug_more, L_DEBUG, "GOT %s to addr: %s",
......@@ -4779,6 +5105,8 @@ int dap_ledger_tx_add(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ha
int l_outs_count = 0;
dap_list_t *l_list_tmp = dap_chain_datum_tx_items_get(a_tx, TX_ITEM_TYPE_OUT_ALL, &l_outs_count);
l_tx_item->cache_data.n_outs = l_outs_count;
l_tx_item->cache_data.tag = l_tag;
l_tx_item->cache_data.action = l_action;
// TODO: dump the UTXO in debug mode if need
if(l_list_tmp)
......@@ -4860,7 +5188,7 @@ int dap_ledger_tx_load(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_c
{
if (dap_chain_net_get_load_mode(a_ledger->net)) {
if (PVT(a_ledger)->cache_tx_check_callback)
PVT(a_ledger)->cache_tx_check_callback(a_tx_hash);
PVT(a_ledger)->cache_tx_check_callback(a_ledger, a_tx_hash);
dap_ledger_tx_item_t *l_tx_item;
unsigned l_hash_value;
HASH_VALUE(a_tx_hash, sizeof(dap_chain_hash_fast_t), l_hash_value);
......@@ -5084,7 +5412,7 @@ uint256_t dap_ledger_calc_balance(dap_ledger_t *a_ledger, const dap_chain_addr_t
uint256_t l_ret = uint256_0;
dap_ledger_wallet_balance_t *l_balance_item = NULL;// ,* l_balance_item_tmp = NULL;
char *l_addr = dap_chain_addr_to_str(a_addr);
const char *l_addr = dap_chain_addr_to_str(a_addr);
char *l_wallet_balance_key = dap_strjoin(" ", l_addr, a_token_ticker, (char*)NULL);
pthread_rwlock_rdlock(&PVT(a_ledger)->balance_accounts_rwlock);
HASH_FIND_STR(PVT(a_ledger)->balance_accounts, l_wallet_balance_key, l_balance_item);
......@@ -5955,14 +6283,14 @@ void dap_ledger_set_cache_tx_check_callback(dap_ledger_t *a_ledger, dap_ledger_c
PVT(a_ledger)->cache_tx_check_callback = a_callback;
}
const char *dap_ledger_tx_get_main_ticker(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, int *a_ledger_rc)
const char *dap_ledger_tx_calculate_main_ticker(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, int *a_ledger_rc)
{
const char *l_main_ticker = NULL;
dap_chain_hash_fast_t * l_tx_hash = dap_chain_node_datum_tx_calc_hash(a_tx);
int l_rc = dap_ledger_tx_cache_check(a_ledger, a_tx, l_tx_hash, false, NULL, NULL, (char **)&l_main_ticker);
char *l_main_ticker = NULL;
dap_chain_hash_fast_t *l_tx_hash = dap_chain_node_datum_tx_calc_hash(a_tx);
int l_rc = dap_ledger_tx_cache_check(a_ledger, a_tx, l_tx_hash, false, NULL, NULL, &l_main_ticker, NULL, NULL);
if (l_rc == DAP_LEDGER_TX_ALREADY_CACHED)
l_main_ticker = dap_ledger_tx_get_token_ticker_by_hash(a_ledger, l_tx_hash);
l_main_ticker = (char *)dap_ledger_tx_get_token_ticker_by_hash(a_ledger, l_tx_hash);
DAP_DEL_Z(l_tx_hash);
if (a_ledger_rc)
*a_ledger_rc = l_rc;
......
......@@ -71,14 +71,7 @@
#include "dap_config.h"
#include "dap_hash.h"
#include "dap_cert.h"
#include "dap_cert_file.h"
#include "dap_chain_datum_tx.h"
#include "dap_chain_datum_tx_in_cond.h"
#include "dap_chain_datum_tx_items.h"
#include "dap_chain_datum_tx_out.h"
#include "dap_chain_datum_tx_out_cond.h"
#include "dap_timerfd.h"
#include "dap_stream_worker.h"
#include "dap_worker.h"
#include "dap_proc_thread.h"
#include "dap_enc_http.h"
......@@ -86,21 +79,16 @@
#include "dap_chain_cell.h"
#include "dap_chain_datum_decree.h"
#include "dap_chain_datum_anchor.h"
#include "dap_chain_tx.h"
#include "dap_chain_net.h"
#include "dap_chain_net_node_list.h"
#include "dap_chain_net_tx.h"
#include "dap_chain_net_anchor.h"
#include "dap_chain_net_decree.h"
#include "dap_chain_net_srv.h"
#include "dap_chain_net_balancer.h"
#include "dap_chain_node_client.h"
#include "dap_chain_node_cli.h"
#include "dap_chain_node_cli_cmd.h"
#include "dap_notify_srv.h"
#include "dap_chain_ledger.h"
#include "dap_chain_cs_none.h"
#include "dap_client_http.h"
#include "dap_global_db.h"
#include "dap_stream_ch_chain_net_pkt.h"
#include "dap_stream_ch_chain_net.h"
......@@ -108,19 +96,17 @@
#include "dap_stream_ch.h"
#include "dap_stream.h"
#include "dap_stream_ch_pkt.h"
#include "dap_chain_node_dns_client.h"
#include "dap_module.h"
#include "rand/dap_rand.h"
#include "json.h"
#include "json_object.h"
#include "dap_chain_net_srv_stake_pos_delegate.h"
#include "dap_chain_net_srv_xchange.h"
#include "dap_chain_cs_esbocs.h"
#include "dap_chain_net_voting.h"
#include "dap_chain_net_srv_voting.h"
#include "dap_global_db_cluster.h"
#include "dap_link_manager.h"
#include "dap_stream_cluster.h"
#include "dap_http_ban_list_client.h"
#include "dap_net.h"
#include <stdio.h>
#include <sys/types.h>
......@@ -268,7 +254,7 @@ int dap_chain_net_init()
dap_chain_ch_init();
dap_stream_ch_chain_net_init();
dap_chain_node_client_init();
dap_chain_net_voting_init();
dap_chain_net_srv_voting_init();
dap_http_ban_list_client_init();
dap_link_manager_init(&s_link_manager_callbacks);
dap_chain_node_init();
......@@ -310,7 +296,7 @@ int dap_chain_net_init()
continue;
// don't search in directories
char l_full_path[MAX_PATH + 1] = {0};
dap_snprintf(l_full_path, sizeof(l_full_path), "%s/%s", l_net_dir_str, l_dir_entry->d_name);
snprintf(l_full_path, sizeof(l_full_path), "%s/%s", l_net_dir_str, l_dir_entry->d_name);
if(dap_dir_test(l_full_path)) {
continue;
}
......@@ -856,22 +842,6 @@ void s_set_reply_text_node_status(void **a_str_reply, dap_chain_net_t * a_net){
DAP_DELETE(l_sync_current_link_text_block);
DAP_DELETE(l_node_address_text_block);
}
/**
* @brief get type of chain
*
* @param l_chain
* @return char*
*/
const char* dap_chain_net_get_type(dap_chain_t *l_chain)
{
if (!l_chain){
log_it(L_DEBUG, "dap_get_chain_type. Chain object is 0");
return NULL;
}
return (const char*)DAP_CHAIN_PVT(l_chain)->cs_name;
}
/**
* @brief reload ledger
* command cellframe-node-cli net -net <network_name> ledger reload
......@@ -879,7 +849,7 @@ const char* dap_chain_net_get_type(dap_chain_t *l_chain)
* @return true
* @return false
*/
static void s_chain_net_ledger_cache_reload(dap_chain_net_t *l_net)
void dap_chain_net_purge(dap_chain_net_t *l_net)
{
dap_ledger_purge(l_net->pub.ledger, false);
dap_chain_net_srv_stake_purge(l_net);
......@@ -888,8 +858,8 @@ static void s_chain_net_ledger_cache_reload(dap_chain_net_t *l_net)
DL_FOREACH(l_net->pub.chains, l_chain) {
if (l_chain->callback_purge)
l_chain->callback_purge(l_chain);
if (l_chain->callback_set_min_validators_count)
l_chain->callback_set_min_validators_count(l_chain, 0);
if (!dap_strcmp(dap_chain_get_cs_type(l_chain), "esbocs"))
dap_chain_esbocs_set_min_validators_count(l_chain, 0);
l_net->pub.fee_value = uint256_0;
l_net->pub.fee_addr = c_dap_chain_addr_blank;
dap_chain_load_all(l_chain);
......@@ -1381,7 +1351,7 @@ static int s_cli_net(int argc, char **argv, void **reply)
uint256_t l_network_fee = {};
dap_chain_addr_t l_network_fee_addr = {};
dap_chain_net_tx_get_fee(l_net->pub.id, &l_network_fee, &l_network_fee_addr);
char *l_network_fee_coins_str, *l_network_fee_balance_str =
const char *l_network_fee_coins_str, *l_network_fee_balance_str =
dap_uint256_to_char(l_network_fee, &l_network_fee_coins_str);
json_object *l_jobj_network = json_object_new_object();
json_object *l_jobj_fee_coins = json_object_new_string(l_network_fee_coins_str);
......@@ -1679,7 +1649,7 @@ static int s_cli_net(int argc, char **argv, void **reply)
} else if (l_ledger_str && !strcmp(l_ledger_str, "reload")) {
int l_return_state = dap_chain_net_stop(l_net);
sleep(1); // wait to net going offline
s_chain_net_ledger_cache_reload(l_net);
dap_chain_net_purge(l_net);
if (l_return_state)
dap_chain_net_start(l_net);
} else if (l_list_str && !strcmp(l_list_str, "list")) {
......@@ -2995,7 +2965,7 @@ static bool s_net_check_acl(dap_chain_net_t *a_net, dap_chain_hash_fast_t *a_pke
{
const char l_path[] = "network/";
char l_cfg_path[strlen(a_net->pub.name) + strlen(l_path) + 1];
dap_snprintf(l_cfg_path, sizeof(l_cfg_path), "%s%s", l_path, a_net->pub.name);
snprintf(l_cfg_path, sizeof(l_cfg_path), "%s%s", l_path, a_net->pub.name);
dap_config_t *l_cfg = dap_config_open(l_cfg_path);
const char *l_auth_type = dap_config_get_item_str(l_cfg, "auth", "type");
bool l_authorized = true;
......
......@@ -25,12 +25,13 @@
#include <assert.h>
#include "dap_common.h"
#include "dap_sign.h"
#include "dap_cert.h"
#include "dap_pkey.h"
#include "dap_chain_common.h"
#include "dap_chain_ledger.h"
#include "dap_chain_net.h"
#include "dap_chain_net_decree.h"
#include "dap_chain_datum_decree.h"
#include "dap_chain_datum_anchor.h"
#define LOG_TAG "chain_net_anchor"
......
......@@ -29,7 +29,9 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic
#include "http_status_code.h"
#include "dap_chain_node_client.h"
#include "dap_chain_node_dns_client.h"
#include "rand/dap_rand.h"
#include "dap_net.h"
#include "dap_client_http.h"
#include "dap_enc_base64.h"
#include "dap_notify_srv.h"
#define LOG_TAG "dap_chain_net_balancer"
......@@ -153,7 +155,7 @@ static void s_balancer_link_prepare_error(dap_balancer_link_request_t *a_request
{
struct json_object *l_json = s_balancer_states_json_collect(a_request->net, a_host_addr, a_host_port);
char l_err_str[512] = { '\0' };
dap_snprintf(l_err_str, sizeof(l_err_str)
snprintf(l_err_str, sizeof(l_err_str)
, "Link from balancer %s can't be prepared, errno %d"
, a_host_addr, a_errno);
log_it(L_WARNING, "%s", l_err_str);
......@@ -511,4 +513,4 @@ dap_string_t *dap_chain_net_balancer_get_node_str(dap_chain_net_t *a_net)
dap_string_append(l_ret, "-----------------------------------------------------------------\n");
DAP_DEL_Z(l_links_info_list);
return l_ret;
}
\ No newline at end of file
}
......@@ -25,12 +25,11 @@
#include <assert.h>
#include "dap_common.h"
#include "dap_sign.h"
#include "dap_cert.h"
#include "dap_pkey.h"
#include "dap_chain_common.h"
#include "dap_chain_net.h"
#include "dap_chain_net_decree.h"
#include "dap_chain_net_srv.h"
#include "dap_chain_cs_esbocs.h"
#include "dap_chain_net_tx.h"
#include "dap_chain_net_srv_stake_pos_delegate.h"
#include "dap_http_ban_list_client.h"
......@@ -198,7 +197,7 @@ static int s_decree_verify(dap_chain_net_t *a_net, dap_chain_datum_decree_t *a_d
DAP_DELETE(l_unique_signs);
if (l_signs_verify_counter < l_min_signs) {
log_it(L_WARNING,"Not enough valid signatures, get %hu from %hu", l_signs_verify_counter, l_min_signs);
log_it(L_WARNING, "Not enough valid signatures, get %hu from %hu", l_signs_verify_counter, l_min_signs);
return -107;
}
......@@ -353,12 +352,15 @@ static bool s_verify_pkey (dap_sign_t *a_sign, dap_chain_net_t *a_net)
static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain_net_t *a_net, bool a_apply, bool a_load_mode)
{
uint256_t l_uint256_buffer;
uint16_t l_uint16_buffer;
dap_chain_addr_t l_addr = {}; //????????
uint256_t l_value;
uint32_t l_sign_type;
uint16_t l_owners_num;
uint8_t l_action;
dap_chain_addr_t l_addr = {};
dap_hash_fast_t l_hash = {};
dap_chain_node_addr_t l_node_addr = {};
dap_list_t *l_owners_list = NULL;
const char *l_ban_addr;
dap_return_val_if_fail(a_decree && a_net, -112);
......@@ -372,17 +374,17 @@ static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain
} else
l_addr = a_net->pub.fee_addr;
}
if (dap_chain_datum_decree_get_fee(a_decree, &l_uint256_buffer)) {
if (dap_chain_datum_decree_get_fee(a_decree, &l_value)) {
log_it(L_WARNING,"Can't get fee value from decree.");
return -103;
}
if (!a_apply)
break;
if (!dap_chain_net_tx_set_fee(a_net->pub.id, l_uint256_buffer, l_addr))
if (!dap_chain_net_tx_set_fee(a_net->pub.id, l_value, l_addr))
log_it(L_ERROR, "Can't set fee value for network %s", a_net->pub.name);
break;
case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_OWNERS:
l_owners_list = dap_chain_datum_decree_get_owners(a_decree, &l_uint16_buffer);
l_owners_list = dap_chain_datum_decree_get_owners(a_decree, &l_owners_num);
if (!l_owners_list){
log_it(L_WARNING,"Can't get ownners from decree.");
return -104;
......@@ -391,26 +393,30 @@ static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain
if (!a_apply)
break;
a_net->pub.decree->num_of_owners = l_uint16_buffer;
a_net->pub.decree->num_of_owners = l_owners_num;
dap_list_free_full(a_net->pub.decree->pkeys, NULL);
a_net->pub.decree->pkeys = l_owners_list;
break;
case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_OWNERS_MIN:
if (dap_chain_datum_decree_get_min_owners(a_decree, &l_uint16_buffer)){
log_it(L_WARNING,"Can't get min number of ownners from decree.");
if (dap_chain_datum_decree_get_min_owners(a_decree, &l_value)) {
log_it(L_WARNING, "Can't get min number of ownners from decree.");
return -105;
}
if (IS_ZERO_256(l_value) || compare256(l_value, GET_256_FROM_64(UINT16_MAX)) == 1) {
log_it(L_WARNING, "Illegal min number of owners %s", dap_uint256_to_char(l_value, NULL));
return -116;
}
if (!a_apply)
break;
a_net->pub.decree->min_num_of_owners = l_uint16_buffer;
a_net->pub.decree->min_num_of_owners = dap_uint256_to_uint64(l_value);
break;
case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_APPROVE:
if (dap_chain_datum_decree_get_stake_tx_hash(a_decree, &l_hash)){
if (dap_chain_datum_decree_get_hash(a_decree, &l_hash)){
log_it(L_WARNING,"Can't get tx hash from decree.");
return -105;
}
if (dap_chain_datum_decree_get_stake_value(a_decree, &l_uint256_buffer)){
if (dap_chain_datum_decree_get_stake_value(a_decree, &l_value)){
log_it(L_WARNING,"Can't get stake value from decree.");
return -106;
}
......@@ -432,7 +438,7 @@ static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain
}
if (!a_apply)
break;
dap_chain_net_srv_stake_key_delegate(a_net, &l_addr, &l_hash, l_uint256_buffer, &l_node_addr);
dap_chain_net_srv_stake_key_delegate(a_net, &l_addr, &l_hash, l_value, &l_node_addr);
break;
case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_INVALIDATE:
if (dap_chain_datum_decree_get_stake_signing_addr(a_decree, &l_addr)){
......@@ -444,16 +450,16 @@ static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain
dap_chain_net_srv_stake_key_invalidate(&l_addr);
break;
case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALUE:
if (dap_chain_datum_decree_get_stake_min_value(a_decree, &l_uint256_buffer)){
if (dap_chain_datum_decree_get_stake_min_value(a_decree, &l_value)){
log_it(L_WARNING,"Can't get min stake value from decree.");
return -105;
}
if (!a_apply)
break;
dap_chain_net_srv_stake_set_allowed_min_value(l_uint256_buffer);
dap_chain_net_srv_stake_set_allowed_min_value(a_net->pub.id, l_value);
break;
case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_MIN_VALIDATORS_COUNT:
if (dap_chain_datum_decree_get_stake_min_signers_count(a_decree, &l_uint256_buffer)){
if (dap_chain_datum_decree_get_stake_min_signers_count(a_decree, &l_value)){
log_it(L_WARNING,"Can't get min stake value from decree.");
return -105;
}
......@@ -462,72 +468,44 @@ static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain
log_it(L_WARNING, "Specified chain not found");
return -106;
}
if (!l_chain->callback_set_min_validators_count) {
if (dap_strcmp(dap_chain_get_cs_type(l_chain), "esbocs")) {
log_it(L_WARNING, "Can't apply this decree to specified chain");
return -115;
}
if (!a_apply)
break;
l_chain->callback_set_min_validators_count(l_chain, (uint16_t)dap_chain_uint256_to(l_uint256_buffer));
dap_chain_esbocs_set_min_validators_count(l_chain, (uint16_t)dap_chain_uint256_to(l_value));
break;
case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_BAN: {
if (dap_chain_datum_decree_get_ban_addr(a_decree, &l_ban_addr)) {
log_it(L_WARNING, "Can't get ban address from decree.");
return -114;
}
if (dap_http_ban_list_client_check(l_ban_addr, NULL, NULL)) {
log_it(L_ERROR, "Can't ban addr %s: already banlisted", l_ban_addr);
return -112;
}
if (!a_apply)
break;
size_t l_tsd_offset = 0, tsd_data_size = a_decree->header.data_size;
while(l_tsd_offset < tsd_data_size){
dap_tsd_t *l_tsd = (dap_tsd_t *)(a_decree->data_n_signs + l_tsd_offset);
size_t l_tsd_size = dap_tsd_size(l_tsd);
if(l_tsd_size > tsd_data_size){
log_it(L_WARNING,"TSD size is greater than all data size. It's possible corrupt data.");
return -2;
}
dap_hash_fast_t l_decree_hash = {0};
dap_hash_fast(a_decree, dap_chain_datum_decree_get_size(a_decree), &l_decree_hash);
char *l_addr = dap_tsd_get_string(l_tsd);
switch (l_tsd->type) {
case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST:
case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR:
if ( dap_http_ban_list_client_add(l_addr, l_decree_hash, a_decree->header.ts_created) ) {
log_it(L_ERROR, "Can't ban addr %s: already banlisted", l_addr);
return -4;
} break;
default:
log_it(L_WARNING, "Invalid section TSD type for sub-decree datum of type "
"DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_BAN.");
return -3;
}
l_tsd_offset += l_tsd_size;
}
dap_hash_fast_t l_decree_hash = {0};
dap_hash_fast(a_decree, dap_chain_datum_decree_get_size(a_decree), &l_decree_hash);
dap_http_ban_list_client_add(l_ban_addr, l_decree_hash, a_decree->header.ts_created);
} break;
case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_UNBAN: {
if (dap_chain_datum_decree_get_ban_addr(a_decree, &l_ban_addr)) {
log_it(L_WARNING, "Can't get ban address from decree.");
return -114;
}
if (!dap_http_ban_list_client_check(l_ban_addr, NULL, NULL)) {
log_it(L_ERROR, "Can't ban addr %s: already banlisted", l_ban_addr);
return -112;
}
if (!a_apply)
break;
size_t l_tsd_offset = 0, tsd_data_size = a_decree->header.data_size;
while(l_tsd_offset < tsd_data_size){
dap_tsd_t *l_tsd = (dap_tsd_t *)(a_decree->data_n_signs + l_tsd_offset);
size_t l_tsd_size = dap_tsd_size(l_tsd);
if(l_tsd_size > tsd_data_size){
log_it(L_WARNING,"TSD size is greater than all data size. It's possible corrupt data.");
return -2;
}
char *l_addr = dap_tsd_get_string(l_tsd);
switch (l_tsd->type) {
case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST:
case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR:
if ( dap_http_ban_list_client_remove(l_addr) ) {
log_it(L_ERROR, "Can't unban addr %s: not banlisted", l_addr);
return -4;
} break;
default:
log_it(L_WARNING, "Invalid section TSD type for sub-decree datum of type "
"DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_BAN.");
return -3;
}
l_tsd_offset += l_tsd_size;
}
dap_http_ban_list_client_remove(l_ban_addr);
} break;
case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_REWARD: {
if (dap_chain_datum_decree_get_value(a_decree, &l_uint256_buffer)) {
if (dap_chain_datum_decree_get_value(a_decree, &l_value)) {
log_it(L_WARNING,"Can't get value from decree.");
return -103;
}
......@@ -536,10 +514,80 @@ static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain
log_it(L_WARNING, "Specified chain not found");
return -106;
}
if (dap_strcmp(dap_chain_get_cs_type(l_chain), "esbocs")) {
log_it(L_WARNING, "Can't apply this decree to specified chain");
return -115;
}
if (!a_apply)
break;
uint64_t l_cur_block_num = l_chain->callback_count_atom(l_chain);
dap_chain_net_add_reward(a_net, l_uint256_buffer, l_cur_block_num);
dap_chain_net_add_reward(a_net, l_value, l_cur_block_num);
} break;
case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_MAX_WEIGHT: {
if (dap_chain_datum_decree_get_value(a_decree, &l_value)) {
log_it(L_WARNING,"Can't get value from decree.");
return -103;
}
dap_chain_t *l_chain = dap_chain_find_by_id(a_net->pub.id, a_decree->header.common_decree_params.chain_id);
if (!l_chain) {
log_it(L_WARNING, "Specified chain not found");
return -106;
}
if (dap_strcmp(dap_chain_get_cs_type(l_chain), "esbocs")) {
log_it(L_WARNING, "Can't apply this decree to specified chain");
return -115;
}
if (compare256(l_value, dap_chain_coins_to_balance("1.0")) >= 0) {
log_it(L_WARNING, "Percent must be lower than 100%%");
return -116;
}
if (!a_apply)
break;
dap_chain_net_srv_stake_set_percent_max(a_net->pub.id, l_value);
} break;
case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_CHECK_SIGNS_STRUCTURE: {
if (dap_chain_datum_decree_get_action(a_decree, &l_action)) {
log_it(L_WARNING,"Can't get action from decree.");
return -103;
}
dap_chain_t *l_chain = dap_chain_find_by_id(a_net->pub.id, a_decree->header.common_decree_params.chain_id);
if (!l_chain) {
log_it(L_WARNING, "Specified chain not found");
return -106;
}
if (dap_strcmp(dap_chain_get_cs_type(l_chain), "esbocs")) {
log_it(L_WARNING, "Can't apply this decree to specified chain");
return -115;
}
if (!a_apply)
break;
dap_chain_esbocs_set_signs_struct_check(l_chain, l_action);
} break;
case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_EMERGENCY_VALIDATORS: {
if (dap_chain_datum_decree_get_action(a_decree, &l_action)) {
log_it(L_WARNING,"Can't get action from decree.");
return -103;
}
if (dap_chain_datum_decree_get_signature_type(a_decree, &l_sign_type)) {
log_it(L_WARNING,"Can't get signature type from decree.");
return -113;
}
if (dap_chain_datum_decree_get_hash(a_decree, &l_hash)){
log_it(L_WARNING,"Can't get validator hash from decree.");
return -105;
}
dap_chain_t *l_chain = dap_chain_find_by_id(a_net->pub.id, a_decree->header.common_decree_params.chain_id);
if (!l_chain) {
log_it(L_WARNING, "Specified chain not found");
return -106;
}
if (dap_strcmp(dap_chain_get_cs_type(l_chain), "esbocs")) {
log_it(L_WARNING, "Can't apply this decree to specified chain");
return -115;
}
if (!a_apply)
break;
dap_chain_esbocs_set_emergency_validator(l_chain, l_action, l_sign_type, &l_hash);
} break;
default:
return -1;
......
......@@ -105,7 +105,7 @@ void dap_chain_net_node_check_http_issue_link(dap_http_simple_t *a_http_simple,
*l_return_code = Http_Status_MethodNotAllowed;
return;
}
char *l_key = dap_stream_node_addr_to_str_static( (dap_chain_node_addr_t){.uint64 = addr} );
const char *l_key = dap_stream_node_addr_to_str_static( (dap_chain_node_addr_t){.uint64 = addr} );
if (!l_key) {
log_it(L_ERROR, "Bad node address %zu", addr);
*l_return_code = Http_Status_BadRequest;
......
......@@ -39,13 +39,11 @@
#include <netinet/in.h>
#endif
#include "utlist.h"
#include "dap_hash.h"
#include "rand/dap_rand.h"
#include "dap_chain_net.h"
#include "dap_global_db.h"
#include "dap_chain_node.h"
#include "dap_chain_cell.h"
#include "dap_chain_cs_esbocs.h"
#include "dap_chain_ledger.h"
#define LOG_TAG "dap_chain_node"
......@@ -89,14 +87,14 @@ static void s_update_node_states_info(UNUSED_ARG void *a_arg)
memcpy(l_info->links_addrs, l_linked_node_addrs, (l_info->uplinks_count + l_info->downlinks_count) * sizeof(dap_chain_node_addr_t));
// DB write
char *l_gdb_group = dap_strdup_printf("%s.nodes.states", l_net->pub.gdb_groups_prefix);
char *l_node_addr_str = dap_stream_node_addr_to_str_static(l_info->address);
const char *l_node_addr_str = dap_stream_node_addr_to_str_static(l_info->address);
dap_global_db_set_sync(l_gdb_group, l_node_addr_str, l_info, l_info_size, false);
DAP_DEL_MULTY(l_linked_node_addrs, l_info, l_gdb_group);
}
}
}
static void s_states_info_to_str(dap_chain_net_t *a_net, char *a_node_addr_str, dap_string_t *l_info_str)
static void s_states_info_to_str(dap_chain_net_t *a_net, const char *a_node_addr_str, dap_string_t *l_info_str)
{
// sanity check
dap_return_if_pass(!a_net || !a_node_addr_str || !l_info_str);
......@@ -137,7 +135,7 @@ static void s_states_info_to_str(dap_chain_net_t *a_net, char *a_node_addr_str,
dap_string_t *dap_chain_node_states_info_read(dap_chain_net_t *a_net, dap_stream_node_addr_t a_addr)
{
dap_string_t *l_ret = dap_string_new("");
char *l_node_addr_str = dap_stream_node_addr_to_str_static(a_addr.uint64 ? a_addr : g_node_addr);
const char *l_node_addr_str = dap_stream_node_addr_to_str_static(a_addr.uint64 ? a_addr : g_node_addr);
if(!a_net) {
for (dap_chain_net_t *l_net = dap_chain_net_iter_start(); l_net; l_net = dap_chain_net_iter_next(l_net)) {
s_states_info_to_str(l_net, l_node_addr_str, l_ret);
......@@ -227,7 +225,7 @@ int dap_chain_node_info_del(dap_chain_net_t *a_net, dap_chain_node_info_t *a_nod
*/
dap_chain_node_info_t* dap_chain_node_info_read(dap_chain_net_t *a_net, dap_chain_node_addr_t *a_address)
{
char *l_key = dap_stream_node_addr_to_str_static(*a_address);
const char *l_key = dap_stream_node_addr_to_str_static(*a_address);
size_t l_node_info_size = 0;
dap_chain_node_info_t *l_node_info
= (dap_chain_node_info_t*)dap_global_db_get_sync(a_net->pub.gdb_nodes, l_key, &l_node_info_size, NULL, NULL);
......@@ -302,7 +300,7 @@ void dap_chain_node_mempool_process_all(dap_chain_t *a_chain, bool a_force)
if (dap_chain_node_mempool_need_process(a_chain, l_datum)) {
if (l_datum->header.type_id == DAP_CHAIN_DATUM_TX &&
a_chain->callback_get_minimum_fee){
!dap_strcmp(dap_chain_get_cs_type(a_chain), "esbocs")) {
uint256_t l_tx_fee = {};
dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)l_datum->data;
if (dap_chain_datum_tx_get_fee_value (l_tx, &l_tx_fee) ||
......@@ -313,7 +311,7 @@ void dap_chain_node_mempool_process_all(dap_chain_t *a_chain, bool a_force)
} else
log_it(L_DEBUG, "Process service tx without fee");
} else {
uint256_t l_min_fee = a_chain->callback_get_minimum_fee(a_chain);
uint256_t l_min_fee = dap_chain_esbocs_get_fee(a_chain->net_id);
if (compare256(l_tx_fee, l_min_fee) < 0) {
char *l_tx_fee_str = dap_chain_balance_to_coins(l_tx_fee);
char *l_min_fee_str = dap_chain_balance_to_coins(l_min_fee);
......
......@@ -68,6 +68,7 @@
#include "dap_cert_file.h"
#include "dap_file_utils.h"
#include "dap_enc_base58.h"
#include "dap_enc_ks.h"
#include "dap_chain_wallet.h"
#include "dap_chain_wallet_internal.h"
#include "dap_chain_node.h"
......@@ -76,17 +77,13 @@
#include "dap_chain_node_client.h"
#include "dap_chain_node_cli_cmd.h"
#include "dap_chain_node_cli_cmd_tx.h"
#include "dap_chain_node_ping.h"
#include "dap_net.h"
#include "dap_chain_net_srv.h"
#include "dap_chain_net_tx.h"
#include "dap_chain_net_balancer.h"
#include "dap_chain_block.h"
#include "dap_chain_cs_blocks.h"
#include "dap_chain_cell.h"
#include "dap_enc_base64.h"
#include "json.h"
#ifdef DAP_OS_UNIX
#include <dirent.h>
#endif
......@@ -98,25 +95,19 @@
#include "dap_chain_ledger.h"
#include "dap_chain_mempool.h"
#include "dap_global_db.h"
#include "dap_global_db_cluster.h"
#include "dap_global_db_pkt.h"
#include "dap_stream_ch_chain_net.h"
#include "dap_chain_ch.h"
#include "dap_stream_ch_chain_net_pkt.h"
#include "dap_enc_base64.h"
#include "dap_chain_net_srv_stake_pos_delegate.h"
#include "dap_chain_net_node_list.h"
#include "dap_json_rpc_errors.h"
#include "dap_json_rpc_chain_datum.h"
#include "dap_http_ban_list_client.h"
#include "dap_chain_datum_tx_voting.h"
#include "dap_enc_ks.h"
#define LOG_TAG "chain_node_cli_cmd"
static void s_dap_chain_net_purge(dap_chain_net_t *a_net);
int _cmd_mempool_add_ca(dap_chain_net_t *a_net, dap_chain_t *a_chain, dap_cert_t *a_cert, void **a_str_reply);
/**
......@@ -382,31 +373,6 @@ static int s_node_info_list_with_reply(dap_chain_net_t *a_net, dap_chain_node_ad
return l_ret;
}
/**
* @brief purge ledger, stake, decree, all chains and remove chain files
* @param a_net
*/
void s_dap_chain_net_purge(dap_chain_net_t * a_net)
{
if (!a_net)
return;
dap_chain_t *l_chain = NULL;
dap_ledger_purge(a_net->pub.ledger, false);
dap_chain_net_srv_stake_purge(a_net);
dap_chain_net_decree_purge(a_net);
DL_FOREACH(a_net->pub.chains, l_chain) {
if (l_chain->callback_purge)
l_chain->callback_purge(l_chain);
if (l_chain->callback_set_min_validators_count)
l_chain->callback_set_min_validators_count(l_chain, 0);
const char *l_chains_rm_path = dap_chain_get_path(l_chain);
dap_rm_rf(l_chains_rm_path);
a_net->pub.fee_value = uint256_0;
a_net->pub.fee_addr = c_dap_chain_addr_blank;
dap_chain_load_all(l_chain);
}
}
/**
* @brief com_global_db
* global_db command
......@@ -828,9 +794,13 @@ int com_global_db(int a_argc, char ** a_argv, void **a_str_reply)
static dap_tsd_t* s_chain_node_cli_com_node_create_tsd_addr(char **a_argv, int a_arg_start, int a_arg_end, void **a_str_reply, const char *a_specified_decree) {
const char *l_ban_addr_str = NULL;
if (dap_cli_server_cmd_find_option_val(a_argv, a_arg_start, a_arg_end, "-addr", &l_ban_addr_str))
return dap_tsd_create_string(DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR, l_ban_addr_str);
else if (dap_cli_server_cmd_find_option_val(a_argv, a_arg_start, a_arg_end, "-host", &l_ban_addr_str))
if (dap_cli_server_cmd_find_option_val(a_argv, a_arg_start, a_arg_end, "-addr", &l_ban_addr_str)) {
dap_chain_addr_t *l_format = dap_chain_addr_from_str(l_ban_addr_str);
if (!l_format)
return dap_cli_server_cmd_set_reply_text(a_str_reply, "Can't convert the -addr option value to node address"), NULL;
DAP_DELETE(l_format);
return dap_tsd_create_string(DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STRING, l_ban_addr_str);
} else if (dap_cli_server_cmd_find_option_val(a_argv, a_arg_start, a_arg_end, "-host", &l_ban_addr_str))
return dap_tsd_create_string(DAP_CHAIN_DATUM_DECREE_TSD_TYPE_HOST, l_ban_addr_str);
else
return dap_cli_server_cmd_set_reply_text(a_str_reply, "The -host or -addr option was not "
......@@ -1849,10 +1819,10 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE;
if (l_wallet) {
l_addr = l_net ? dap_chain_wallet_get_addr(l_wallet, l_net->pub.id) : NULL;
char *l_addr_str = dap_chain_addr_to_str(l_addr);
const char *l_addr_str = dap_chain_addr_to_str(l_addr);
json_object_object_add(json_obj_wall, "Wallet", json_object_new_string(l_file_name));
if(l_wallet->flags & DAP_WALLET$M_FL_ACTIVE)
json_object_object_add(json_obj_wall, "status", json_object_new_string("Active"));
json_object_object_add(json_obj_wall, "status", json_object_new_string("active"));
else
json_object_object_add(json_obj_wall, "status", json_object_new_string("not active"));
json_object_object_add(json_obj_wall, "sign_status", json_object_new_string(
......@@ -1921,7 +1891,7 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE;
}
}
json_object * json_obj_wall = json_object_new_object();
char *l_l_addr_str = dap_chain_addr_to_str((dap_chain_addr_t*) l_addr);
const char *l_l_addr_str = dap_chain_addr_to_str((dap_chain_addr_t*) l_addr);
if(l_wallet)
{
json_object_object_add(json_obj_wall, "sign", json_object_new_string(
......@@ -1942,7 +1912,7 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE;
if(l_l_addr_tokens[i]) {
json_object * j_balance_data = json_object_new_object();
uint256_t l_balance = dap_ledger_calc_balance(l_ledger, l_addr, l_l_addr_tokens[i]);
char *l_balance_coins, *l_balance_datoshi = dap_uint256_to_char(l_balance, &l_balance_coins);
const char *l_balance_coins, *l_balance_datoshi = dap_uint256_to_char(l_balance, &l_balance_coins);
json_object_object_add(j_balance_data, "balance", json_object_new_string(""));
json_object_object_add(j_balance_data, "coins", json_object_new_string(l_balance_coins));
json_object_object_add(j_balance_data, "datoshi", json_object_new_string(l_balance_datoshi));
......@@ -2167,7 +2137,7 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE;
l_addr = l_net ? dap_chain_wallet_get_addr(l_wallet,l_net->pub.id ) : NULL;
char *l_addr_str = dap_chain_addr_to_str(l_addr);
const char *l_addr_str = dap_chain_addr_to_str(l_addr);
json_object * json_obj_wall = json_object_new_object();
json_object_object_add(json_obj_wall, "Wallet name", json_object_new_string(l_wallet->name));
json_object_object_add(json_obj_wall, "Sign type", json_object_new_string(l_sign_type_str));
......@@ -2351,6 +2321,88 @@ int dap_chain_node_cli_cmd_values_parse_net_chain(int *a_arg_index, int a_argc,
return 0;
}
/**
* @brief dap_chain_node_cli_cmd_values_parse_net_chain_json
* @param argc
* @param argv
* @param a_chain
* @param a_net
* @return
*/
int dap_chain_node_cli_cmd_values_parse_net_chain_json(int *a_arg_index, int a_argc, char **a_argv,
dap_chain_t **a_chain, dap_chain_net_t **a_net)
{
const char * l_chain_str = NULL;
const char * l_net_str = NULL;
// Net name
if(a_net)
dap_cli_server_cmd_find_option_val(a_argv, *a_arg_index, a_argc, "-net", &l_net_str);
else
return -DAP_CHAIN_NODE_CLI_COM_PARSE_NET_NET_STR_ERR;
// Select network
if(!l_net_str) {
dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_PARSE_NET_NET_PARAM_ERR, "%s requires parameter '-net'", a_argv[0]);
return -DAP_CHAIN_NODE_CLI_COM_PARSE_NET_NET_PARAM_ERR;
}
if((*a_net = dap_chain_net_by_name(l_net_str)) == NULL) { // Can't find such network
dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_PARSE_NET_NOT_FOUND_ERR, "%s can't find network \"%s\"", a_argv[0], l_net_str);
char l_str_to_reply_chain[500] = {0};
char *l_str_to_reply = NULL;
sprintf(l_str_to_reply_chain, "%s can't find network \"%s\"\n", a_argv[0], l_net_str);
l_str_to_reply = dap_strcat2(l_str_to_reply,l_str_to_reply_chain);
dap_string_t* l_net_str = dap_cli_list_net();
l_str_to_reply = dap_strcat2(l_str_to_reply,l_net_str->str);
dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_PARSE_NET_NOT_FOUND_ERR, l_str_to_reply);
DAP_DELETE(l_str_to_reply);
dap_string_free(l_net_str, true);
return -DAP_CHAIN_NODE_CLI_COM_PARSE_NET_NOT_FOUND_ERR;
}
// Chain name
if(a_chain) {
dap_cli_server_cmd_find_option_val(a_argv, *a_arg_index, a_argc, "-chain", &l_chain_str);
// Select chain
if(l_chain_str) {
if ((*a_chain = dap_chain_net_get_chain_by_name(*a_net, l_chain_str)) == NULL) { // Can't find such chain
char l_str_to_reply_chain[500] = {0};
char *l_str_to_reply = NULL;
sprintf(l_str_to_reply_chain, "%s requires parameter '-chain' to be valid chain name in chain net %s. Current chain %s is not valid\n",
a_argv[0], l_net_str, l_chain_str);
l_str_to_reply = dap_strcat2(l_str_to_reply,l_str_to_reply_chain);
dap_chain_t * l_chain;
dap_chain_net_t * l_chain_net = *a_net;
l_str_to_reply = dap_strcat2(l_str_to_reply,"\nAvailable chains:\n");
DL_FOREACH(l_chain_net->pub.chains, l_chain) {
l_str_to_reply = dap_strcat2(l_str_to_reply,"\t");
l_str_to_reply = dap_strcat2(l_str_to_reply,l_chain->name);
l_str_to_reply = dap_strcat2(l_str_to_reply,"\n");
}
dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_PARSE_NET_CHAIN_PARAM_ERR, l_str_to_reply);
DAP_DELETE(l_str_to_reply);
return -DAP_CHAIN_NODE_CLI_COM_PARSE_NET_CHAIN_PARAM_ERR;
}
}
else if ( !strcmp(a_argv[0], "token_decl")
|| !strcmp(a_argv[0], "token_decl_sign")) {
if ( (*a_chain = dap_chain_net_get_default_chain_by_chain_type(*a_net, CHAIN_TYPE_TOKEN)) == NULL )
{
dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_PARSE_NET_CHAIN_PARAM_ERR, "%s requires parameter '-chain' or set default datum type in chain configuration file",
a_argv[0]);
return -DAP_CHAIN_NODE_CLI_COM_PARSE_NET_CHAIN_PARAM_ERR;
}
} else {
dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_PARSE_NET_CHAIN_PARAM_ERR, "%s requires parameter '-chain'", a_argv[0]);
return -DAP_CHAIN_NODE_CLI_COM_PARSE_NET_CHAIN_PARAM_ERR;
}
}
return 0;
}
/**
* @brief
* sign data (datum_token) by certificates (1 or more)
......@@ -2495,7 +2547,7 @@ int com_token_decl_sign(int a_argc, char **a_argv, void **a_str_reply)
l_datum_token->signs_total = 0;
for (i = 1; i <= l_tmp_signs_total; i++){
dap_sign_t *l_sign = (dap_sign_t *)(l_datum_token->data_n_tsd + l_tsd_size + l_signs_size);
if( dap_sign_verify(l_sign, l_datum_token, sizeof(*l_datum_token) + l_tsd_size) != 1) {
if( dap_sign_verify(l_sign, l_datum_token, sizeof(*l_datum_token) + l_tsd_size) ) {
log_it(L_WARNING, "Wrong signature %zu for datum_token with key %s in mempool!", i, l_datum_hash_out_str);
dap_cli_server_cmd_set_reply_text(a_str_reply,
"Datum %s with datum token has wrong signature %zu, break process and exit",
......@@ -2748,7 +2800,7 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a
dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *) l_datum->data;
int l_ledger_rc = DAP_LEDGER_TX_CHECK_NULL_TX;
const char *l_main_ticker = dap_ledger_tx_get_main_ticker(a_net->pub.ledger, l_tx,
const char *l_main_ticker = dap_ledger_tx_calculate_main_ticker(a_net->pub.ledger, l_tx,
&l_ledger_rc);
char *l_ledger_rc_str = dap_ledger_tx_check_err_str(l_ledger_rc);
......@@ -2935,7 +2987,7 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a
dap_json_rpc_allocation_error;
return;
}
char *l_value_coins_str, *l_value_str = dap_uint256_to_char(l_value, &l_value_coins_str);
const char *l_value_coins_str, *l_value_str = dap_uint256_to_char(l_value, &l_value_coins_str);
json_object_object_add(l_jobj_money, "value", json_object_new_string(l_value_str));
json_object_object_add(l_jobj_money, "coins", json_object_new_string(l_value_coins_str));
if (l_dist_token) {
......@@ -3097,11 +3149,11 @@ void s_com_mempool_list_print_for_chain(dap_chain_net_t * a_net, dap_chain_t * a
if (l_wallet_addr && l_emi && dap_chain_addr_compare(l_wallet_addr, &l_emi->hdr.address))
datum_is_accepted_addr = true;
DAP_DELETE(l_emi);
json_object_object_add(l_jobj_datum, "data", dap_chain_datum_data_to_json(l_datum));
dap_chain_datum_dump_json(l_jobj_datum,l_datum,a_hash_out_type,a_net->pub.id);
}
break;
default:
json_object_object_add(l_jobj_datum, "data", dap_chain_datum_data_to_json(l_datum));
dap_chain_datum_dump_json(l_jobj_datum,l_datum,a_hash_out_type,a_net->pub.id);
}
}
if (l_wallet_addr) {
......@@ -3347,8 +3399,10 @@ int _cmd_mempool_check(dap_chain_net_t *a_net, dap_chain_t *a_chain, const char
json_object_object_add(l_obj_atom, "hash", l_jobj_atom_hash);
json_object_object_add(l_obj_atom, "ledger_response_code", l_jobj_atom_err);
json_object_object_add(l_jobj_datum, "atom", l_obj_atom);
}
json_object *l_datum_obj_inf = dap_chain_datum_to_json(l_datum);
}
json_object *l_datum_obj_inf = json_object_new_object();
dap_chain_datum_dump_json(l_datum_obj_inf, l_datum, a_hash_out_type, a_net->pub.id);
if (!l_datum_obj_inf) {
if (!l_found_in_chains)
DAP_DELETE(l_datum);
......@@ -3357,6 +3411,7 @@ int _cmd_mempool_check(dap_chain_net_t *a_net, dap_chain_t *a_chain, const char
"Failed to serialize datum to JSON.");
return DAP_JSON_RPC_ERR_CODE_SERIALIZATION_DATUM_TO_JSON;
}
json_object_object_add(l_jobj_datum, "datum", l_datum_obj_inf);
if (!l_found_in_chains)
DAP_DELETE(l_datum);
json_object_array_add(*a_json_reply, l_jobj_datum);
......@@ -3645,15 +3700,12 @@ int _cmd_mempool_dump_from_group(dap_chain_net_id_t a_net_id, const char *a_grou
return COM_DUMP_ERROR_LIST_CORRUPTED_SIZE;
}
if (!l_datum) {
char *l_msg_str = dap_strdup_printf("Error! Can't find datum %s in %s", a_datum_hash, a_group_gdb);
if (!l_msg_str) {
dap_json_rpc_allocation_error;
return -1;
}
json_object *l_jobj_message = json_object_new_string(l_msg_str);
dap_json_rpc_error_add(COM_DUMP_ERROR_LIST_CORRUPTED_SIZE, "Error! Can't find datum %s in %s", a_datum_hash, a_group_gdb);
return COM_DUMP_ERROR_CAN_NOT_FIND_DATUM;
}
json_object *l_jobj_datum = dap_chain_datum_to_json(l_datum);
json_object *l_jobj_datum = json_object_new_object();
dap_chain_datum_dump_json(l_jobj_datum, l_datum, a_hash_out_type, a_net_id);
json_object_array_add(*a_json_reply, l_jobj_datum);
return 0;
}
......@@ -6099,7 +6151,6 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **reply)
}
l_tx->header.ts_created = time(NULL);
size_t l_items_ready = 0;
size_t l_receipt_count = 0;
dap_list_t *l_sign_list = NULL;// list 'sing' items
dap_list_t *l_in_list = NULL;// list 'in' items
dap_list_t *l_tsd_list = NULL;// list tsd sections
......@@ -6397,9 +6448,7 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **reply)
size_t l_params_size = dap_strlen(l_params_str);
dap_chain_datum_tx_receipt_t *l_receipt = dap_chain_datum_tx_receipt_create(l_srv_uid, l_price_unit, l_units, l_value, l_params_str, l_params_size);
l_item = (const uint8_t*) l_receipt;
if(l_item)
l_receipt_count++;
else {
if (!l_item) {
char *l_str_err = dap_strdup_printf("Unable to create receipt out for transaction "
"described by item %zu.", i);
json_object *l_jobj_err = json_object_new_string(l_str_err);
......@@ -7078,6 +7127,8 @@ int com_tx_history(int a_argc, char ** a_argv, void **a_str_reply)
const char *l_net_str = NULL;
const char *l_chain_str = NULL;
const char *l_tx_hash_str = NULL;
const char *l_tx_srv_str = NULL;
const char *l_tx_act_str = NULL;
const char *l_limit_str = NULL;
const char *l_offset_str = NULL;
......@@ -7100,6 +7151,18 @@ int com_tx_history(int a_argc, char ** a_argv, void **a_str_reply)
dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-net", &l_net_str);
dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-chain", &l_chain_str);
dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-tx", &l_tx_hash_str);
dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-srv", &l_tx_srv_str);
dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-act", &l_tx_act_str);
dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-limit", &l_limit_str);
dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-offset", &l_offset_str);
size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 1000;
size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0;
//default is ALL/ANY
dap_chain_tx_tag_action_type_t l_action = dap_ledger_tx_action_str_to_action_t(l_tx_act_str);
bool l_brief = (dap_cli_server_cmd_check_option(a_argv, arg_index, a_argc, "-brief") != -1) ? true : false;
bool l_is_tx_all = dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-all", NULL);
......@@ -7145,7 +7208,15 @@ int com_tx_history(int a_argc, char ** a_argv, void **a_str_reply)
"Wallet address not recognized");
return DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_WALLET_ADDR_ERR;
}
l_net = dap_chain_net_by_id(l_addr->net_id);
if (l_net) {
if (l_net->pub.id.uint64 != l_addr->net_id.uint64) {
dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_ID_NET_ADDR_DIF_ERR,
"Network ID with '-net' param and network ID with '-addr' param are different");
DAP_DELETE(l_addr);
return DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_ID_NET_ADDR_DIF_ERR;
}
} else
l_net = dap_chain_net_by_id(l_addr->net_id);
}
if (l_wallet_name) {
const char *c_wallets_path = dap_chain_wallet_get_path(g_config);
......@@ -7206,11 +7277,7 @@ int com_tx_history(int a_argc, char ** a_argv, void **a_str_reply)
if (!json_obj_summary) {
return DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_MEMORY_ERR;
}
dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-limit", &l_limit_str);
dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-offset", &l_offset_str);
size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 1000;
size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0;
json_obj_out = dap_db_history_addr(l_addr, l_chain, l_hash_out_type, dap_chain_addr_to_str(l_addr), json_obj_summary, l_limit, l_offset);
json_obj_out = dap_db_history_addr(l_addr, l_chain, l_hash_out_type, dap_chain_addr_to_str(l_addr), json_obj_summary, l_limit, l_offset, l_brief, l_tx_srv_str, l_action);
if (!json_obj_out) {
dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_DAP_DB_HISTORY_ADDR_ERR,
"something went wrong in tx_history");
......@@ -7222,22 +7289,13 @@ int com_tx_history(int a_argc, char ** a_argv, void **a_str_reply)
return DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_OK;
} else if (l_is_tx_all) {
// history all
const char * l_brief_type = NULL;
bool l_brief_out = false;
if (dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-brief", &l_brief_type))
l_brief_out = true;
json_object * json_obj_summary = json_object_new_object();
if (!json_obj_summary) {
return DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_MEMORY_ERR;
}
dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-limit", &l_limit_str);
dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-offset", &l_offset_str);
size_t l_limit = l_limit_str ? strtoul(l_limit_str, NULL, 10) : 1000;
size_t l_offset = l_offset_str ? strtoul(l_offset_str, NULL, 10) : 0;
json_object* json_arr_history_all = dap_db_history_tx_all(l_chain, l_net, l_hash_out_type, json_obj_summary,
l_limit, l_offset, l_brief_out);
l_limit, l_offset, l_brief, l_tx_srv_str, l_action);
if (!json_arr_history_all) {
dap_json_rpc_error_add(DAP_CHAIN_NODE_CLI_COM_TX_HISTORY_DAP_DB_HISTORY_ALL_ERR,
"something went wrong in tx_history");
......@@ -7708,7 +7766,7 @@ int cmd_remove(int a_argc, char **a_argv, void **a_str_reply)
if (NULL == l_gdb_path)
l_net_returns = s_go_all_nets_offline();
for (dap_chain_net_t *it = dap_chain_net_iter_start(); it; it = dap_chain_net_iter_next(it)) {
s_dap_chain_net_purge(it);
dap_chain_net_purge(it);
}
if (!error)
successful |= REMOVED_CHAINS;
......@@ -7719,7 +7777,7 @@ int cmd_remove(int a_argc, char **a_argv, void **a_str_reply)
} else {
error |= NET_NOT_VALID;
}
s_dap_chain_net_purge(l_net);
dap_chain_net_purge(l_net);
if (!error)
successful |= REMOVED_CHAINS;
......@@ -8165,7 +8223,6 @@ static int s_sign_file(const char *a_filename, dap_sign_signer_file_t a_flags, c
{
uint32_t l_shift = 1;
int l_count_meta = 0;
int l_index_meta = 0;
char *l_buffer = NULL;
if (a_flags == SIGNER_ALL_FLAGS) {
......@@ -8194,7 +8251,6 @@ static int s_sign_file(const char *a_filename, dap_sign_signer_file_t a_flags, c
dap_tsd_t *l_item = s_alloc_metadata(a_filename, l_shift & a_flags);
if (l_item) {
l_std_list = dap_list_append(l_std_list, l_item);
l_index_meta++;
}
}
l_shift <<= 1;
......
......@@ -26,7 +26,7 @@
#include <stddef.h>
#include <pthread.h>
#include "dap_chain_wallet.h"
#include "dap_cli_server.h"
#include "dap_common.h"
#include "dap_enc_base58.h"
#include "dap_strfuncs.h"
......@@ -40,14 +40,14 @@
#include "dap_chain_datum_token.h"
#include "dap_chain_datum_decree.h"
#include "dap_chain_datum_tx_items.h"
#include "dap_chain_node_cli.h"
#include "dap_chain_datum_anchor.h"
#include "dap_chain_node_cli_cmd_tx.h"
#include "dap_chain_net_tx.h"
#include "dap_chain_net_decree.h"
#include "dap_chain_mempool.h"
#include "dap_math_convert.h"
#include "dap_json_rpc_errors.h"
#include "dap_json_rpc_chain_datum_tx.h"
#define LOG_TAG "chain_node_cli_cmd_tx"
......@@ -92,7 +92,7 @@ void s_dap_chain_tx_hash_processed_ht_free(dap_chain_tx_hash_processed_ht_t **l_
* @param l_tx_num
*/
static bool s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum,
bool s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum,
dap_ledger_t *a_ledger,
json_object * json_obj_out,
const char *a_hash_out_type,
......@@ -106,13 +106,16 @@ static bool s_dap_chain_datum_tx_out_data(dap_chain_datum_tx_t *a_datum,
: NULL;
if (!l_ticker)
return false;
const char *l_description = dap_ledger_get_description_by_ticker(a_ledger, l_ticker);
dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, l_ts_create);
dap_chain_hash_fast_to_str(a_tx_hash,l_tx_hash_str,sizeof(l_tx_hash_str));
json_object_object_add(json_obj_out, "Datum_tx_hash", json_object_new_string(l_tx_hash_str));
json_object_object_add(json_obj_out, "TS_Created", json_object_new_string(l_tmp_buf));
json_object_object_add(json_obj_out, "Token_ticker", json_object_new_string(l_ticker));
json_object* datum_tx = dap_chain_datum_tx_to_json(a_datum,&a_ledger->net->pub.id);
json_object_object_add(json_obj_out, "Datum_tx", datum_tx);
json_object_object_add(json_obj_out, "Token_description", l_description ? json_object_new_string(l_description)
: json_object_new_null());
dap_chain_datum_dump_tx_json(a_datum, l_ticker, json_obj_out, a_hash_out_type, a_tx_hash, a_ledger->net->pub.id);
dap_list_t *l_out_items = dap_chain_datum_tx_items_get(a_datum, TX_ITEM_TYPE_OUT_ALL, NULL);
int l_out_idx = 0;
json_object* json_arr_items = json_object_new_array();
......@@ -156,6 +159,7 @@ json_object * dap_db_tx_history_to_json(dap_chain_hash_fast_t* a_tx_hash,
bool brief_out)
{
const char *l_tx_token_ticker = NULL;
const char *l_tx_token_description = NULL;
json_object* json_obj_datum = json_object_new_object();
if (!json_obj_datum) {
return NULL;
......@@ -165,6 +169,7 @@ json_object * dap_db_tx_history_to_json(dap_chain_hash_fast_t* a_tx_hash,
l_tx_token_ticker = dap_ledger_tx_get_token_ticker_by_hash(l_ledger, a_tx_hash);
if (l_tx_token_ticker) {
json_object_object_add(json_obj_datum, "status", json_object_new_string("ACCEPTED"));
l_tx_token_description = dap_ledger_get_description_by_ticker(l_ledger, l_tx_token_ticker);
*accepted_tx = true;
} else {
json_object_object_add(json_obj_datum, "status", json_object_new_string("DECLINED"));
......@@ -185,10 +190,27 @@ json_object * dap_db_tx_history_to_json(dap_chain_hash_fast_t* a_tx_hash,
json_object_object_add(json_obj_datum, "token_ticker", l_tx_token_ticker ? json_object_new_string(l_tx_token_ticker)
: json_object_new_null());
json_object_object_add(json_obj_datum, "token_description", l_tx_token_description ? json_object_new_string(l_tx_token_description)
: json_object_new_null());
json_object_object_add(json_obj_datum, "ret_code", json_object_new_int(l_ret_code));
json_object_object_add(json_obj_datum, "ret_code_str", json_object_new_string(dap_ledger_tx_check_err_str(l_ret_code)));
dap_chain_net_srv_uid_t uid;
char *service_name;
dap_chain_tx_tag_action_type_t action;
if (dap_ledger_tx_service_info(l_ledger, a_tx_hash, &uid, &service_name, &action))
{
json_object_object_add(json_obj_datum, "service", json_object_new_string(service_name));
json_object_object_add(json_obj_datum, "action", json_object_new_string(dap_ledger_tx_action_str(action)));
}
else
{
json_object_object_add(json_obj_datum, "service", json_object_new_string("UNKNOWN"));
json_object_object_add(json_obj_datum, "action", json_object_new_string("UNKNOWN"));
}
char l_time_str[DAP_TIME_STR_SIZE];
if (l_tx->header.ts_created) {
dap_time_to_str_rfc822(l_time_str, DAP_TIME_STR_SIZE, l_tx->header.ts_created);/* Convert ts to "Sat May 17 01:17:08 2014\n" */
......@@ -198,9 +220,8 @@ json_object * dap_db_tx_history_to_json(dap_chain_hash_fast_t* a_tx_hash,
json_object_object_add(json_obj_datum, "tx_created", l_obj_ts_created);
if(!brief_out)
{
json_object* datum_tx = dap_chain_datum_tx_to_json(l_tx,&a_chain->net_id);
json_object_object_add(json_obj_datum, "items", datum_tx);
{
dap_chain_datum_dump_tx_json(l_tx,NULL,json_obj_datum,a_hash_out_type,a_tx_hash,a_chain->net_id);
}
return json_obj_datum;
......@@ -277,6 +298,23 @@ static void s_tx_header_print(json_object* json_obj_datum, dap_chain_tx_hash_pro
json_object_object_add(json_obj_datum, "atom_hash", json_object_new_string(l_atom_hash_str));
json_object_object_add(json_obj_datum, "ret_code", json_object_new_int(a_ret_code));
json_object_object_add(json_obj_datum, "ret_code_str", json_object_new_string(dap_ledger_tx_check_err_str(a_ret_code)));
dap_chain_net_srv_uid_t uid;
char *service_name;
dap_chain_tx_tag_action_type_t action;
if (dap_ledger_tx_service_info(a_ledger, a_tx_hash, &uid, &service_name, &action))
{
json_object_object_add(json_obj_datum, "service", json_object_new_string(service_name));
json_object_object_add(json_obj_datum, "action", json_object_new_string(dap_ledger_tx_action_str(action)));
}
else
{
json_object_object_add(json_obj_datum, "service", json_object_new_string("UNKNOWN"));
json_object_object_add(json_obj_datum, "action", json_object_new_string("UNKNOWN"));
}
json_object_object_add(json_obj_datum, "tx_created", json_object_new_string(l_time_str));
DAP_DELETE(l_tx_hash_str);
......@@ -296,7 +334,7 @@ static void s_tx_header_print(json_object* json_obj_datum, dap_chain_tx_hash_pro
*/
json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain,
const char *a_hash_out_type, const char * l_addr_str, json_object *json_obj_summary,
size_t a_limit, size_t a_offset)
size_t a_limit, size_t a_offset, bool a_brief, const char *a_srv, dap_chain_tx_tag_action_type_t a_action)
{
json_object* json_obj_datum = json_object_new_array();
if (!json_obj_datum){
......@@ -331,24 +369,23 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain,
bool l_net_fee_used = dap_chain_net_tx_get_fee(l_net->pub.id, NULL, &l_net_fee_addr);
bool l_is_need_correction = false;
uint256_t l_corr_value = {}, l_unstake_value = {};
bool look_for_unknown_service = (a_srv && strcmp(a_srv,"unknown") == 0);
json_object* json_obj_lim = json_object_new_object();
size_t l_arr_start = 0;
if (a_offset){
l_arr_start = a_offset;
json_object* json_obj_off = json_object_new_object();
json_object_object_add(json_obj_off, "offset", json_object_new_int(l_arr_start));
json_object_array_add(json_obj_datum, json_obj_off);
json_object_object_add(json_obj_lim, "offset", json_object_new_int(l_arr_start));
}
size_t l_arr_end = a_chain->callback_count_atom(a_chain);
if (a_limit) {
json_object* json_obj_lim = json_object_new_object();
json_object_object_add(json_obj_lim, "limit", json_object_new_int(a_limit));
json_object_array_add(json_obj_datum, json_obj_lim);
json_object_object_add(json_obj_lim, "limit", json_object_new_int(a_limit));
l_arr_end = l_arr_start + a_limit;
size_t l_length = a_chain->callback_count_atom(a_chain);
if (l_arr_end > l_length)
l_arr_end = l_length;
}
json_object_array_add(json_obj_datum, json_obj_lim);
size_t i_tmp = 0;
// load transactions
dap_chain_datum_iter_t *l_datum_iter = a_chain->callback_datum_iter_create(a_chain);
......@@ -360,7 +397,7 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain,
json_object *l_corr_object = NULL;
if (l_datum->header.type_id != DAP_CHAIN_DATUM_TX)
// go to next datum
continue;
continue;
// it's a transaction
bool l_is_unstake = false;
dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t *)l_datum->data;
......@@ -368,6 +405,11 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain,
if (!l_list_in_items) // a bad tx
continue;
// all in items should be from the same address
if (i_tmp >= l_arr_end || i_tmp < l_arr_start) {
i_tmp++;
continue;
}
i_tmp++;
dap_chain_addr_t *l_src_addr = NULL;
bool l_base_tx = false, l_reward_collect = false;
const char *l_noaddr_token = NULL;
......@@ -515,46 +557,68 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain,
if (l_dst_addr && l_net_fee_used && dap_chain_addr_compare(&l_net_fee_addr, l_dst_addr))
SUM_256_256(l_fee_sum, l_value, &l_fee_sum);
//tag
char *service_name = NULL;
dap_chain_tx_tag_action_type_t l_action;
bool srv_found = dap_ledger_tx_service_info(l_ledger, &l_tx_hash, NULL, &service_name, &l_action);
if (!(l_action & a_action))
continue;
if (a_srv)
{
//skip if looking for UNKNOWN + it is known
if (look_for_unknown_service && srv_found) {
continue;
}
//skip if search condition provided, it not UNKNOWN and found name not match
if (!look_for_unknown_service && (!srv_found || strcmp(service_name, a_srv) != 0))
{
continue;
}
}
if (l_dst_addr && dap_chain_addr_compare(l_dst_addr, a_addr)) {
if (!l_header_printed) {
s_tx_header_print(j_obj_tx, &l_tx_data_ht, l_tx, l_datum_iter->cur_atom_hash,
a_hash_out_type, l_ledger, &l_tx_hash, l_datum_iter->ret_code);
l_header_printed = true;
}
char *l_src_str = NULL;
const char *l_src_str = NULL;
if (l_base_tx)
l_src_str = l_reward_collect ? "reward collecting" : "emission";
else if (l_src_addr && dap_strcmp(l_dst_token, l_noaddr_token))
l_src_str = dap_chain_addr_to_str(l_src_addr);
else
l_src_str = (char*)dap_chain_tx_out_cond_subtype_to_str(l_src_subtype);
l_src_str = dap_chain_tx_out_cond_subtype_to_str(l_src_subtype);
if (l_is_unstake)
l_value = l_unstake_value;
else if (!dap_strcmp(l_native_ticker, l_noaddr_token)) {
l_is_need_correction = true;
l_corr_value = l_value;
}
char *l_coins_str, *l_value_str = dap_uint256_to_char(l_value, &l_coins_str);
if (i_tmp > l_arr_start && i_tmp <= l_arr_end) {
json_object *j_obj_data = json_object_new_object();
if (!j_obj_data) {
dap_json_rpc_allocation_error;
json_object_put(j_obj_tx);
json_object_put(j_arr_data);
return NULL;
}
json_object_object_add(j_obj_data, "tx_type", json_object_new_string("recv"));
json_object_object_add(j_obj_data, "recv_coins", json_object_new_string(l_coins_str));
json_object_object_add(j_obj_data, "recv_datoshi", json_object_new_string(l_value_str));
json_object_object_add(j_obj_data, "token", l_dst_token ? json_object_new_string(l_dst_token)
: json_object_new_string("UNKNOWN"));
json_object_object_add(j_obj_data, "source_address", json_object_new_string(l_src_str));
if (l_is_need_correction)
l_corr_object = j_obj_data;
else
json_object_array_add(j_arr_data, j_obj_data);
const char *l_coins_str, *l_value_str = dap_uint256_to_char(l_value, &l_coins_str);
json_object *j_obj_data = json_object_new_object();
if (!j_obj_data) {
dap_json_rpc_allocation_error;
json_object_put(j_obj_tx);
json_object_put(j_arr_data);
return NULL;
}
i_tmp++;
json_object_object_add(j_obj_data, "tx_type", json_object_new_string("recv"));
json_object_object_add(j_obj_data, "recv_coins", json_object_new_string(l_coins_str));
json_object_object_add(j_obj_data, "recv_datoshi", json_object_new_string(l_value_str));
json_object_object_add(j_obj_data, "token", l_dst_token ? json_object_new_string(l_dst_token)
: json_object_new_string("UNKNOWN"));
json_object_object_add(j_obj_data, "source_address", json_object_new_string(l_src_str));
if (l_is_need_correction)
l_corr_object = j_obj_data;
else
json_object_array_add(j_arr_data, j_obj_data);
} else if (!l_src_addr || dap_chain_addr_compare(l_src_addr, a_addr)) {
if (!l_dst_addr && ((dap_chain_tx_out_cond_t *)it->data)->header.subtype == l_src_subtype && l_src_subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE)
continue;
......@@ -569,24 +633,21 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain,
const char *l_dst_addr_str = l_dst_addr ? dap_chain_addr_to_str(l_dst_addr)
: dap_chain_tx_out_cond_subtype_to_str(
((dap_chain_tx_out_cond_t *)it->data)->header.subtype);
char *l_coins_str, *l_value_str = dap_uint256_to_char(l_value, &l_coins_str);
if (i_tmp > l_arr_start && i_tmp <= l_arr_end) {
json_object * j_obj_data = json_object_new_object();
if (!j_obj_data) {
dap_json_rpc_allocation_error;
json_object_put(j_obj_tx);
json_object_put(j_arr_data);
return NULL;
}
json_object_object_add(j_obj_data, "tx_type", json_object_new_string("send"));
json_object_object_add(j_obj_data, "send_coins", json_object_new_string(l_coins_str));
json_object_object_add(j_obj_data, "send_datoshi", json_object_new_string(l_value_str));
json_object_object_add(j_obj_data, "token", l_dst_token ? json_object_new_string(l_dst_token)
: json_object_new_string("UNKNOWN"));
json_object_object_add(j_obj_data, "destination_address", json_object_new_string(l_dst_addr_str));
json_object_array_add(j_arr_data, j_obj_data);
const char *l_coins_str, *l_value_str = dap_uint256_to_char(l_value, &l_coins_str);
json_object * j_obj_data = json_object_new_object();
if (!j_obj_data) {
dap_json_rpc_allocation_error;
json_object_put(j_obj_tx);
json_object_put(j_arr_data);
return NULL;
}
i_tmp++;
json_object_object_add(j_obj_data, "tx_type", json_object_new_string("send"));
json_object_object_add(j_obj_data, "send_coins", json_object_new_string(l_coins_str));
json_object_object_add(j_obj_data, "send_datoshi", json_object_new_string(l_value_str));
json_object_object_add(j_obj_data, "token", l_dst_token ? json_object_new_string(l_dst_token)
: json_object_new_string("UNKNOWN"));
json_object_object_add(j_obj_data, "destination_address", json_object_new_string(l_dst_addr_str));
json_object_array_add(j_arr_data, j_obj_data);
}
}
if (json_object_array_length(j_arr_data) > 0) {
......@@ -596,7 +657,7 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain,
dap_list_free(l_list_out_items);
if (l_is_need_correction && l_corr_object) {
SUM_256_256(l_corr_value, l_fee_sum, &l_corr_value);
char *l_coins_str, *l_value_str = dap_uint256_to_char(l_corr_value, &l_coins_str);
const char *l_coins_str, *l_value_str = dap_uint256_to_char(l_corr_value, &l_coins_str);
json_object_object_add(l_corr_object, "recv_coins", json_object_new_string(l_coins_str));
json_object_object_add(l_corr_object, "recv_datoshi", json_object_new_string(l_value_str));
if (!j_arr_data) {
......@@ -629,7 +690,9 @@ json_object* dap_db_history_addr(dap_chain_addr_t *a_addr, dap_chain_t *a_chain,
json_object *dap_db_history_tx_all(dap_chain_t *l_chain, dap_chain_net_t *l_net,
const char *l_hash_out_type, json_object *json_obj_summary,
size_t a_limit, size_t a_offset, bool out_brief)
size_t a_limit, size_t a_offset, bool out_brief,
const char *a_srv,
dap_chain_tx_tag_action_type_t a_action)
{
log_it(L_DEBUG, "Start getting tx from chain");
size_t
......@@ -642,43 +705,65 @@ json_object *dap_db_history_tx_all(dap_chain_t *l_chain, dap_chain_net_t *l_net,
*l_cell_tmp = NULL;
dap_chain_atom_iter_t *l_iter = NULL;
json_object * json_arr_out = json_object_new_array();
json_object* json_obj_lim = json_object_new_object();
size_t l_arr_start = 0;
if (a_offset) {
l_arr_start = a_offset;
json_object* json_obj_off = json_object_new_object();
json_object_object_add(json_obj_off, "offset", json_object_new_int(l_arr_start));
json_object_array_add(json_arr_out, json_obj_off);
json_object_object_add(json_obj_lim, "offset", json_object_new_int(l_arr_start));
}
size_t l_arr_end = l_chain->callback_count_atom(l_chain);
if (a_limit) {
l_arr_end = l_arr_start + a_limit;
json_object* json_obj_lim = json_object_new_object();
json_object_object_add(json_obj_lim, "limit", json_object_new_int(a_limit));
json_object_array_add(json_arr_out, json_obj_lim);
if (l_arr_end > l_chain->callback_count_atom(l_chain)) {
l_arr_end = l_chain->callback_count_atom(l_chain);
}
l_arr_end = a_limit ? l_arr_start + a_limit : l_arr_start + 1000;
json_object_object_add(json_obj_lim, "limit", json_object_new_int(l_arr_end - l_arr_start));
json_object_array_add(json_arr_out, json_obj_lim);
if (l_arr_end > l_chain->callback_count_atom(l_chain)) {
l_arr_end = l_chain->callback_count_atom(l_chain);
}
size_t i_tmp = 1;
bool look_for_unknown_service = (a_srv && strcmp(a_srv,"unknown") == 0);
HASH_ITER(hh, l_chain->cells, l_cell, l_cell_tmp) {
if (a_limit && l_count_tx >= a_limit)
if (l_count_tx >= l_arr_end)
break;
l_iter = l_chain->callback_atom_iter_create(l_chain, l_cell->id, NULL);
size_t l_atom_size = 0;
dap_chain_atom_ptr_t l_ptr = l_chain->callback_atom_iter_get(l_iter, DAP_CHAIN_ITER_OP_FIRST, &l_atom_size);
while (l_ptr && l_atom_size && (a_limit ? l_count_tx < a_limit : true)) {
while (l_ptr && l_atom_size && (l_count_tx < l_arr_end)) {
size_t l_datums_count = 0;
dap_chain_datum_t **l_datums = l_cell->chain->callback_atom_get_datums(l_ptr, l_atom_size, &l_datums_count);
for (size_t i = 0; i < l_datums_count && (a_limit ? l_count_tx < a_limit : true); i++) {
for (size_t i = 0; i < l_datums_count && (l_count_tx < l_arr_end); i++) {
if (l_datums[i]->header.type_id == DAP_CHAIN_DATUM_TX) {
if (i_tmp < l_arr_start || i_tmp >= l_arr_end) {
i_tmp++;
if (l_count_tx < l_arr_start) {
l_count_tx++;
continue;
}
i_tmp++;
dap_chain_datum_tx_t *l_tx = (dap_chain_datum_tx_t*)l_datums[i]->data;
dap_hash_fast_t l_ttx_hash = {0};
dap_hash_fast(l_tx, l_datums[i]->header.data_size, &l_ttx_hash);
char *service_name = NULL;
dap_chain_tx_tag_action_type_t l_action;
dap_ledger_t *l_ledger = l_net->pub.ledger;
bool srv_found = dap_ledger_tx_service_info(l_ledger, &l_ttx_hash, NULL, &service_name, &l_action);
if (!(l_action & a_action))
continue;
if (a_srv)
{
char *service_name = NULL;
bool srv_found = dap_ledger_tx_service_info(l_ledger, &l_ttx_hash, NULL, &service_name, NULL);
//skip if looking for UNKNOWN + it is known
if (look_for_unknown_service && srv_found) {
continue;
}
//skip if search condition provided, it not UNKNOWN and found name not match
if (!look_for_unknown_service && (!srv_found || strcmp(service_name, a_srv) != 0))
{
continue;
}
}
bool accepted_tx;
json_object* json_obj_datum = dap_db_tx_history_to_json(&l_ttx_hash, NULL, l_tx, l_chain, l_hash_out_type, l_net, 0, &accepted_tx, out_brief);
if (!json_obj_datum) {
......@@ -691,8 +776,9 @@ json_object *dap_db_history_tx_all(dap_chain_t *l_chain, dap_chain_net_t *l_net,
++l_tx_ledger_rejected;
}
json_object_array_add(json_arr_out, json_obj_datum);
const char * debug_json_string = json_object_to_json_string(json_obj_datum);
//const char * debug_json_string = json_object_to_json_string(json_obj_datum);
++l_count_tx;
l_count++;
}
}
DAP_DEL_Z(l_datums);
......@@ -704,7 +790,7 @@ json_object *dap_db_history_tx_all(dap_chain_t *l_chain, dap_chain_net_t *l_net,
json_object_object_add(json_obj_summary, "network", json_object_new_string(l_net->pub.name));
json_object_object_add(json_obj_summary, "chain", json_object_new_string(l_chain->name));
json_object_object_add(json_obj_summary, "tx_sum", json_object_new_int(l_count_tx));
json_object_object_add(json_obj_summary, "tx_sum", json_object_new_int(l_count));
json_object_object_add(json_obj_summary, "accepted_tx", json_object_new_int(l_tx_ledger_accepted));
json_object_object_add(json_obj_summary, "rejected_tx", json_object_new_int(l_tx_ledger_rejected));
return json_arr_out;
......
......@@ -37,6 +37,9 @@
#include "dap_chain_datum_tx_items.h"
#include "dap_chain_net.h"
#define DAP_CHAIN_NET_SRV_TRANSFER_ID 0x07
#define DAP_CHAIN_NET_SRV_BLOCK_REWARD_ID 0x08
typedef struct dap_ledger {
dap_chain_net_t *net;
void *_internal;
......@@ -114,6 +117,27 @@ typedef enum dap_ledger_token_decl_add_err{
DAP_LEDGER_TOKEN_DECL_ADD_UNKNOWN /* MAX */
} dap_ledger_token_decl_add_err_t;
typedef enum dap_chain_tx_tag_action_type {
//subtags, till 32
DAP_CHAIN_TX_TAG_ACTION_UNKNOWN = 1 << 1,
DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REGULAR = 1 << 2,
DAP_CHAIN_TX_TAG_ACTION_TRANSFER_COMISSION = 1 << 3,
DAP_CHAIN_TX_TAG_ACTION_TRANSFER_CROSSCHAIN = 1 << 4,
DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REWARD = 1 << 5,
DAP_CHAIN_TX_TAG_ACTION_OPEN = 1 << 6,
DAP_CHAIN_TX_TAG_ACTION_USE = 1 << 7,
DAP_CHAIN_TX_TAG_ACTION_EXTEND = 1 << 8,
DAP_CHAIN_TX_TAG_ACTION_CHANGE = 1 << 9,
DAP_CHAIN_TX_TAG_ACTION_CLOSE = 1 << 10,
DAP_CHAIN_TX_TAG_ACTION_ALL = ~0,
} dap_chain_tx_tag_action_type_t;
typedef struct dap_ledger_datum_iter {
dap_chain_net_t *net;
dap_chain_datum_tx_t *cur;
......@@ -127,9 +151,10 @@ typedef bool (*dap_ledger_verificator_callback_t)(dap_ledger_t *a_ledger, dap_ch
typedef void (*dap_ledger_updater_callback_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_tx_out_cond_t *a_prev_cond);
typedef void (* dap_ledger_tx_add_notify_t)(void *a_arg, dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx);
typedef void (* dap_ledger_bridged_tx_notify_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, void *a_arg);
typedef bool (*dap_ledger_cache_tx_check_callback_t)(dap_hash_fast_t *a_tx_hash);
typedef bool (*dap_ledger_cache_tx_check_callback_t)(dap_ledger_t *a_ledger, dap_hash_fast_t *a_tx_hash);
typedef struct dap_chain_net dap_chain_net_t;
typedef bool (*dap_chain_ledger_voting_callback_t)(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_type, dap_chain_datum_tx_t *a_tx, bool a_apply);
typedef bool (*dap_ledger_tag_check_callback_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_datum_tx_item_groups_t *a_items_grp, dap_chain_tx_tag_action_type_t *a_action);
//Change this UUID to automatically reload ledger cache on next node startup
#define DAP_LEDGER_CACHE_RELOAD_ONCE_UUID "0c92b759-a565-448f-b8bd-99103dacf7fc"
......@@ -267,13 +292,34 @@ void dap_ledger_addr_get_token_ticker_all_depricated(dap_ledger_t *a_ledger, dap
void dap_ledger_addr_get_token_ticker_all(dap_ledger_t *a_ledger, dap_chain_addr_t * a_addr,
char *** a_tickers, size_t * a_tickers_size);
const char *dap_ledger_get_description_by_ticker(dap_ledger_t *a_ledger, const char *a_token_ticker);
bool dap_ledger_tx_poa_signed(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx);
// Checking a new transaction before adding to the cache
int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash,
bool a_from_threshold, dap_list_t **a_list_bound_items, dap_list_t **a_list_tx_out, char **a_main_ticker);
//TX service-tags
bool dap_ledger_deduct_tx_tag(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_chain_net_srv_uid_t *uid, dap_chain_tx_tag_action_type_t *action);
const char *dap_ledger_tx_action_str(dap_chain_tx_tag_action_type_t a_tag);
dap_chain_tx_tag_action_type_t dap_ledger_tx_action_str_to_action_t(const char *a_str);
bool dap_ledger_tx_service_info(dap_ledger_t *a_ledger, dap_hash_fast_t *a_tx_hash,
dap_chain_net_srv_uid_t *a_uid, char **a_service_name, dap_chain_tx_tag_action_type_t *a_action);
const char *dap_ledger_tx_get_main_ticker(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, int *a_ledger_rc);
int dap_ledger_service_add(dap_chain_net_srv_uid_t a_uid, char *tag_str, dap_ledger_tag_check_callback_t a_callback);
// Checking a new transaction before adding to the cache
int dap_ledger_tx_cache_check(dap_ledger_t *a_ledger,
dap_chain_datum_tx_t *a_tx,
dap_hash_fast_t *a_tx_hash,
bool a_from_threshold,
dap_list_t **a_list_bound_items,
dap_list_t **a_list_tx_out,
char **a_main_ticker,
dap_chain_net_srv_uid_t *a_tag,
dap_chain_tx_tag_action_type_t *a_action);
const char *dap_ledger_tx_calculate_main_ticker(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, int *a_ledger_rc);
/**
* Delete all transactions from the cache
......@@ -374,3 +420,4 @@ void dap_ledger_bridged_tx_notify_add(dap_ledger_t *a_ledger, dap_ledger_bridged
bool dap_ledger_cache_enabled(dap_ledger_t *a_ledger);
void dap_ledger_set_cache_tx_check_callback(dap_ledger_t *a_ledger, dap_ledger_cache_tx_check_callback_t a_callback);
dap_chain_tx_out_cond_t* dap_chain_ledger_get_tx_out_cond_linked_to_tx_in_cond(dap_ledger_t *a_ledger, dap_chain_tx_in_cond_t *a_in_cond);