Skip to content
Snippets Groups Projects

Compare revisions

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

Source

Select target project
No results found

Target

Select target project
  • cellframe/cellframe-sdk
  • MIKA83/cellframe-sdk
2 results
Show changes
Commits on Source (29)
Showing
with 770 additions and 868 deletions
Subproject commit 9db9d52588ceaae60bc7b57ca96888fdf03bb128
Subproject commit c2246d6f0f8fc8b33a6b9402fbd9e5b97b95dee1
......@@ -916,7 +916,7 @@ void dap_chain_datum_notify(dap_chain_cell_t *a_chain_cell, dap_hash_fast_t *a_
.callback = l_notifier->callback, .callback_arg = l_notifier->arg,
.chain = a_chain_cell->chain, .cell_id = a_chain_cell->id,
.hash = *a_hash,
.datum = a_chain_cell->chain->is_mapped ? (byte_t*)a_datum : DAP_DUP_SIZE(a_datum, a_datum_size),
.datum = a_chain_cell->chain->is_mapped ? (byte_t*)a_datum : DAP_DUP_SIZE((uint8_t*)a_datum, a_datum_size),
.datum_size = a_datum_size,
.ret_code = a_ret_code,
.action = a_action,
......
......@@ -545,7 +545,7 @@ dap_chain_tx_out_cond_t *dap_chain_datum_tx_out_cond_get(dap_chain_datum_tx_t *a
switch (*l_item) {
case TX_ITEM_TYPE_OUT_COND:
if ( l_idx >= 0 && ((dap_chain_tx_out_cond_t*)l_item)->header.subtype == a_cond_subtype )
return (a_out_num ? (*a_out_num = l_idx) : 0), (dap_chain_tx_out_cond_t*)l_item;
return ( a_out_num ? (*a_out_num += l_idx) : 0 ), (dap_chain_tx_out_cond_t*)l_item;
case TX_ITEM_TYPE_OUT: case TX_ITEM_TYPE_OUT_OLD: case TX_ITEM_TYPE_OUT_EXT:
++l_idx;
default:
......@@ -683,3 +683,16 @@ bool dap_chain_datum_tx_group_items(dap_chain_datum_tx_t *a_tx, dap_chain_datum_
return true;
}
dap_chain_tx_tsd_t *dap_chain_datum_tx_item_get_tsd_by_type(dap_chain_datum_tx_t *a_tx, int a_type)
{
dap_return_val_if_pass(!a_tx, NULL);
byte_t *l_item = NULL;
size_t l_tx_item_size = 0;
TX_ITEM_ITER_TX(l_item, l_tx_item_size, a_tx) {
if (*l_item == TX_ITEM_TYPE_TSD && ((dap_tsd_t *)(((dap_chain_tx_tsd_t *)l_item)->tsd))->type == a_type)
return (dap_chain_tx_tsd_t *)l_item;
}
return NULL;
}
......@@ -388,6 +388,9 @@ typedef struct dap_chain_datum_token_emission {
#define DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_UNIQUE_ID 0x000F
#define DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_BASE_TX_HASH 0x0010
// TSD sections with transfer additional params
#define DAP_CHAIN_DATUM_TRANSFER_TSD_TYPE_OUT_COUNT 0x0013
#define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_STAKING "STAKING"
#define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_STAKE_CROSSCHAIN "CONTRACT"
#define DAP_CHAIN_DATUM_TOKEN_EMISSION_SOURCE_SUBTYPE_STAKING_STAKE_CROSSCHAINV2 "CONTRACT_NFT"
......
......@@ -247,6 +247,7 @@ json_object* dap_chain_datum_tx_item_sig_to_json(const dap_chain_tx_sig_t *a_sig
dap_sign_t *dap_chain_datum_tx_item_sign_get_sig(dap_chain_tx_sig_t *a_tx_sig);
byte_t *dap_chain_datum_tx_item_get_data(dap_chain_tx_tsd_t *a_tx_tsd, int *a_type, size_t *a_size);
dap_chain_tx_tsd_t *dap_chain_datum_tx_item_get_tsd_by_type(dap_chain_datum_tx_t *a_tx, int a_type);
/**
* Get item from transaction
......
......@@ -3062,8 +3062,8 @@ static int s_cli_esbocs(int a_argc, char **a_argv, void **a_str_reply)
(dap_cli_server_cmd_check_option(a_argv, l_arg_index, l_arg_index + 1, "add") > 0 && l_subcmd == SUBCMD_EMERGENCY_VALIDATOR) ||
(dap_cli_server_cmd_check_option(a_argv, l_arg_index, l_arg_index + 1, "remove") > 0 && l_subcmd == SUBCMD_EMERGENCY_VALIDATOR))
{
if (dap_cli_server_cmd_check_option(a_argv, l_arg_index, l_arg_index + 1, "enable") ||
dap_cli_server_cmd_check_option(a_argv, l_arg_index, l_arg_index + 1, "add"))
if (dap_cli_server_cmd_check_option(a_argv, l_arg_index, l_arg_index + 1, "enable") != -1 ||
dap_cli_server_cmd_check_option(a_argv, l_arg_index, l_arg_index + 1, "add") != -1)
l_subcommand_add = true;
const char *l_cert_str = NULL;
dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-cert", &l_cert_str);
......
......@@ -141,20 +141,27 @@ char *dap_chain_mempool_datum_add(const dap_chain_datum_t *a_datum, dap_chain_t
*
* return 0 Ok, -2 not enough funds to transfer, -1 other Error
*/
char *dap_chain_mempool_tx_create(dap_chain_t * a_chain, dap_enc_key_t *a_key_from,
const dap_chain_addr_t* a_addr_from, const dap_chain_addr_t* a_addr_to,
char *dap_chain_mempool_tx_create(dap_chain_t *a_chain, dap_enc_key_t *a_key_from,
const dap_chain_addr_t* a_addr_from, const dap_chain_addr_t** a_addr_to,
const char a_token_ticker[DAP_CHAIN_TICKER_SIZE_MAX],
uint256_t a_value, uint256_t a_value_fee, const char *a_hash_out_type)
uint256_t *a_value, uint256_t a_value_fee, const char *a_hash_out_type, size_t a_tx_num)
{
// check valid param
dap_return_val_if_pass(!a_chain | !a_key_from || !a_addr_from || !a_key_from->priv_key_data || !a_key_from->priv_key_data_size ||
dap_chain_addr_check_sum(a_addr_from) || (a_addr_to && dap_chain_addr_check_sum(a_addr_to)) || IS_ZERO_256(a_value), NULL);
dap_chain_addr_check_sum(a_addr_from) || !a_tx_num || !a_value, NULL);
for (size_t i = 0; i < a_tx_num; ++i) {
dap_return_val_if_pass((a_addr_to && dap_chain_addr_check_sum(a_addr_to[i])) || IS_ZERO_256(a_value[i]), NULL);
}
const char *l_native_ticker = dap_chain_net_by_id(a_chain->net_id)->pub.native_ticker;
bool l_single_channel = !dap_strcmp(a_token_ticker, l_native_ticker);
// find the transactions from which to take away coins
uint256_t l_value_transfer = {}; // how many coins to transfer
uint256_t l_value_need = a_value, l_net_fee = {}, l_total_fee = {}, l_fee_transfer = {};
uint256_t l_value_total = {}, l_net_fee = {}, l_total_fee = {}, l_fee_transfer = {};
for (size_t i = 0; i < a_tx_num; ++i) {
SUM_256_256(l_value_total, a_value[i], &l_value_total);
}
uint256_t l_value_need = l_value_total;
dap_chain_addr_t l_addr_fee = {};
dap_list_t *l_list_fee_out = NULL;
bool l_net_fee_used = dap_chain_net_tx_get_fee(a_chain->net_id, &l_net_fee, &l_addr_fee);
......@@ -193,14 +200,21 @@ char *dap_chain_mempool_tx_create(dap_chain_t * a_chain, dap_enc_key_t *a_key_fr
}
}
if (a_tx_num > 1) {
uint32_t l_tx_num = a_tx_num;
dap_chain_tx_tsd_t *l_out_count = dap_chain_datum_tx_item_tsd_create(&l_tx_num, DAP_CHAIN_DATUM_TRANSFER_TSD_TYPE_OUT_COUNT, sizeof(uint32_t));
dap_chain_datum_tx_add_item(&l_tx, l_out_count);
}
if (l_single_channel) { // add 'out' items
uint256_t l_value_pack = {}; // how much datoshi add to 'out' items
if (dap_chain_datum_tx_add_out_item(&l_tx, a_addr_to, a_value) == 1) {
SUM_256_256(l_value_pack, a_value, &l_value_pack);
} else {
dap_chain_datum_tx_delete(l_tx);
return NULL;
for (size_t i = 0; i < a_tx_num; ++i) {
if (dap_chain_datum_tx_add_out_item(&l_tx, a_addr_to[i], a_value[i]) == 1) {
SUM_256_256(l_value_pack, a_value[i], &l_value_pack);
} else {
dap_chain_datum_tx_delete(l_tx);
return NULL;
}
}
// Network fee
if (l_net_fee_used) {
......@@ -230,13 +244,15 @@ char *dap_chain_mempool_tx_create(dap_chain_t * a_chain, dap_enc_key_t *a_key_fr
}
}
} else { // add 'out_ext' items
if (dap_chain_datum_tx_add_out_ext_item(&l_tx, a_addr_to, a_value, a_token_ticker) != 1) {
dap_chain_datum_tx_delete(l_tx);
return NULL;
for (size_t i = 0; i < a_tx_num; ++i) {
if (dap_chain_datum_tx_add_out_ext_item(&l_tx, a_addr_to[i], a_value[i], a_token_ticker) != 1) {
dap_chain_datum_tx_delete(l_tx);
return NULL;
}
}
// coin back
uint256_t l_value_back;
SUBTRACT_256_256(l_value_transfer, a_value, &l_value_back);
SUBTRACT_256_256(l_value_transfer, l_value_total, &l_value_back);
if(!IS_ZERO_256(l_value_back)) {
if(dap_chain_datum_tx_add_out_ext_item(&l_tx, a_addr_from, l_value_back, a_token_ticker) != 1) {
dap_chain_datum_tx_delete(l_tx);
......
......@@ -64,9 +64,9 @@ void dap_chain_mempool_filter(dap_chain_t *a_chain, int *a_removed);
char *dap_chain_mempool_datum_add(const dap_chain_datum_t *a_datum, dap_chain_t *a_chain, const char *a_hash_out_type);
char *dap_chain_mempool_tx_create(dap_chain_t *a_chain, dap_enc_key_t *a_key_from,
const dap_chain_addr_t *a_addr_from, const dap_chain_addr_t *a_addr_to,
const dap_chain_addr_t *a_addr_from, const dap_chain_addr_t **a_addr_to,
const char a_token_ticker[DAP_CHAIN_TICKER_SIZE_MAX],
uint256_t a_value, uint256_t a_value_fee, const char *a_hash_out_type);
uint256_t* a_value, uint256_t a_value_fee, const char *a_hash_out_type, size_t a_tx_num);
// Make transfer transaction & insert to cache
char* dap_chain_mempool_tx_create_cond(dap_chain_net_t * a_net,
......
......@@ -58,6 +58,7 @@
#include "dap_notify_srv.h"
#include "dap_chain_net_srv_stake_pos_delegate.h"
#include "dap_chain_wallet.h"
#include "dap_chain_net_tx.h"
#define LOG_TAG "dap_ledger"
......@@ -407,11 +408,13 @@ static bool s_tag_check_transfer(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a
}
//not voting or vote...
if (a_items_grp->items_vote || a_items_grp->items_voting || a_items_grp->items_tsd)
if (a_items_grp->items_vote || a_items_grp->items_voting || dap_list_length(a_items_grp->items_tsd) > 1 || (a_items_grp->items_tsd && !dap_chain_datum_tx_item_get_tsd_by_type(a_tx, DAP_CHAIN_DATUM_TRANSFER_TSD_TYPE_OUT_COUNT)))
return false;
//not tsd sects (staking!)
if(a_action) *a_action = DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REGULAR;
//not tsd sects (staking!) or only batching tsd
if(a_action) {
*a_action = DAP_CHAIN_TX_TAG_ACTION_TRANSFER_REGULAR;
}
return true;
}
......@@ -3957,8 +3960,7 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger,
return l_err_num;
}
// 6. Compare sum of values in 'out' items in the current transaction and in the previous transactions
// Calculate the sum of values in 'out' items from the current transaction
// 6. Compare sum of values in 'out' items in the current transaction and in the previous transa // Calculate the sum of values in 'out' items from the current transaction
bool l_multichannel = false;
if (HASH_COUNT(l_values_from_prev_tx) > 1) {
l_multichannel = true;
......@@ -3992,6 +3994,7 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger,
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
bool l_cross_network = false;
uint256_t l_value = {}, l_fee_sum = {}, l_tax_sum = {};
bool l_fee_check = !IS_ZERO_256(a_ledger->net->pub.fee_value) && !dap_chain_addr_is_blank(&a_ledger->net->pub.fee_addr);
int l_item_idx = 0;
......@@ -4059,6 +4062,17 @@ static int s_tx_cache_check(dap_ledger_t *a_ledger,
default:
continue;
}
if (!dap_chain_addr_is_blank(&l_tx_out_to)) {
if (l_tx_out_to.net_id.uint64 != a_ledger->net->pub.id.uint64) {
if (!l_cross_network) {
l_cross_network = true;
} else {
log_it(L_WARNING, "The transaction was rejected because it contains multiple outputs to other network.");
l_err_num = DAP_LEDGER_TX_CHECK_MULTIPLE_OUTS_TO_OTHER_NET;
break;
}
}
}
if (l_err_num)
break;
......
......@@ -65,14 +65,20 @@ int dap_chain_node_cli_init(dap_config_t * g_config)
return log_it(L_ERROR, "Can't init CLI server!"), -1;
dap_cli_server_cmd_add("global_db", com_global_db, "Work with global database",
"global_db cells add -cell <cell_id> \n"
"global_db flush \n\n"
"global_db flush\n"
"\tFlushes the current state of the database to disk.\n\n"
"global_db write -group <group_name> -key <key_name> -value <value>\n"
"\tWrites a key value to a specified group in the database.\n\n"
"global_db read -group <group_name> -key <key_name>\n"
"\tReads a value by key from a specified group.\n\n"
"global_db delete -group <group_name> -key <key_name>\n"
"\tRemoves a value by key from a specified group.\n\n"
"global_db group_list\n"
"\tGets a list of groups in the database.\n\n"
"global_db drop_table -group <group_name>\n"
"global_db get_keys -group <group_name>"
"\tPerforms deletion of the entire group in the database.\n\n"
"global_db get_keys -group <group_name>\n"
"\tGets all record keys from a specified group.\n"
// "global_db wallet_info set -addr <wallet address> -cell <cell id> \n\n"
);
......@@ -91,8 +97,8 @@ int dap_chain_node_cli_init(dap_config_t * g_config)
"node balancer -net <net_name>\n"
"node dump [-net <net_name> | -addr <node_address>]\n\n"
"node list -net <net_name> [-addr <node_address> | -alias <node_alias>] [-full]\n\n"
"node ban -net <net_name> -chain <chain_name> -certs <certs_name> [-addr <node_address> | -ip <ip_v4_or_v6_address>]\n"
"node unban -net <net_name> -chain <chain_name> -certs <certs_name> [-addr <node_address> | -ip <ip_v4_or_v6_address>]\n"
"node ban -net <net_name> -certs <certs_name> [-addr <node_address> | -host <ip_v4_or_v6_address>]\n"
"node unban -net <net_name> -certs <certs_name> [-addr <node_address> | -host <ip_v4_or_v6_address>]\n"
"node banlist\n\n");
dap_cli_server_cmd_add ("version", com_version, "Return software version",
......@@ -153,7 +159,7 @@ int dap_chain_node_cli_init(dap_config_t * g_config)
"wallet info {-addr <addr> | -w <wallet_name>} -net <net_name>\n"
"wallet activate -w <wallet_name> -password <password> [-ttl <password_ttl_in_minutes>]\n"
"wallet deactivate -w <wallet_name>>\n"
"wallet convert -w <wallet_name> -password <password>\n");
"wallet convert -w <wallet_name> {-password <password> | -remove_password }\n");
// Token commands
......
......@@ -399,15 +399,13 @@ int com_global_db(int a_argc, char ** a_argv, void **a_str_reply)
{
json_object **a_json_arr_reply = (json_object **)a_str_reply;
enum {
CMD_NONE, CMD_NAME_CELL, CMD_ADD, CMD_FLUSH, CMD_RECORD, CMD_WRITE, CMD_READ,
CMD_NONE, CMD_ADD, CMD_FLUSH, CMD_RECORD, CMD_WRITE, CMD_READ,
CMD_DELETE, CMD_DROP, CMD_GET_KEYS, CMD_GROUP_LIST
};
int arg_index = 1;
int cmd_name = CMD_NONE;
// find 'cells' as first parameter only
if(dap_cli_server_cmd_find_option_val(a_argv, arg_index, dap_min(a_argc, arg_index + 1), "cells", NULL))
cmd_name = CMD_NAME_CELL;
else if(dap_cli_server_cmd_find_option_val(a_argv, arg_index, dap_min(a_argc, arg_index + 1), "flush", NULL))
if(dap_cli_server_cmd_find_option_val(a_argv, arg_index, dap_min(a_argc, arg_index + 1), "flush", NULL))
cmd_name = CMD_FLUSH;
else if(dap_cli_server_cmd_find_option_val(a_argv, arg_index, dap_min(a_argc, arg_index + 1), "record", NULL))
cmd_name = CMD_RECORD;
......@@ -425,66 +423,6 @@ int com_global_db(int a_argc, char ** a_argv, void **a_str_reply)
cmd_name = CMD_GROUP_LIST;
switch (cmd_name) {
case CMD_NAME_CELL:
{
if(!arg_index || a_argc < 3) {
dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_PARAM_ERR, "parameters are not valid");
return -DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_PARAM_ERR;
}
dap_chain_t * l_chain = NULL;
dap_chain_net_t * l_net = NULL;
if (dap_chain_node_cli_cmd_values_parse_net_chain_for_json(*a_json_arr_reply, &arg_index, a_argc, a_argv, &l_chain, &l_net, CHAIN_TYPE_INVALID) < 0)
return -DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_PARAM_ERR;
const char *l_cell_str = NULL, *l_chain_str = NULL;
// find cell and chain
dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-cell", &l_cell_str);
int arg_index_n = ++arg_index;
// find command (add, delete, etc) as second parameter only
int cmd_num = CMD_NONE;
switch (cmd_name) {
case CMD_NAME_CELL:
if((arg_index_n = dap_cli_server_cmd_find_option_val(a_argv, arg_index, dap_min(a_argc, arg_index + 1), "add", NULL))
!= 0) {
cmd_num = CMD_ADD;
}
dap_chain_cell_id_t l_cell_id = { {0} };
if(l_cell_str) {
dap_digit_from_string(l_cell_str, (uint8_t*) &l_cell_id.raw, sizeof(l_cell_id.raw)); //DAP_CHAIN_CELL_ID_SIZE);
}
switch (cmd_num)
{
// add new node to global_db
case CMD_ADD:
if(!arg_index || a_argc < 7) {
dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_PARAM_ERR, "invalid parameters");
return -DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_PARAM_ERR;
}
dap_chain_cell_t *l_cell = dap_chain_cell_create_fill(l_chain, l_cell_id);
int l_ret = (int)dap_chain_cell_file_update(l_cell);
if ( l_ret > 0 )
{
json_object* json_obj_name = json_object_new_object();
json_object_object_add(json_obj_name, "comand status", json_object_new_string("cell added successfully"));
json_object_array_add(*a_json_arr_reply, json_obj_name);
}
else
dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_CAN_CREATE_CELL_ERR, "can't create file for cell 0x%016"DAP_UINT64_FORMAT_X" ( %s )",
l_cell->id.uint64,l_cell->file_storage_path);
dap_chain_cell_close(l_cell);
return l_ret;
//case CMD_NONE:
default:
dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_COMMAND_ERR, "command %s not recognized", a_argv[1]);
return -DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_COMMAND_ERR;
}
}
}
case CMD_FLUSH:
{
json_object* json_obj_flush = NULL;
......@@ -696,13 +634,15 @@ int com_global_db(int a_argc, char ** a_argv, void **a_str_reply)
dap_nanotime_to_str_rfc822(l_ts_str, sizeof(l_ts_str), l_ts);
char *l_value_hexdump = dap_dump_hex(l_value_out, l_out_len);
if (l_value_hexdump) {
char *l_value_hexdump_new = dap_strdup_printf("\n%s", l_value_hexdump);
json_object* json_obj_read = json_object_new_object();
json_object_object_add(json_obj_read, "group", json_object_new_string(l_group_str));
json_object_object_add(json_obj_read, "key", json_object_new_string(l_key_str));
json_object_object_add(json_obj_read, "time", json_object_new_string(l_ts_str));
json_object_object_add(json_obj_read, "value len", json_object_new_uint64(l_out_len));
json_object_object_add(json_obj_read, "value hex", json_object_new_string(l_value_hexdump));
json_object_object_add(json_obj_read, "value hex", json_object_new_string(l_value_hexdump_new));
json_object_array_add(*a_json_arr_reply, json_obj_read);
DAP_DELETE(l_value_hexdump_new);
DAP_DELETE(l_value_hexdump);
} else {
dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_TIME_NO_VALUE,
......@@ -861,10 +801,9 @@ 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)) {
dap_chain_addr_t *l_format = dap_chain_addr_from_str(l_ban_addr_str);
if (!l_format)
dap_stream_node_addr_t l_addr = {0};
if (dap_stream_node_addr_from_str(&l_addr, l_ban_addr_str))
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);
......@@ -1337,11 +1276,11 @@ int com_node(int a_argc, char ** a_argv, void **a_str_reply)
} break;
case CMD_BAN: {
dap_chain_net_t *l_netl = NULL;
dap_chain_t *l_chain = NULL;
if(dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, a_argc, a_argv, a_str_reply, &l_chain, &l_netl,
CHAIN_TYPE_DECREE) < 0)
dap_chain_t *l_chain = dap_chain_net_get_default_chain_by_chain_type(l_net, CHAIN_TYPE_DECREE);
if(!l_chain) {
dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s does not support decrees.", l_net->pub.name);
return -11;
}
const char * l_hash_out_type = NULL;
dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-H", &l_hash_out_type);
if(!l_hash_out_type)
......@@ -1375,7 +1314,7 @@ int com_node(int a_argc, char ** a_argv, void **a_str_reply)
l_decree->header.type = DAP_CHAIN_DATUM_DECREE_TYPE_COMMON;
l_decree->header.common_decree_params.net_id = l_net->pub.id;
l_decree->header.common_decree_params.chain_id = l_chain->id;
l_decree->header.common_decree_params.cell_id = *dap_chain_net_get_cur_cell(l_netl);
l_decree->header.common_decree_params.cell_id = *dap_chain_net_get_cur_cell(l_net);
l_decree->header.sub_type = DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_BAN;
l_decree->header.data_size = dap_tsd_size(l_addr_tsd);
l_decree->header.signs_size = 0;
......@@ -1400,11 +1339,11 @@ int com_node(int a_argc, char ** a_argv, void **a_str_reply)
} break;
case CMD_UNBAN: {
dap_chain_net_t *l_netl = NULL;
dap_chain_t *l_chain = NULL;
if(dap_chain_node_cli_cmd_values_parse_net_chain(&arg_index, a_argc, a_argv, a_str_reply, &l_chain, &l_net,
CHAIN_TYPE_DECREE) < 0)
dap_chain_t *l_chain = dap_chain_net_get_default_chain_by_chain_type(l_net, CHAIN_TYPE_DECREE);
if(!l_chain) {
dap_cli_server_cmd_set_reply_text(a_str_reply, "Network %s does not support decrees.", l_net->pub.name);
return -11;
}
const char * l_hash_out_type = NULL;
dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-H", &l_hash_out_type);
if(!l_hash_out_type)
......@@ -1438,7 +1377,7 @@ int com_node(int a_argc, char ** a_argv, void **a_str_reply)
l_decree->header.type = DAP_CHAIN_DATUM_DECREE_TYPE_COMMON;
l_decree->header.common_decree_params.net_id = l_net->pub.id;
l_decree->header.common_decree_params.chain_id = l_chain->id;
l_decree->header.common_decree_params.cell_id = *dap_chain_net_get_cur_cell(l_netl);
l_decree->header.common_decree_params.cell_id = *dap_chain_net_get_cur_cell(l_net);
l_decree->header.sub_type = DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_UNBAN;
l_decree->header.data_size = dap_tsd_size(l_addr_tsd);
l_decree->header.signs_size = 0;
......@@ -1792,7 +1731,7 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE;
json_object_put(json_arr_out);
return DAP_CHAIN_NODE_CLI_COM_TX_WALLET_NAME_ERR;
}
if( cmd_num != CMD_WALLET_DEACTIVATE && !l_pass_str && cmd_num != CMD_WALLET_NEW) {
if( cmd_num != CMD_WALLET_DEACTIVATE && !l_pass_str && cmd_num != CMD_WALLET_NEW && cmd_num != CMD_WALLET_CONVERT) {
dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_WALLET_PASS_ERR,
"Wallet password option <-password> not defined");
json_object_put(json_arr_out);
......@@ -1847,18 +1786,28 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE;
} break;
// convert wallet
case CMD_WALLET_CONVERT: {
bool l_remove_password = false;
if(dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-remove_password", NULL))
l_remove_password = true;
l_wallet = dap_chain_wallet_open(l_wallet_name, c_wallets_path, NULL);
if (!l_wallet) {
dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_WALLET_PASS_ERR,
"wrong password");
"Can't open wallet check activation");
json_object_put(json_arr_out);
return DAP_CHAIN_NODE_CLI_COM_TX_WALLET_PASS_ERR;
} else if (l_wallet->flags & DAP_WALLET$M_FL_ACTIVE) {
} else if (l_wallet->flags & DAP_WALLET$M_FL_ACTIVE && !l_remove_password) {
dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_WALLET_CONVERT_ERR,
"Wallet can't be converted twice");
"Wallet can't be converted twice");
json_object_put(json_arr_out);
return DAP_CHAIN_NODE_CLI_COM_TX_WALLET_CONVERT_ERR;
}
if (l_pass_str && !dap_check_valid_password(l_pass_str, dap_strlen(l_pass_str))) {
dap_json_rpc_error_add(*a_json_arr_reply,
DAP_CHAIN_NODE_CLI_COM_TX_WALLET_INVALID_CHARACTERS_USED_FOR_PASSWORD,
"Invalid characters used for password.");
return DAP_CHAIN_NODE_CLI_COM_TX_WALLET_INVALID_CHARACTERS_USED_FOR_PASSWORD;
}
// create wallet backup
dap_chain_wallet_internal_t* l_file_name = DAP_CHAIN_WALLET_INTERNAL(l_wallet);
snprintf(l_file_name->file_name, sizeof(l_file_name->file_name), "%s/%s_%012lu%s", c_wallets_path, l_wallet_name, time(NULL),".backup");
......@@ -1868,9 +1817,22 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE;
json_object_put(json_arr_out);
return DAP_CHAIN_NODE_CLI_COM_TX_WALLET_BACKUP_ERR;
}
if (l_remove_password) {
if (dap_chain_wallet_deactivate(l_wallet_name, strlen(l_wallet_name))){
dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_WALLET_BACKUP_ERR,
"Can't deactivate wallet");
json_object_put(json_arr_out);
return DAP_CHAIN_NODE_CLI_COM_TX_WALLET_DEACT_ERR;
}
} else if (!l_pass_str) {
dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_WALLET_PASS_ERR,
"Wallet password option <-password> not defined");
json_object_put(json_arr_out);
return DAP_CHAIN_NODE_CLI_COM_TX_WALLET_PASS_ERR;
}
// change to old filename
snprintf(l_file_name->file_name, sizeof(l_file_name->file_name), "%s/%s%s", c_wallets_path, l_wallet_name, ".dwallet");
if ( dap_chain_wallet_save(l_wallet, l_pass_str) ) {
if ( dap_chain_wallet_save(l_wallet, l_remove_password ? NULL : l_pass_str) ) {
dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_WALLET_CONVERT_ERR,
"Wallet is not converted because of internal error");
json_object_put(json_arr_out);
......@@ -1990,6 +1952,13 @@ int l_arg_index = 1, l_rc, cmd_num = CMD_NONE;
return DAP_CHAIN_NODE_CLI_COM_TX_WALLET_HASH_ERR;
}
}
// Checking that if a password is set, it contains only Latin characters, numbers and special characters, except for spaces.
if (l_pass_str && !dap_check_valid_password(l_pass_str, dap_strlen(l_pass_str))) {
dap_json_rpc_error_add(*a_json_arr_reply,
DAP_CHAIN_NODE_CLI_COM_TX_WALLET_INVALID_CHARACTERS_USED_FOR_PASSWORD,
"Invalid characters used for password.");
return DAP_CHAIN_NODE_CLI_COM_TX_WALLET_INVALID_CHARACTERS_USED_FOR_PASSWORD;
}
// Creates new wallet
l_wallet = dap_chain_wallet_create_with_seed_multi(l_wallet_name, c_wallets_path, l_sign_types, l_sign_count,
......@@ -2605,6 +2574,7 @@ void s_com_mempool_list_print_for_chain(json_object* a_json_arr_reply, dap_chain
json_object_object_add(l_jobj_datum, "service", json_object_new_string("UNKNOWN"));
json_object_object_add(l_jobj_datum, "action", json_object_new_string("UNKNOWN"));
}
json_object_object_add(l_jobj_datum, "batching", json_object_new_string(!dap_chain_datum_tx_item_get_tsd_by_type(l_tx, DAP_CHAIN_DATUM_TRANSFER_TSD_TYPE_OUT_COUNT) ? "false" : "true"));
dap_list_t *l_list_in_ems = dap_chain_datum_tx_items_get(l_tx, TX_ITEM_TYPE_IN_EMS, NULL);
dap_chain_tx_sig_t *l_sig = (dap_chain_tx_sig_t*)dap_chain_datum_tx_item_get(l_tx, NULL, NULL, TX_ITEM_TYPE_SIG, NULL);
......@@ -6660,12 +6630,40 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_json_arr_reply)
dap_chain_wallet_t *l_wallet = s_json_get_wallet(l_json_item_obj, "wallet");
const dap_cert_t *l_cert = s_json_get_cert(l_json_item_obj, "cert");
const char *l_sign_type_str = s_json_get_text(l_json_item_obj, "sig_type");
int64_t l_pkey_size;
int64_t l_sig_size;
uint8_t *l_pkey = NULL;
dap_sign_t *l_sign = NULL;
dap_enc_key_type_t l_type = dap_enc_key_type_find_by_name(l_sign_type_str);
dap_enc_key_t * l_ret = dap_enc_key_new(l_type);
//wallet goes first
if (l_wallet) {
l_enc_key = dap_chain_wallet_get_key(l_wallet, 0);
} else if (l_cert && l_cert->enc_key) {
l_enc_key = l_cert->enc_key;
} else if (l_sign_type_str) {
s_json_get_int64(l_json_item_obj, "pub_key_size", &l_pkey_size);
s_json_get_int64(l_json_item_obj, "sig_size", &l_sig_size);
json_object *l_jobj_sign = json_object_object_get(l_json_item_obj, "sig_b64");
const char *l_sign_str = json_object_get_string(l_jobj_sign);
dap_sign_t *l_sign = DAP_NEW_Z_SIZE(dap_sign_t, DAP_ENC_BASE64_DECODE_SIZE(dap_strlen(l_sign_str)));
size_t l_sign_decree_size = dap_enc_base64_decode(l_sign_str, dap_strlen(l_sign_str), l_sign, DAP_ENC_DATA_TYPE_B64);
json_object *l_jobj_pub_key = json_object_object_get(l_json_item_obj, "pub_key_b64");
const char *l_pub_key_str = json_object_get_string(l_jobj_pub_key);
size_t l_proc_buf_size = 0;
void *l_proc_buf = DAP_NEW_SIZE(void,DAP_ENC_BASE64_DECODE_SIZE(l_pkey_size));
l_proc_buf_size = dap_enc_base64_decode(l_pub_key_str, l_pkey_size, l_proc_buf, DAP_ENC_DATA_TYPE_B64);
if (dap_enc_key_deserialize_pub_key(l_ret, l_proc_buf, l_pkey_size)) {
log_it(L_ERROR, "Error in enc pub key deserialize");
DAP_DEL_Z(l_ret);
}
}
else{
json_object *l_jobj_err = json_object_new_string("Can't create sign for transactions.");
......@@ -6675,6 +6673,18 @@ int com_tx_create_json(int a_argc, char ** a_argv, void **a_json_arr_reply)
continue;
}
if (l_sign) {
size_t l_chain_sign_size = dap_sign_get_size(l_sign); // sign data
dap_chain_tx_sig_t *l_tx_sig = DAP_NEW_Z_SIZE(dap_chain_tx_sig_t,
sizeof(dap_chain_tx_sig_t) + l_chain_sign_size);
l_tx_sig->header.type = TX_ITEM_TYPE_SIG;
l_tx_sig->header.sig_size =(uint32_t) l_chain_sign_size;
memcpy(l_tx_sig->sig, l_sign, l_chain_sign_size);
dap_chain_datum_tx_add_item(&l_tx, l_tx_sig);
DAP_DELETE(l_sign);
}
if(l_enc_key && dap_chain_datum_tx_add_sign_item(&l_tx, l_enc_key) > 0) {
l_items_ready++;
} else {
......@@ -6786,9 +6796,11 @@ int com_tx_create(int a_argc, char **a_argv, void **a_json_arr_reply)
return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_NET_NOT_FOUND;
}
uint256_t l_value = {};
uint256_t *l_value = NULL;
uint256_t l_value_fee = {};
dap_chain_addr_t *l_addr_to = NULL;
dap_chain_addr_t **l_addr_to = NULL;
size_t l_addr_el_count = 0;
size_t l_value_el_count = 0;
dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-from_wallet", &l_from_wallet_name);
dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-wallet_fee", &l_wallet_fee_name);
dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-from_emission", &l_emission_hash_str);
......@@ -6820,6 +6832,20 @@ int com_tx_create(int a_argc, char **a_argv, void **a_json_arr_reply)
const char *c_wallets_path = dap_chain_wallet_get_path(g_config);
dap_chain_t *l_chain = NULL;
if (l_chain_name) {
l_chain = dap_chain_net_get_chain_by_name(l_net, l_chain_name);
} else {
l_chain = dap_chain_net_get_default_chain_by_chain_type(l_net,CHAIN_TYPE_TX);
}
if(!l_chain) {
dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_NOT_FOUND_CHAIN,
"not found chain name '%s', try use parameter '-chain' or set default datum type in chain configuration file",
l_chain_name);
return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_NOT_FOUND_CHAIN;
}
dap_chain_t *l_emission_chain = NULL;
if (l_emission_hash_str) {
if (dap_chain_hash_fast_from_str(l_emission_hash_str, &l_emission_hash)) {
......@@ -6872,35 +6898,67 @@ int com_tx_create(int a_argc, char **a_argv, void **a_json_arr_reply)
return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_TOKEN_NOT_DECLARATED_IN_NET;
}
dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-to_addr", &addr_base58_to);
dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-value", &str_tmp);
if (!addr_base58_to) {
dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_TO_ADDR, "tx_create requires parameter '-to_addr'");
return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_TO_ADDR;
}
l_addr_to = dap_chain_addr_from_str(addr_base58_to);
if(!l_addr_to) {
dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_DESTINATION_ADDRESS_INVALID, "destination address is invalid");
return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_DESTINATION_ADDRESS_INVALID;
}
if (dap_cli_server_cmd_find_option_val(a_argv, arg_index, a_argc, "-value", &str_tmp))
l_value = dap_chain_balance_scan(str_tmp);
if (IS_ZERO_256(l_value)) {
if (!str_tmp) {
dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_VALUE_OR_INVALID_FORMAT_VALUE, "tx_create requires parameter '-value' to be valid uint256 value");
return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_VALUE_OR_INVALID_FORMAT_VALUE;
}
}
l_addr_el_count = dap_str_symbol_count(addr_base58_to, ',') + 1;
l_value_el_count = dap_str_symbol_count(str_tmp, ',') + 1;
dap_chain_t *l_chain = NULL;
if (l_chain_name) {
l_chain = dap_chain_net_get_chain_by_name(l_net, l_chain_name);
} else {
l_chain = dap_chain_net_get_default_chain_by_chain_type(l_net,CHAIN_TYPE_TX);
}
if (l_addr_el_count != l_value_el_count) {
dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_VALUE_OR_INVALID_FORMAT_VALUE, "num of '-to_addr' and '-value' should be equal");
return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_VALUE_OR_INVALID_FORMAT_VALUE;
}
if(!l_chain) {
dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_NOT_FOUND_CHAIN,
"not found chain name '%s', try use parameter '-chain' or set default datum type in chain configuration file",
l_chain_name);
return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_NOT_FOUND_CHAIN;
l_value = DAP_NEW_Z_COUNT(uint256_t, l_value_el_count);
if (!l_value) {
dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_MEMORY_ERR, c_error_memory_alloc);
return DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_MEMORY_ERR;
}
char **l_value_array = dap_strsplit(str_tmp, ",", l_value_el_count);
if (!l_value_array) {
DAP_DELETE(l_value);
dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_PARAM_ERR, "Can't read '-to_addr' arg");
return DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_PARAM_ERR;
}
for (size_t i = 0; i < l_value_el_count; ++i) {
l_value[i] = dap_chain_balance_scan(l_value_array[i]);
if(IS_ZERO_256(l_value[i])) {
DAP_DEL_MULTY(l_value_array, l_value);
dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_VALUE_OR_INVALID_FORMAT_VALUE, "tx_create requires parameter '-value' to be valid uint256 value");
return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_REQUIRE_PARAMETER_VALUE_OR_INVALID_FORMAT_VALUE;
}
}
DAP_DELETE(l_value_array);
l_addr_to = DAP_NEW_Z_COUNT(dap_chain_addr_t *, l_addr_el_count);
if (!l_addr_to) {
log_it(L_CRITICAL, "%s", c_error_memory_alloc);
DAP_DELETE(l_value);
dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_MEMORY_ERR, c_error_memory_alloc);
return DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_MEMORY_ERR;
}
char **l_addr_base58_to_array = dap_strsplit(addr_base58_to, ",", l_addr_el_count);
if (!l_addr_base58_to_array) {
DAP_DEL_MULTY(l_addr_to, l_value);
dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_PARAM_ERR, "Can't read '-to_addr' arg");
return DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_PARAM_ERR;
}
for (size_t i = 0; i < l_addr_el_count; ++i) {
l_addr_to[i] = dap_chain_addr_from_str(l_addr_base58_to_array[i]);
if(!l_addr_to[i]) {
DAP_DEL_ARRAY(l_addr_to, i);
DAP_DEL_MULTY(l_addr_to, l_addr_base58_to_array, l_value);
dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_DESTINATION_ADDRESS_INVALID, "destination address is invalid");
return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_DESTINATION_ADDRESS_INVALID;
}
}
DAP_DELETE(l_addr_base58_to_array);
}
int l_ret = DAP_CHAIN_NODE_CLI_COM_TX_CREATE_OK;
......@@ -6931,7 +6989,8 @@ int com_tx_create(int a_argc, char **a_argv, void **a_json_arr_reply)
l_ret = DAP_CHAIN_NODE_CLI_COM_TX_CREATE_CAN_NOT_ADD_DATUM_IN_MEMPOOL;
}
json_object_array_add(*a_json_arr_reply, l_jobj_emission);
DAP_DELETE(l_addr_to);
DAP_DEL_ARRAY(l_addr_to, l_addr_el_count);
DAP_DEL_MULTY(l_addr_to, l_value);
if (l_wallet_fee) {
dap_chain_wallet_close(l_wallet_fee);
dap_enc_key_delete(l_priv_key);
......@@ -6945,6 +7004,8 @@ int com_tx_create(int a_argc, char **a_argv, void **a_json_arr_reply)
if(!l_wallet) {
dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_WALLET_DOES_NOT_EXIST,
"wallet %s does not exist", l_from_wallet_name);
DAP_DEL_ARRAY(l_addr_to, l_addr_el_count);
DAP_DEL_MULTY(l_addr_to, l_value);
return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_WALLET_DOES_NOT_EXIST;
} else {
const char *l_wallet_check_str = dap_chain_wallet_check_sign(l_wallet);
......@@ -6953,48 +7014,56 @@ int com_tx_create(int a_argc, char **a_argv, void **a_json_arr_reply)
json_object_object_add(l_jobj_result, "warning", l_obj_wgn_str);
}
}
const dap_chain_addr_t *addr_from = (const dap_chain_addr_t *) dap_chain_wallet_get_addr(l_wallet, l_net->pub.id);
const dap_chain_addr_t *l_addr_from = (const dap_chain_addr_t *) dap_chain_wallet_get_addr(l_wallet, l_net->pub.id);
if(!addr_from) {
DAP_DELETE(l_addr_to);
if(!l_addr_from) {
dap_chain_wallet_close(l_wallet);
dap_enc_key_delete(l_priv_key);
dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_SOURCE_ADDRESS_INVALID, "source address is invalid");
json_object_put(l_jobj_result);
DAP_DEL_ARRAY(l_addr_to, l_addr_el_count);
DAP_DEL_MULTY(l_addr_to, l_value);
return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_SOURCE_ADDRESS_INVALID;
}
if (addr_from && dap_chain_addr_compare(l_addr_to, addr_from)) {
DAP_DELETE(l_addr_to);
dap_chain_wallet_close(l_wallet);
dap_enc_key_delete(l_priv_key);
dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_EQ_SOURCE_DESTINATION_ADDRESS, "The transaction cannot be directed to the same address as the source.");
json_object_put(l_jobj_result);
return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_EQ_SOURCE_DESTINATION_ADDRESS;
for (size_t i = 0; i < l_addr_el_count; ++i) {
if (dap_chain_addr_compare(l_addr_to[i], l_addr_from)) {
dap_chain_wallet_close(l_wallet);
dap_enc_key_delete(l_priv_key);
dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_EQ_SOURCE_DESTINATION_ADDRESS, "The transaction cannot be directed to the same address as the source.");
json_object_put(l_jobj_result);
DAP_DEL_ARRAY(l_addr_to, l_addr_el_count);
DAP_DEL_MULTY(l_addr_to, l_value);
return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_EQ_SOURCE_DESTINATION_ADDRESS;
}
}
if (l_addr_to->net_id.uint64 != l_net->pub.id.uint64 && !dap_chain_addr_is_blank(l_addr_to)) {
bool l_found = false;
int i;
for (i = 0; i < l_net->pub.bridged_networks_count; ++i) {
if (l_net->pub.bridged_networks[i].uint64 == l_addr_to->net_id.uint64) {
l_found = true;
break;
for (size_t i = 0; i < l_addr_el_count; ++i) {
if (!dap_chain_addr_is_blank(l_addr_to[i]) && l_addr_to[i]->net_id.uint64 != l_net->pub.id.uint64) {
bool l_found = false;
for (size_t j = 0; j < l_net->pub.bridged_networks_count; ++j) {
if (l_net->pub.bridged_networks[j].uint64 == l_addr_to[i]->net_id.uint64) {
l_found = true;
break;
}
}
if (!l_found) {
dap_string_t *l_allowed_list = dap_string_new("");
dap_string_append_printf(l_allowed_list, "0x%016"DAP_UINT64_FORMAT_X, l_net->pub.id.uint64);
for (size_t j = 0; j < l_net->pub.bridged_networks_count; ++j)
dap_string_append_printf(l_allowed_list, ", 0x%016"DAP_UINT64_FORMAT_X, l_net->pub.bridged_networks[j].uint64);
dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_DESTINATION_NETWORK_IS_UNREACHEBLE,
"Destination network ID=0x%"DAP_UINT64_FORMAT_x
" is unreachable. List of available network IDs:\n%s"
" Please, change network name or wallet address",
l_addr_to[i]->net_id.uint64, l_allowed_list->str);
dap_string_free(l_allowed_list, true);
json_object_put(l_jobj_result);
DAP_DEL_ARRAY(l_addr_to, l_addr_el_count);
DAP_DEL_MULTY(l_addr_to, l_value);
return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_DESTINATION_NETWORK_IS_UNREACHEBLE;
}
}
if (!l_found) {
dap_string_t *l_allowed_list = dap_string_new("");
dap_string_append_printf(l_allowed_list, "0x%016"DAP_UINT64_FORMAT_X, l_net->pub.id.uint64);
for (i = 0; i < l_net->pub.bridged_networks_count; ++i)
dap_string_append_printf(l_allowed_list, ", 0x%016"DAP_UINT64_FORMAT_X, l_net->pub.bridged_networks[i].uint64);
dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_COM_TX_CREATE_DESTINATION_NETWORK_IS_UNREACHEBLE,
"Destination network ID=0x%"DAP_UINT64_FORMAT_x
" is unreachable. List of available network IDs:\n%s"
" Please, change network name or wallet address",
l_addr_to->net_id.uint64, l_allowed_list->str);
dap_string_free(l_allowed_list, true);
json_object_put(l_jobj_result);
return DAP_CHAIN_NODE_CLI_COM_TX_CREATE_DESTINATION_NETWORK_IS_UNREACHEBLE;
}
}
......@@ -7003,13 +7072,13 @@ int com_tx_create(int a_argc, char **a_argv, void **a_json_arr_reply)
l_priv_key = dap_chain_wallet_get_key(l_wallet, 0);
if(l_tx_num){
l_ret = dap_chain_mempool_tx_create_massive(l_chain, l_priv_key, addr_from,
l_addr_to, l_token_ticker, l_value, l_value_fee, l_tx_num);
l_ret = dap_chain_mempool_tx_create_massive(l_chain, l_priv_key, l_addr_from,
l_addr_to[0], l_token_ticker, l_value[0], l_value_fee, l_tx_num);
l_jobj_transfer_status = json_object_new_string((l_ret == 0) ? "Ok" : (l_ret == -2) ? "False, not enough funds for transfer" : "False");
json_object_object_add(l_jobj_result, "transfer", l_jobj_transfer_status);
} else {
char *l_tx_hash_str = dap_chain_mempool_tx_create(l_chain, l_priv_key, addr_from, l_addr_to,
l_token_ticker, l_value, l_value_fee, l_hash_out_type);
char *l_tx_hash_str = dap_chain_mempool_tx_create(l_chain, l_priv_key, l_addr_from, (const dap_chain_addr_t **)l_addr_to,
l_token_ticker, l_value, l_value_fee, l_hash_out_type, l_addr_el_count);
if (l_tx_hash_str) {
l_jobj_transfer_status = json_object_new_string("Ok");
l_jobj_tx_hash = json_object_new_string(l_tx_hash_str);
......@@ -7024,7 +7093,8 @@ int com_tx_create(int a_argc, char **a_argv, void **a_json_arr_reply)
}
json_object_array_add(*a_json_arr_reply, l_jobj_result);
DAP_DELETE(l_addr_to);
DAP_DEL_ARRAY(l_addr_to, l_addr_el_count);
DAP_DEL_MULTY(l_addr_to, l_value);
dap_chain_wallet_close(l_wallet);
dap_enc_key_delete(l_priv_key);
return l_ret;
......
This diff is collapsed.
......@@ -101,7 +101,8 @@ typedef enum dap_ledger_check_error {
DAP_LEDGER_TOKEN_ADD_CHECK_TSD_ADDR_MISMATCH,
DAP_LEDGER_TOKEN_ADD_CHECK_TSD_PKEY_MISMATCH,
DAP_LEDGER_TOKEN_ADD_CHECK_TSD_FORBIDDEN,
DAP_LEDGER_TOKEN_ADD_CHECK_TSD_OTHER_TICKER_EXPECTED
DAP_LEDGER_TOKEN_ADD_CHECK_TSD_OTHER_TICKER_EXPECTED,
DAP_LEDGER_TX_CHECK_MULTIPLE_OUTS_TO_OTHER_NET,
} dap_ledger_check_error_t;
DAP_STATIC_INLINE const char *dap_ledger_check_error_str(dap_ledger_check_error_t a_error)
......@@ -147,6 +148,7 @@ DAP_STATIC_INLINE const char *dap_ledger_check_error_str(dap_ledger_check_error_
case DAP_LEDGER_TX_CHECK_NOT_ENOUGH_FEE: return "Not enough network fee for transaction processing";
case DAP_LEDGER_TX_CHECK_NOT_ENOUGH_TAX: return "Not enough sovereign tax provided with current transaction";
case DAP_LEDGER_TX_CHECK_FOR_REMOVING_CANT_FIND_TX: return "Can't find tx in ledger for removing.";
case DAP_LEDGER_TX_CHECK_MULTIPLE_OUTS_TO_OTHER_NET: return "The transaction was rejected because it contains multiple outputs to other networks.";
/* Emisssion check return codes */
case DAP_LEDGER_EMISSION_CHECK_VALUE_EXCEEDS_CURRENT_SUPPLY: return "Value of emission execeeds current token supply";
case DAP_LEDGER_EMISSION_CHECK_LEGACY_FORBIDDEN: return "Legacy type of emissions are present for old chains comliance only";
......@@ -185,12 +187,10 @@ typedef enum dap_chain_tx_tag_action_type {
DAP_CHAIN_TX_TAG_ACTION_VOTING = 1 << 11,
DAP_CHAIN_TX_TAG_ACTION_VOTE = 1 << 12,
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;
......
......@@ -60,7 +60,6 @@ typedef enum s_com_global_db_json_err {
DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_JSON_OK = 0,
DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_PARAM_ERR,
DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_CAN_CREATE_CELL_ERR,
DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_COMMAND_ERR,
DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_CAN_NOT_OPEN_DIR,
DAP_CHAIN_NODE_CLI_COM_GLOBAL_DB_CAN_NOT_INIT_DB,
......@@ -159,12 +158,14 @@ typedef enum s_com_tx_wallet_err{
DAP_CHAIN_NODE_CLI_COM_TX_WALLET_ACTIVE_ERR,
DAP_CHAIN_NODE_CLI_COM_TX_WALLET_CONVERT_ERR,
DAP_CHAIN_NODE_CLI_COM_TX_WALLET_BACKUP_ERR,
DAP_CHAIN_NODE_CLI_COM_TX_WALLET_DEACT_ERR,
DAP_CHAIN_NODE_CLI_COM_TX_WALLET_UNKNOWN_SIGN_ERR,
DAP_CHAIN_NODE_CLI_COM_TX_WALLET_PROTECTION_ERR,
DAP_CHAIN_NODE_CLI_COM_TX_WALLET_HASH_ERR,
DAP_CHAIN_NODE_CLI_COM_TX_WALLET_CHAIN_PARAM_ERR,
DAP_CHAIN_NODE_CLI_COM_TX_WALLET_INTERNAL_ERR,
DAP_CHAIN_NODE_CLI_COM_TX_WALLET_CAN_NOT_GET_ADDR,
DAP_CHAIN_NODE_CLI_COM_TX_WALLET_INVALID_CHARACTERS_USED_FOR_PASSWORD,
/* add custom codes here */
......
......@@ -978,13 +978,13 @@ static int s_cli_voting(int a_argc, char **a_argv, void **a_str_reply)
json_object* json_vote_out = json_object_new_object();
json_object_object_add(json_vote_out, "hash of voting",
json_object_new_string(l_hash_str));
json_object_object_add(json_vote_out, "Voting dump",
json_object_object_add(json_vote_out, "question",
json_object_new_string_len((char*)((byte_t*)l_voting->voting_params.voting_tx + l_voting->voting_params.voting_question_offset),
l_voting->voting_params.voting_question_length));
if (l_voting->voting_params.voting_expire) {
char l_tmp_buf[DAP_TIME_STR_SIZE];
dap_time_to_str_rfc822(l_tmp_buf, DAP_TIME_STR_SIZE, l_voting->voting_params.voting_expire);
json_object_object_add(json_vote_out, "Voting expire",
json_object_object_add(json_vote_out, "voting expire",
json_object_new_string(l_tmp_buf));
//dap_string_truncate(l_str_out, l_str_out->len - 1);
json_object_object_add(json_vote_out, "status",
......@@ -993,9 +993,9 @@ static int s_cli_voting(int a_argc, char **a_argv, void **a_str_reply)
json_object_new_string("expired"));
}
if (l_voting->voting_params.votes_max_count){
char *l_val = dap_strdup_printf(" %"DAP_UINT64_FORMAT_U" (%s)\n", l_voting->voting_params.votes_max_count,
char *l_val = dap_strdup_printf("%"DAP_UINT64_FORMAT_U" (%s)", l_voting->voting_params.votes_max_count,
l_voting->voting_params.votes_max_count <= l_votes_count ? "closed" : "active");
json_object_object_add(json_vote_out, "Votes max count", json_object_new_string(l_val));
json_object_object_add(json_vote_out, "votes max count", json_object_new_string(l_val));
DAP_DELETE(l_val);
}
json_object_object_add(json_vote_out, "changing vote status", l_voting->voting_params.vote_changing_allowed ?
......@@ -1006,10 +1006,10 @@ static int s_cli_voting(int a_argc, char **a_argv, void **a_str_reply)
json_object_new_string("not required"));
json_object* json_arr_vote_out = json_object_new_array();
char *l_val = NULL;
for (uint64_t i = 0; i < dap_list_length(l_voting->voting_params.option_offsets_list); i++){
json_object* json_vote_obj = json_object_new_object();
char *l_val = NULL;
l_val = dap_strdup_printf(" %"DAP_UINT64_FORMAT_U") ", i);
l_val = dap_strdup_printf("%"DAP_UINT64_FORMAT_U, i);
json_object_object_add(json_vote_obj, "#", json_object_new_string(l_val));
DAP_DELETE(l_val);
dap_list_t* l_option = dap_list_nth(l_voting->voting_params.option_offsets_list, (uint64_t)i);
......@@ -1022,23 +1022,24 @@ static int s_cli_voting(int a_argc, char **a_argv, void **a_str_reply)
DIV_256_COIN(l_results[i].weights, l_total_weight, &l_weight_percentage);
MULT_256_COIN(l_weight_percentage, dap_chain_coins_to_balance("100.0"), &l_weight_percentage);
const char *l_weight_percentage_str = dap_uint256_decimal_to_round_char(l_weight_percentage, 2, true);
const char *l_w_coins, *l_w_datoshi = dap_uint256_to_char(l_results[i].weights, &l_w_coins);
l_val = dap_strdup_printf("Votes: %"DAP_UINT64_FORMAT_U" (%.2f%%)\nWeight: %s (%s) %s (%s%%)",
l_results[i].num_of_votes, l_percentage, l_w_coins, l_w_datoshi, l_net->pub.native_ticker, l_weight_percentage_str);
json_object_object_add(json_vote_obj, "price", json_object_new_string(l_val));
const char *l_weight_percentage_str = dap_uint256_decimal_to_round_char(l_weight_percentage, 2, true),
*l_w_coins, *l_w_datoshi = dap_uint256_to_char(l_results[i].weights, &l_w_coins);
l_val = dap_strdup_printf("%"DAP_UINT64_FORMAT_U" (%.2f%%)", l_results[i].num_of_votes);
json_object_object_add(json_vote_obj, "votes", json_object_new_string(l_val));
DAP_DELETE(l_val);
l_val = dap_strdup_printf("%s (%s) %s (%s%%)", l_percentage, l_w_coins, l_w_datoshi, l_net->pub.native_ticker, l_weight_percentage_str);
json_object_object_add(json_vote_obj, "weight", json_object_new_string(l_val));
DAP_DELETE(l_val);
json_object_array_add(json_arr_vote_out, json_vote_obj);
}
json_object_object_add(json_vote_out, "Results", json_arr_vote_out);
json_object_object_add(json_vote_out, "results", json_arr_vote_out);
DAP_DELETE(l_results);
char *l_val = NULL;
l_val = dap_strdup_printf(" %"DAP_UINT64_FORMAT_U, l_votes_count);
json_object_object_add(json_vote_out, "Total number of votes", json_object_new_string(l_val));
l_val = dap_strdup_printf("%"DAP_UINT64_FORMAT_U, l_votes_count);
json_object_object_add(json_vote_out, "total number of votes", json_object_new_string(l_val));
DAP_DELETE(l_val);
const char *l_tw_coins, *l_tw_datoshi = dap_uint256_to_char(l_total_weight, &l_tw_coins);
l_val = dap_strdup_printf("%s (%s) %s\n\n", l_tw_coins, l_tw_datoshi, l_net->pub.native_ticker);
json_object_object_add(json_vote_out, "Total weight", json_object_new_string(l_val));
l_val = dap_strdup_printf("%s (%s) %s", l_tw_coins, l_tw_datoshi, l_net->pub.native_ticker);
json_object_object_add(json_vote_out, "total weight", json_object_new_string(l_val));
DAP_DELETE(l_val);
json_object_array_add(*json_arr_reply, json_vote_out);
}break;
......
......@@ -1362,7 +1362,7 @@ static int s_cli_dag(int argc, char ** argv, void **a_str_reply)
return -DAP_CHAIN_NODE_CLI_COM_DAG_PARAM_ERR;
}
if(dap_chain_node_cli_cmd_values_parse_net_chain_for_json(*a_json_arr_reply, &arg_index, argc, argv, &l_chain, &l_net,CHAIN_TYPE_TX) < 0)
if(dap_chain_node_cli_cmd_values_parse_net_chain_for_json(*a_json_arr_reply, &arg_index, argc, argv, &l_chain, &l_net,CHAIN_TYPE_TOKEN) < 0)
return -DAP_CHAIN_NODE_CLI_COM_DAG_PARAM_ERR;
if ((l_net == NULL) || (l_chain == NULL)){
......
......@@ -73,7 +73,7 @@ typedef struct dap_wallet_tx_cache {
char token_ticker[DAP_CHAIN_TICKER_SIZE_MAX];
bool multichannel;
int ret_code;
dap_chain_net_srv_uid_t tag;
dap_chain_net_srv_uid_t srv_uid;
dap_chain_tx_tag_action_type_t action;
dap_list_t *tx_wallet_inputs;
dap_list_t *tx_wallet_outputs;
......@@ -122,7 +122,7 @@ static char * s_wallet_cache_type_to_str(dap_s_wallets_cache_type_t a_type)
int dap_chain_wallet_cache_init()
{
char *l_walet_cache_type_str = dap_config_get_item_str(g_config, "wallets","wallets_cache");
const char *l_walet_cache_type_str = dap_config_get_item_str(g_config, "wallets","wallets_cache");
if (l_walet_cache_type_str){
if (!dap_strcmp(l_walet_cache_type_str, "disable")){
s_wallets_cache_type = DAP_WALLET_CACHE_TYPE_DISABLED;
......@@ -175,8 +175,6 @@ int dap_chain_wallet_cache_init()
dap_chain_wallet_add_wallet_opened_notify(s_wallet_opened_callback, NULL);
dap_chain_wallet_add_wallet_created_notify(s_wallet_opened_callback, NULL);
}
return 0;
}
......@@ -307,7 +305,7 @@ int dap_chain_wallet_cache_tx_find_in_history(dap_chain_addr_t *a_addr, char **a
if(a_action)
*a_action = l_current_wallet_tx->action;
if(a_uid)
*a_uid = l_current_wallet_tx->tag;
*a_uid = l_current_wallet_tx->srv_uid;
if (a_token)
*a_token = l_current_wallet_tx->token_ticker;
pthread_rwlock_unlock(&s_wallet_cache_rwlock);
......@@ -521,10 +519,9 @@ static int s_save_tx_into_wallet_cache(dap_chain_t *a_chain, dap_chain_datum_tx_
l_wallet_tx_item = DAP_NEW_Z(dap_wallet_tx_cache_t);
l_wallet_tx_item->tx_hash = *a_tx_hash;
l_wallet_tx_item->tx = a_tx;
if (a_main_token_ticker)
dap_strncpy(l_wallet_tx_item->token_ticker, a_main_token_ticker, DAP_CHAIN_TICKER_SIZE_MAX);
dap_strncpy(l_wallet_tx_item->token_ticker, a_main_token_ticker ? a_main_token_ticker : "0", DAP_CHAIN_TICKER_SIZE_MAX);
l_wallet_tx_item->ret_code = a_ret_code;
l_wallet_tx_item->tag = a_srv_uid;
l_wallet_tx_item->srv_uid = a_srv_uid;
l_wallet_tx_item->action = a_action;
HASH_ADD(hh, l_wallet_item->wallet_txs, tx_hash, sizeof(dap_hash_fast_t), l_wallet_tx_item);
}
......@@ -584,11 +581,10 @@ static int s_save_tx_into_wallet_cache(dap_chain_t *a_chain, dap_chain_datum_tx_
l_wallet_tx_item = DAP_NEW_Z(dap_wallet_tx_cache_t);
l_wallet_tx_item->tx_hash = *a_tx_hash;
l_wallet_tx_item->tx = a_tx;
if(a_main_token_ticker)
dap_strncpy(l_wallet_tx_item->token_ticker, a_main_token_ticker, DAP_CHAIN_TICKER_SIZE_MAX);
dap_strncpy(l_wallet_tx_item->token_ticker, a_main_token_ticker ? a_main_token_ticker : "0", DAP_CHAIN_TICKER_SIZE_MAX);
l_wallet_tx_item->multichannel = l_multichannel;
l_wallet_tx_item->ret_code = a_ret_code;
l_wallet_tx_item->tag = a_srv_uid;
l_wallet_tx_item->srv_uid = a_srv_uid;
l_wallet_tx_item->action = a_action;
HASH_ADD(hh, l_wallet_item->wallet_txs, tx_hash, sizeof(dap_hash_fast_t), l_wallet_tx_item);
}
......@@ -711,10 +707,9 @@ static int s_save_tx_cache_for_addr(dap_chain_t *a_chain, dap_chain_addr_t *a_ad
l_wallet_tx_item = DAP_NEW_Z(dap_wallet_tx_cache_t);
l_wallet_tx_item->tx_hash = *a_tx_hash;
l_wallet_tx_item->tx = a_tx;
if (a_main_token_ticker)
dap_strncpy(l_wallet_tx_item->token_ticker, a_main_token_ticker, DAP_CHAIN_TICKER_SIZE_MAX);
dap_strncpy(l_wallet_tx_item->token_ticker, a_main_token_ticker ? a_main_token_ticker : "0", DAP_CHAIN_TICKER_SIZE_MAX);
l_wallet_tx_item->ret_code = a_ret_code;
l_wallet_tx_item->tag = a_srv_uid;
l_wallet_tx_item->srv_uid = a_srv_uid;
l_wallet_tx_item->action = a_action;
HASH_ADD(hh, l_wallet_item->wallet_txs, tx_hash, sizeof(dap_hash_fast_t), l_wallet_tx_item);
}
......@@ -773,11 +768,10 @@ static int s_save_tx_cache_for_addr(dap_chain_t *a_chain, dap_chain_addr_t *a_ad
l_wallet_tx_item = DAP_NEW_Z(dap_wallet_tx_cache_t);
l_wallet_tx_item->tx_hash = *a_tx_hash;
l_wallet_tx_item->tx = a_tx;
if(a_main_token_ticker)
dap_strncpy(l_wallet_tx_item->token_ticker, a_main_token_ticker, DAP_CHAIN_TICKER_SIZE_MAX);
dap_strncpy(l_wallet_tx_item->token_ticker, a_main_token_ticker ? a_main_token_ticker : "0", DAP_CHAIN_TICKER_SIZE_MAX);
l_wallet_tx_item->multichannel = l_multichannel;
l_wallet_tx_item->ret_code = a_ret_code;
l_wallet_tx_item->tag = a_srv_uid;
l_wallet_tx_item->srv_uid = a_srv_uid;
l_wallet_tx_item->action = a_action;
HASH_ADD(hh, l_wallet_item->wallet_txs, tx_hash, sizeof(dap_hash_fast_t), l_wallet_tx_item);
}
......@@ -823,4 +817,90 @@ static void s_callback_datum_removed_notify(void *a_arg, dap_chain_hash_fast_t *
}
}
pthread_rwlock_unlock(&s_wallet_cache_rwlock);
}
static void s_wallet_cache_iter_fill(dap_chain_wallet_cache_iter_t *a_cache_iter, dap_wallet_tx_cache_t *a_cache_index)
{
a_cache_iter->cur_item = (void*)a_cache_index;
if (a_cache_index) {
a_cache_iter->cur_tx = a_cache_index->tx;
a_cache_iter->cur_hash = &a_cache_index->tx_hash;
a_cache_iter->ret_code = a_cache_index->ret_code;
a_cache_iter->action = a_cache_index->action;
a_cache_iter->uid = a_cache_index->srv_uid;
a_cache_iter->token_ticker = dap_strcmp(a_cache_index->token_ticker, "0") ? a_cache_index->token_ticker : NULL;
} else {
a_cache_iter->cur_tx = NULL;
a_cache_iter->cur_hash = NULL;
a_cache_iter->ret_code = 0;
a_cache_iter->token_ticker = NULL;
a_cache_iter->action = 0;
a_cache_iter->uid.uint64 = 0;
}
}
dap_chain_wallet_cache_iter_t *dap_chain_wallet_cache_iter_create(dap_chain_addr_t a_addr)
{
dap_chain_wallet_cache_iter_t *l_iter = NULL;
pthread_rwlock_wrlock(&s_wallet_cache_rwlock);
dap_wallet_cache_t *l_wallet_item = NULL, *l_tmp;
HASH_FIND(hh, s_wallets_cache, &a_addr, sizeof(dap_chain_addr_t), l_wallet_item);
if (!l_wallet_item || !l_wallet_item->wallet_txs){
pthread_rwlock_unlock(&s_wallet_cache_rwlock);
return l_iter;
}
l_iter = DAP_NEW_Z(dap_chain_wallet_cache_iter_t);
if(!l_iter){
log_it(L_CRITICAL, "%s", c_error_memory_alloc);
pthread_rwlock_unlock(&s_wallet_cache_rwlock);
return NULL;
}
l_iter->cur_item = l_wallet_item->wallet_txs;
l_iter->cur_addr_cache = l_wallet_item;
pthread_rwlock_unlock(&s_wallet_cache_rwlock);
return l_iter;
}
void dap_chain_wallet_cache_iter_delete(dap_chain_wallet_cache_iter_t *a_iter)
{
DAP_DELETE(a_iter);
}
dap_chain_datum_tx_t *dap_chain_wallet_cache_iter_get(dap_chain_wallet_cache_iter_t *a_iter, dap_chain_wallet_getting_type_t a_type)
{
switch (a_type){
case DAP_CHAIN_WALLET_CACHE_GET_FIRST:{
pthread_rwlock_wrlock(&s_wallet_cache_rwlock);
s_wallet_cache_iter_fill(a_iter, ((dap_wallet_cache_t*)a_iter->cur_addr_cache)->wallet_txs);
pthread_rwlock_unlock(&s_wallet_cache_rwlock);
} break;
case DAP_CHAIN_WALLET_CACHE_GET_LAST:{
pthread_rwlock_wrlock(&s_wallet_cache_rwlock);
dap_wallet_tx_cache_t *l_tx_cache = HASH_LAST(((dap_wallet_cache_t*)a_iter->cur_addr_cache)->wallet_txs);
s_wallet_cache_iter_fill(a_iter, l_tx_cache);
pthread_rwlock_unlock(&s_wallet_cache_rwlock);
} break;
case DAP_CHAIN_WALLET_CACHE_GET_NEXT:{
pthread_rwlock_wrlock(&s_wallet_cache_rwlock);
dap_wallet_tx_cache_t *l_tx_cache = a_iter->cur_item ? (dap_wallet_tx_cache_t*)a_iter->cur_item : NULL;
l_tx_cache = l_tx_cache && l_tx_cache->hh.next ? l_tx_cache->hh.next : NULL;
s_wallet_cache_iter_fill(a_iter, l_tx_cache);
pthread_rwlock_unlock(&s_wallet_cache_rwlock);
} break;
case DAP_CHAIN_WALLET_CACHE_GET_PREVIOUS:{
pthread_rwlock_wrlock(&s_wallet_cache_rwlock);
dap_wallet_tx_cache_t *l_tx_cache = a_iter->cur_item ? (dap_wallet_tx_cache_t*)a_iter->cur_item : NULL;
l_tx_cache = l_tx_cache && l_tx_cache->hh.prev ? l_tx_cache->hh.prev : NULL;
s_wallet_cache_iter_fill(a_iter, l_tx_cache);
pthread_rwlock_unlock(&s_wallet_cache_rwlock);
} break;
default:
break;
}
return a_iter->cur_tx;
}
\ No newline at end of file
......@@ -30,6 +30,22 @@
int dap_chain_wallet_cache_init();
int dap_chain_wallet_cache_deinit();
typedef enum dap_chain_wallet_getting_type {
DAP_CHAIN_WALLET_CACHE_GET_FIRST = 0,
DAP_CHAIN_WALLET_CACHE_GET_LAST,
DAP_CHAIN_WALLET_CACHE_GET_NEXT,
DAP_CHAIN_WALLET_CACHE_GET_PREVIOUS,
} dap_chain_wallet_getting_type_t;
typedef struct dap_chain_wallet_cache_iter {
dap_chain_datum_tx_t *cur_tx;
dap_chain_hash_fast_t *cur_hash;
uint32_t action;
dap_chain_net_srv_uid_t uid;
int ret_code;
char *token_ticker;
void *cur_item;
void *cur_addr_cache;
} dap_chain_wallet_cache_iter_t;
/**
* @brief Find next transactions after l_tx_hash_curr for wallet addr and save pointer to datum into a_tx. If l_tx_hash_curr is NULL then function find first tx for addr.
......@@ -77,3 +93,8 @@ int dap_chain_wallet_cache_tx_find_in_history(dap_chain_addr_t *a_addr, char **a
*/
int dap_chain_wallet_cache_tx_find_outs_with_val(dap_chain_net_t *a_net, const char *a_token_ticker, const dap_chain_addr_t *a_addr,
dap_list_t **a_outs_list, uint256_t a_value_needed, uint256_t *a_value_transfer);
dap_chain_wallet_cache_iter_t *dap_chain_wallet_cache_iter_create(dap_chain_addr_t a_addr);
void dap_chain_wallet_cache_iter_delete(dap_chain_wallet_cache_iter_t *a_iter);
dap_chain_datum_tx_t *dap_chain_wallet_cache_iter_get(dap_chain_wallet_cache_iter_t *a_iter, dap_chain_wallet_getting_type_t a_type);
\ No newline at end of file