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 (14)
Showing
with 837 additions and 613 deletions
Subproject commit 0e5303fbfc0a646d157117d451ac3e98e5a5752d
Subproject commit 89400bc2340111a11ed7895a30983dffc875d488
......@@ -76,25 +76,73 @@ dap_chain_addr_str_t dap_chain_addr_to_str_static_(const dap_chain_addr_t *a_add
return res;
}
/**
* @brief s_addr_from_str
* @param [out] a_addr - pointer to addr fill
* @param [in] a_str - string with one addr
* @return 0 if pass, other if error
*/
static int s_addr_from_str(dap_chain_addr_t *a_addr, const char *a_str)
{
dap_return_val_if_pass(!a_addr || !a_str || !a_str[0], -1);
if (!dap_strcmp(a_str, "null") || !dap_strcmp(a_str, "0")) {
memset(a_addr, 0, sizeof(dap_chain_addr_t));
return 0;
}
int l_ret = 0;
size_t l_ret_size = DAP_ENC_BASE58_DECODE_SIZE(strlen(a_str));
dap_chain_addr_t *l_addr_cur = DAP_NEW_Z_SIZE_RET_VAL_IF_FAIL(dap_chain_addr_t, l_ret_size, -2);
if (dap_enc_base58_decode(a_str, l_addr_cur) == sizeof(dap_chain_addr_t) && !dap_chain_addr_check_sum(l_addr_cur)) {
memcpy(a_addr, l_addr_cur, sizeof(dap_chain_addr_t));
} else {
l_ret = -3;
}
DAP_DELETE(l_addr_cur);
return l_ret;
}
/**
* @brief dap_chain_str_to_addr
* @param a_addr
* @return
* @param a_str - string with one addr
* @return pointer to dap_chain_addr_t if pass, if not - NULL
*/
dap_chain_addr_t* dap_chain_addr_from_str(const char *a_str)
dap_chain_addr_t *dap_chain_addr_from_str(const char *a_str)
{
size_t l_str_len = (a_str) ? strlen(a_str) : 0;
if(l_str_len <= 0)
dap_chain_addr_t *l_ret = DAP_NEW_Z_RET_VAL_IF_FAIL(dap_chain_addr_t, NULL);
if (s_addr_from_str(l_ret, a_str)) {
DAP_DELETE(l_ret);
return NULL;
if (!dap_strcmp(a_str, "null") || !dap_strcmp(a_str, "0")) {
return DAP_NEW_Z(dap_chain_addr_t);
}
size_t l_ret_size = DAP_ENC_BASE58_DECODE_SIZE(l_str_len);
dap_chain_addr_t *l_addr = DAP_NEW_Z_SIZE(dap_chain_addr_t, l_ret_size);
return ( dap_enc_base58_decode(a_str, l_addr) == sizeof(dap_chain_addr_t) )
&& !dap_chain_addr_check_sum(l_addr)
? l_addr
: ( DAP_DELETE(l_addr), NULL );
return l_ret;
}
/**
* @brief parce addrs string div by ',', alloc memory to addrs
* @param a_addr_str - ddrs string div by ','
* @param a_addr - pointer to memory alloc
* @return addr count
*/
size_t dap_chain_addr_from_str_array(const char *a_addr_str, dap_chain_addr_t **a_addr)
{
dap_return_val_if_pass(!a_addr_str || !a_addr, 0);
size_t l_count = dap_str_symbol_count(a_addr_str, ',') + 1;
dap_chain_addr_t *l_addr = DAP_NEW_Z_COUNT_RET_VAL_IF_FAIL(dap_chain_addr_t, l_count, 0);
char **l_addr_str_array = dap_strsplit(a_addr_str, ",", l_count);
if (!l_addr_str_array) {
DAP_DELETE(l_addr);
return 0;
}
for (size_t i = 0; i < l_count; ++i) {
if (s_addr_from_str(l_addr + i, l_addr_str_array[i])) {
DAP_DELETE(l_addr);
dap_strfreev(l_addr_str_array);
return 0;
}
}
dap_strfreev(l_addr_str_array);
*a_addr = l_addr;
return l_count;
}
bool dap_chain_addr_is_blank(const dap_chain_addr_t *a_addr)
......
......@@ -55,8 +55,41 @@ DAP_STATIC_INLINE struct policy_net_list_item *s_net_find(uint64_t a_net_id)
DAP_STATIC_INLINE int s_policy_num_compare(dap_list_t *a_list1, dap_list_t *a_list2)
{
return ((dap_chain_policy_t *)(a_list1->data))->activate.num == ((dap_chain_policy_t *)(a_list2->data))->activate.num ? 0 :
((dap_chain_policy_t *)(a_list1->data))->activate.num > ((dap_chain_policy_t *)(a_list2->data))->activate.num ? 1 : -1;
dap_chain_policy_t
*l_policy1 = a_list1->data,
*l_policy2 = a_list2->data;
if (l_policy1->type != DAP_CHAIN_POLICY_ACTIVATE || l_policy2->type != DAP_CHAIN_POLICY_ACTIVATE) {
log_it(L_WARNING, "Compare wrong policy type");
return 0;
}
return ((dap_chain_policy_activate_t *)(l_policy1->data))->num == ((dap_chain_policy_activate_t *)(l_policy2->data))->num ? 0 :
((dap_chain_policy_activate_t *)(l_policy1->data))->num > ((dap_chain_policy_activate_t *)(l_policy2->data))->num ? 1 : -1;
}
DAP_STATIC_INLINE bool s_policy_is_cond(dap_chain_policy_t *a_policy)
{
return a_policy->type == DAP_CHAIN_POLICY_ACTIVATE &&
(DAP_FLAG_CHECK(((dap_chain_policy_activate_t *)(a_policy->data))->flags, DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_TS) ||
DAP_FLAG_CHECK(((dap_chain_policy_activate_t *)(a_policy->data))->flags, DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_BLOCK_NUM));
}
static bool s_policy_cond_activated(dap_chain_policy_activate_t *a_policy_activate)
{
bool l_ret = false;
if (DAP_FLAG_CHECK(a_policy_activate->flags, DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_TS)) {
time_t l_current_time = dap_time_now();
if (l_current_time >= a_policy_activate->ts_start && (!a_policy_activate->ts_stop || l_current_time <= a_policy_activate->ts_stop))
l_ret |= true;
}
if (DAP_FLAG_CHECK(a_policy_activate->flags, DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_BLOCK_NUM)) {
if (!a_policy_activate->chain_union.chain) {
log_it(L_ERROR, "Chain is null in policy item with upped DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_BLOCK_NUM flag");
return l_ret;
}
if ( a_policy_activate->chain_union.chain->atom_num_last >= a_policy_activate->block_start && (!a_policy_activate->block_stop || a_policy_activate->chain_union.chain->atom_num_last <= a_policy_activate->block_stop))
l_ret |= true;
}
return l_ret;
}
/**
......@@ -122,20 +155,30 @@ int dap_chain_policy_add(dap_chain_policy_t *a_policy, uint64_t a_net_id)
log_it(L_ERROR, "Can't find net %"DAP_UINT64_FORMAT_X" in policy list", a_net_id);
return -2;
}
if (dap_list_find(l_net_item->policies, a_policy, s_policy_num_compare)) {
log_it(L_ERROR, "CN-%u already added to net %"DAP_UINT64_FORMAT_X, a_policy->activate.num, a_net_id);
return -3;
switch (a_policy->type) {
case DAP_CHAIN_POLICY_ACTIVATE:
if (dap_list_find(l_net_item->policies, a_policy, s_policy_num_compare)) {
log_it(L_ERROR, "CN-%u already added to net %"DAP_UINT64_FORMAT_X, ((dap_chain_policy_activate_t *)(a_policy->data))->num, a_net_id);
return -3;
}
l_net_item->policies = dap_list_insert_sorted(l_net_item->policies, a_policy, s_policy_num_compare);
if (!s_policy_is_cond(a_policy))
l_net_item->last_num_policy = dap_max(((dap_chain_policy_activate_t *)(a_policy->data))->num, l_net_item->last_num_policy);
break;
case DAP_CHAIN_POLICY_DEACTIVATE:
for (size_t i = 0; i < ((dap_chain_policy_deactivate_t *)(a_policy->data))->count; ++i) {
uint32_t l_policy_num = ((dap_chain_policy_deactivate_t *)(a_policy->data))->nums[i];
if (dap_list_find(l_net_item->exception_list, (const void *)(uintptr_t)l_policy_num, NULL)) {
log_it(L_ERROR, "CN-%u already added to exception list net %"DAP_UINT64_FORMAT_X, l_policy_num, a_net_id);
continue;
}
l_net_item->exception_list = dap_list_append(l_net_item->exception_list, (void *)(uintptr_t)l_policy_num);
}
break;
default:
log_it(L_ERROR, "Unknow policy type %u", a_policy->type);
break;
}
l_net_item->policies = dap_list_insert_sorted(l_net_item->policies, a_policy, s_policy_num_compare);
for (size_t i = 0; i < a_policy->deactivate.count; ++i) {
uint32_t l_policy_num = a_policy->deactivate.nums[i];
if (dap_list_find(l_net_item->exception_list, (const void *)(uintptr_t)l_policy_num, NULL)) {
log_it(L_ERROR, "CN-%u already added to exception list net %"DAP_UINT64_FORMAT_X, l_policy_num, a_net_id);
continue;
}
l_net_item->exception_list = dap_list_append(l_net_item->exception_list, (void *)(uintptr_t)l_policy_num);
}
l_net_item->last_num_policy = dap_max(a_policy->activate.num, l_net_item->last_num_policy);
return 0;
}
......@@ -147,6 +190,7 @@ int dap_chain_policy_add(dap_chain_policy_t *a_policy, uint64_t a_net_id)
*/
int dap_chain_policy_add_to_exception_list(uint32_t a_policy_num, uint64_t a_net_id)
{
dap_return_val_if_pass(!a_policy_num, -1);
struct policy_net_list_item *l_net_item = s_net_find(a_net_id);
if (!l_net_item) {
log_it(L_ERROR, "Can't find net %"DAP_UINT64_FORMAT_X" in policy list", a_net_id);
......@@ -168,40 +212,23 @@ int dap_chain_policy_add_to_exception_list(uint32_t a_policy_num, uint64_t a_net
*/
bool dap_chain_policy_activated(uint32_t a_policy_num, uint64_t a_net_id)
{
bool l_ret = false;
const bool l_ret_false = false;
struct policy_net_list_item *l_net_item = s_net_find(a_net_id);
dap_return_val_if_pass(!l_net_item, l_ret);
if (l_net_item->last_num_policy < a_policy_num)
return l_ret;
dap_return_val_if_pass(!l_net_item, l_ret_false);
// exception list check
if (dap_list_find(l_net_item->exception_list, (const void *)(uintptr_t)a_policy_num, NULL))
return l_ret;
return l_ret_false;
// seach politics to condition check
dap_chain_policy_t l_to_search = {
.activate.num = a_policy_num
};
dap_list_t *l_list_item = dap_list_find(l_net_item->policies, &l_to_search, s_policy_num_compare);
if (!l_list_item) {
if (l_net_item->last_num_policy > a_policy_num) // use cumulative principle without check conditions
return true;
return l_ret;
}
dap_chain_policy_t *l_policy_item = (dap_chain_policy_t *)l_list_item->data;
// condition check
if (DAP_FLAG_CHECK(l_policy_item->activate.flags, DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_TS)) {
time_t l_current_time = dap_time_now();
if (l_current_time < l_policy_item->activate.ts_start || (l_policy_item->activate.ts_stop && l_current_time > l_policy_item->activate.ts_stop))
return l_ret;
dap_chain_policy_t *l_to_search = DAP_NEW_Z_SIZE_RET_VAL_IF_FAIL(dap_chain_policy_t, sizeof(dap_chain_policy_t) + sizeof(dap_chain_policy_activate_t), false);
l_to_search->type = DAP_CHAIN_POLICY_ACTIVATE;
((dap_chain_policy_activate_t *)(l_to_search->data))->num = a_policy_num;
dap_list_t *l_list_item = dap_list_find(l_net_item->policies, l_to_search, s_policy_num_compare);
DAP_DELETE(l_to_search);
if (l_list_item && s_policy_is_cond((dap_chain_policy_t *)l_list_item->data)) {
return s_policy_cond_activated((dap_chain_policy_activate_t *)((dap_chain_policy_t *)(l_list_item->data))->data);
}
if (DAP_FLAG_CHECK(l_policy_item->activate.flags, DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_BLOCK_NUM)) {
if (!l_policy_item->activate.chain_union.chain) {
log_it(L_ERROR, "Chain is null in policy item with upped DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_BLOCK_NUM flag");
return l_ret;
}
if ( l_policy_item->activate.chain_union.chain->atom_num_last < l_policy_item->activate.block_start || (l_policy_item->activate.block_stop && l_policy_item->activate.chain_union.chain->atom_num_last > l_policy_item->activate.block_stop))
return l_ret;
}
return true;
// cumulative return
return a_policy_num <= l_net_item->last_num_policy;
}
/**
......@@ -212,14 +239,15 @@ bool dap_chain_policy_activated(uint32_t a_policy_num, uint64_t a_net_id)
*/
dap_chain_policy_t *dap_chain_policy_find(uint32_t a_policy_num, uint64_t a_net_id)
{
dap_return_val_if_pass(!a_policy_num, NULL);
struct policy_net_list_item *l_net_item = s_net_find(a_net_id);
dap_return_val_if_pass(!l_net_item, NULL);
if (l_net_item->last_num_policy < a_policy_num)
return NULL;
dap_chain_policy_t l_to_search = {
.activate.num = a_policy_num
};
dap_list_t *l_find = dap_list_find(l_net_item->policies, &l_to_search, s_policy_num_compare);
dap_chain_policy_t *l_to_search = DAP_NEW_Z_SIZE_RET_VAL_IF_FAIL(dap_chain_policy_t, sizeof(dap_chain_policy_t) + sizeof(dap_chain_policy_activate_t), false);
l_to_search->type = DAP_CHAIN_POLICY_ACTIVATE;
((dap_chain_policy_activate_t *)(l_to_search->data))->num = a_policy_num;
dap_list_t *l_find = dap_list_find(l_net_item->policies, l_to_search, s_policy_num_compare);
DAP_DELETE(l_to_search);
if (!l_find) {
log_it(L_DEBUG, "Can't find CN-%u in net %"DAP_UINT64_FORMAT_X, a_policy_num, a_net_id);
return NULL;
......@@ -248,21 +276,30 @@ json_object *dap_chain_policy_list(uint64_t a_net_id)
dap_string_t *l_active_str = dap_string_new("");
dap_string_t *l_inactive_str = dap_string_new("");
if (l_net_item->last_num_policy)
dap_string_append_printf(l_active_str, "%s CN-%u ", dap_list_find(l_net_item->exception_list, (const void *)(uintptr_t)l_net_item->last_num_policy, NULL) ? "<" : "<=", l_net_item->last_num_policy);
json_object_object_add(l_ret, "cumulative active", json_object_new_string(l_active_str->str));
dap_string_erase(l_active_str, 0, -1);
for (dap_list_t *l_iter = dap_list_first(l_net_item->policies); l_iter; l_iter = l_iter->next) {
if (dap_chain_policy_activated(((dap_chain_policy_t *)l_iter->data)->activate.num, a_net_id))
dap_string_append_printf(l_active_str, "CN-%u ", ((dap_chain_policy_t *)l_iter->data)->activate.num);
else
dap_string_append_printf(l_inactive_str, "CN-%u ", ((dap_chain_policy_t *)l_iter->data)->activate.num);
dap_chain_policy_activate_t *l_policy_activate = (dap_chain_policy_activate_t *)((dap_chain_policy_t *)(l_iter->data))->data;
if (dap_list_find(l_net_item->exception_list, (const void *)(uintptr_t)l_policy_activate->num, NULL))
continue;
if (s_policy_is_cond((dap_chain_policy_t *)(l_iter->data))) {
if (s_policy_cond_activated(l_policy_activate))
dap_string_append_printf(l_active_str, "CN-%u ", l_policy_activate->num);
else
dap_string_append_printf(l_inactive_str, "CN-%u ", l_policy_activate->num);
}
}
json_object_object_add(l_ret, "active", json_object_new_string(l_active_str->str));
json_object_object_add(l_ret, "inactive", json_object_new_string(l_inactive_str->str));
json_object_object_add(l_ret, "conditional active", json_object_new_string(l_active_str->str));
json_object_object_add(l_ret, "conditional inactive", json_object_new_string(l_inactive_str->str));
dap_string_free(l_active_str, true);
dap_string_erase(l_inactive_str, 0, -1);
for (dap_list_t *l_iter = dap_list_first(l_net_item->exception_list); l_iter; l_iter = l_iter->next) {
dap_string_append_printf(l_inactive_str, "CN-%u ", (uint32_t)(uintptr_t)l_iter->data);
}
json_object_object_add(l_ret, "in exception list", json_object_new_string(l_inactive_str->str));
json_object_object_add(l_ret, "exception list", json_object_new_string(l_inactive_str->str));
dap_string_free(l_inactive_str, true);
return l_ret;
}
......@@ -273,44 +310,58 @@ json_object *dap_chain_policy_json_collect(dap_chain_policy_t *a_policy)
json_object *l_ret = json_object_new_object();
json_object_object_add(l_ret, "version", json_object_new_uint64(a_policy->version));
json_object_object_add(l_ret, "num", json_object_new_uint64(a_policy->activate.num));
if (a_policy->activate.ts_start) {
char l_time[DAP_TIME_STR_SIZE] = {};
dap_time_to_str_rfc822(l_time, DAP_TIME_STR_SIZE - 1, a_policy->activate.ts_start);
json_object_object_add(l_ret, "ts_start", json_object_new_string(l_time));
} else {
json_object_object_add(l_ret, "ts_start", json_object_new_int(0));
}
if (a_policy->activate.ts_stop) {
char l_time[DAP_TIME_STR_SIZE] = {};
dap_time_to_str_rfc822(l_time, DAP_TIME_STR_SIZE - 1, a_policy->activate.ts_stop);
json_object_object_add(l_ret, "ts_stop", json_object_new_string(l_time));
} else {
json_object_object_add(l_ret, "ts_stop", json_object_new_int(0));
}
json_object_object_add(l_ret, "block_start", json_object_new_uint64(a_policy->activate.block_start));
json_object_object_add(l_ret, "block_stop", json_object_new_uint64(a_policy->activate.block_stop));
if (a_policy->activate.block_start || a_policy->activate.block_stop) {
if (!a_policy->activate.chain_union.chain) {
json_object_object_add(l_ret, "chain", json_object_new_string("ERROR pointer chain is NULL"));
} else {
char l_chain_id[32] = { };
snprintf(l_chain_id, sizeof(l_chain_id) - 1, "0x%016"DAP_UINT64_FORMAT_x, a_policy->activate.chain_union.chain->id.uint64);
json_object_object_add(l_ret, "chain", json_object_new_string(l_chain_id));
json_object_object_add(l_ret, "type", json_object_new_string(dap_chain_policy_to_str(a_policy)));
switch (a_policy->type) {
case DAP_CHAIN_POLICY_ACTIVATE: {
dap_chain_policy_activate_t *l_policy_activate = (dap_chain_policy_activate_t *)a_policy->data;
json_object_object_add(l_ret, "num", json_object_new_uint64(l_policy_activate->num));
if (l_policy_activate->ts_start) {
char l_time[DAP_TIME_STR_SIZE] = {};
dap_time_to_str_rfc822(l_time, DAP_TIME_STR_SIZE - 1, l_policy_activate->ts_start);
json_object_object_add(l_ret, "ts_start", json_object_new_string(l_time));
} else {
json_object_object_add(l_ret, "ts_start", json_object_new_int(0));
}
if (l_policy_activate->ts_stop) {
char l_time[DAP_TIME_STR_SIZE] = {};
dap_time_to_str_rfc822(l_time, DAP_TIME_STR_SIZE - 1, l_policy_activate->ts_stop);
json_object_object_add(l_ret, "ts_stop", json_object_new_string(l_time));
} else {
json_object_object_add(l_ret, "ts_stop", json_object_new_int(0));
}
json_object_object_add(l_ret, "block_start", json_object_new_uint64(l_policy_activate->block_start));
json_object_object_add(l_ret, "block_stop", json_object_new_uint64(l_policy_activate->block_stop));
if (l_policy_activate->block_start || l_policy_activate->block_stop) {
if (!l_policy_activate->chain_union.chain) {
json_object_object_add(l_ret, "chain", json_object_new_string("ERROR pointer chain is NULL"));
} else {
char l_chain_id[32] = { };
snprintf(l_chain_id, sizeof(l_chain_id) - 1, "0x%016"DAP_UINT64_FORMAT_x, l_policy_activate->chain_union.chain->id.uint64);
json_object_object_add(l_ret, "chain", json_object_new_string(l_chain_id));
}
} else {
json_object_object_add(l_ret, "chain", json_object_new_string(""));
}
json_object_object_add(l_ret, "description", json_object_new_string("WIKI"));
}
} else {
json_object_object_add(l_ret, "chain", json_object_new_string(""));
}
if (a_policy->deactivate.count) {
dap_string_t *l_nums_list = dap_string_sized_new(a_policy->deactivate.count * (sizeof(uint32_t) + 4));
for (size_t i = 0; i < a_policy->deactivate.count; ++i) {
dap_string_append_printf(l_nums_list, "CN-%u ", a_policy->deactivate.nums[i]);
break;
case DAP_CHAIN_POLICY_DEACTIVATE: {
dap_chain_policy_deactivate_t *l_policy_deactivate = (dap_chain_policy_deactivate_t *)a_policy->data;
if (l_policy_deactivate->count) {
dap_string_t *l_nums_list = dap_string_sized_new(l_policy_deactivate->count * (sizeof(uint32_t) + 4));
for (size_t i = 0; i < l_policy_deactivate->count; ++i) {
dap_string_append_printf(l_nums_list, "CN-%u ", l_policy_deactivate->nums[i]);
}
json_object_object_add(l_ret, "deactivate", json_object_new_string(l_nums_list->str));
dap_string_free(l_nums_list, true);
} else {
json_object_object_add(l_ret, "deactivate", json_object_new_string(""));
}
}
json_object_object_add(l_ret, "deactivate", json_object_new_string(l_nums_list->str));
dap_string_free(l_nums_list, true);
} else {
json_object_object_add(l_ret, "deactivate", json_object_new_string(""));
break;
default:
break;
}
json_object_object_add(l_ret, "description", json_object_new_string("WIKI"));
return l_ret;
}
\ No newline at end of file
......@@ -227,6 +227,7 @@ dap_chain_addr_str_t dap_chain_addr_to_str_static_(const dap_chain_addr_t *a_add
#define dap_chain_addr_to_str dap_chain_addr_to_str_static
dap_chain_addr_t* dap_chain_addr_from_str(const char *str);
size_t dap_chain_addr_from_str_array(const char *a_addr_str, dap_chain_addr_t **a_addr);
bool dap_chain_addr_is_blank(const dap_chain_addr_t *a_addr);
dap_chain_srv_uid_t dap_chain_net_srv_uid_from_str(const char* a_str);
......
......@@ -29,32 +29,43 @@ along with any CellFrame SDK based project. If not, see <http://www.gnu.org/lic
#define DAP_CHAIN_POLICY_VERSION 1
#define DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_TS 1
#define DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_BLOCK_NUM (1 << 1)
#define DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_CONFIG (1 << 2)
#define DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_TS BIT(0)
#define DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_BLOCK_NUM BIT(1)
#define DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_CONFIG BIT(2)
#define DAP_CHAIN_POLICY_PUBLIC_KEY_HASH_SIGN_VALIDATORS 0x1
#define DAP_CHAIN_POLICY_OUT_EXT_USE_ENSURE 0x2
typedef enum {
DAP_CHAIN_POLICY_ACTIVATE = 0,
DAP_CHAIN_POLICY_DEACTIVATE
} dap_chain_policy_type_t;
typedef struct dap_chain_policy_activate {
uint64_t flags;
uint32_t num;
int64_t ts_start;
int64_t ts_stop;
uint64_t block_start;
uint64_t block_stop;
union {
dap_chain_id_t chain_id;
dap_chain_t *chain;
} chain_union;
} DAP_ALIGN_PACKED dap_chain_policy_activate_t;
typedef struct dap_chain_policy_deactivate {
uint64_t flags;
uint32_t count;
uint32_t nums[];
} dap_chain_policy_deactivate_t;
typedef struct dap_chain_policy {
uint16_t version;
struct {
uint32_t num;
uint64_t flags;
int64_t ts_start;
int64_t ts_stop;
uint64_t block_start;
uint64_t block_stop;
union {
dap_chain_id_t chain_id;
dap_chain_t *chain;
} chain_union;
} activate;
struct {
uint32_t count;
uint32_t nums[];
} deactivate;
} dap_chain_policy_t;
uint16_t type;
uint64_t data_size;
uint8_t data[];
} DAP_ALIGN_PACKED dap_chain_policy_t;
int dap_chain_policy_init();
int dap_chain_policy_net_add(uint64_t a_net_id);
......@@ -67,7 +78,39 @@ json_object *dap_chain_policy_json_collect(dap_chain_policy_t *a_policy);
json_object *dap_chain_policy_list(uint64_t a_net_id);
bool dap_chain_policy_activated(uint32_t a_policy_num, uint64_t a_net_id);
DAP_STATIC_INLINE size_t dap_chain_policy_deactivate_calc_size(size_t a_deactivate_count)
{
return sizeof(dap_chain_policy_t) + sizeof(dap_chain_policy_deactivate_t) + sizeof(uint32_t) * a_deactivate_count;
}
DAP_STATIC_INLINE size_t dap_chain_policy_activate_calc_size()
{
return sizeof(dap_chain_policy_t) + sizeof(dap_chain_policy_activate_t);
}
DAP_STATIC_INLINE size_t dap_chain_policy_get_size(dap_chain_policy_t *a_policy)
{
return a_policy ? a_policy->deactivate.count * sizeof(uint32_t) + sizeof(dap_chain_policy_t) : 0;
return a_policy ? sizeof(dap_chain_policy_t) + a_policy->data_size : 0;
}
DAP_STATIC_INLINE const char *dap_chain_policy_to_str(dap_chain_policy_t *a_policy)
{
if(!a_policy)
return "NULL";
switch (a_policy->type) {
case DAP_CHAIN_POLICY_ACTIVATE: return ("DAP_CHAIN_POLICY_ACTIVATE");
case DAP_CHAIN_POLICY_DEACTIVATE: return ("DAP_CHAIN_POLICY_DEACTIVATE");
default: return ("UNKNOWN");
}
}
/**
* @brief check policy num
* @param a_num
* @return true if valid, fail if not
*/
DAP_STATIC_INLINE bool dap_chain_policy_num_is_valid(uint64_t a_num)
{
uint32_t l_num = dap_maxval(l_num);
return (a_num && a_num <= l_num);
}
......@@ -397,10 +397,10 @@ void dap_chain_datum_decree_dump_json(json_object *a_json_out, dap_chain_datum_d
case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_POLICY_EXECUTE:
if (l_tsd->size != dap_chain_policy_get_size((dap_chain_policy_t *)(l_tsd->data))) {
json_object_object_add(a_json_out, "policy_num", json_object_new_string("WRONG SIZE"));
json_object_object_add(a_json_out, "policy_type", json_object_new_string("WRONG SIZE"));
break;
}
json_object_object_add(a_json_out, "policy_num", json_object_new_uint64(((dap_chain_policy_t *)(l_tsd->data))->activate.num));
json_object_object_add(a_json_out, "policy_type", json_object_new_string( dap_chain_policy_to_str((dap_chain_policy_t *)(l_tsd->data))));
break;
default:
......
......@@ -376,11 +376,11 @@ dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_stake_lock(
dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_emit_delegate(dap_chain_srv_uid_t a_srv_uid, uint256_t a_value,
uint32_t a_signs_min, dap_hash_fast_t *a_pkey_hashes,
size_t a_pkey_hashes_count)
size_t a_pkey_hashes_count, const char *a_tag_str)
{
if (IS_ZERO_256(a_value))
return NULL;
size_t l_tsd_total_size = a_pkey_hashes_count * (sizeof(dap_hash_fast_t) + sizeof(dap_tsd_t));
size_t l_tsd_total_size = a_pkey_hashes_count * (sizeof(dap_hash_fast_t) + sizeof(dap_tsd_t)) + (a_tag_str ? sizeof(dap_tsd_t) + strlen(a_tag_str) + 1 : 0);
dap_chain_tx_out_cond_t *l_item = DAP_NEW_Z_SIZE_RET_VAL_IF_FAIL(dap_chain_tx_out_cond_t, sizeof(dap_chain_tx_out_cond_t) + l_tsd_total_size, NULL);
l_item->header.item_type = TX_ITEM_TYPE_OUT_COND;
l_item->header.value = a_value;
......@@ -391,6 +391,8 @@ dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_emit_delega
byte_t *l_next_tsd_ptr = l_item->tsd;
for (size_t i = 0; i < a_pkey_hashes_count; i++)
l_next_tsd_ptr = dap_tsd_write(l_next_tsd_ptr, DAP_CHAIN_TX_OUT_COND_TSD_HASH, a_pkey_hashes + i, sizeof(dap_hash_fast_t));
if (a_tag_str)
l_next_tsd_ptr = dap_tsd_write(l_next_tsd_ptr, DAP_CHAIN_TX_OUT_COND_TSD_STR, (const void*)a_tag_str, strlen(a_tag_str) + 1);
return l_item;
}
......
......@@ -31,7 +31,7 @@ dap_chain_datum_tx_voting_params_t *dap_chain_datum_tx_voting_parse_tsd(dap_chai
{
if (!a_tx)
return NULL;
dap_chain_datum_tx_voting_params_t *l_voting_parms = DAP_NEW_Z(dap_chain_datum_tx_voting_params_t);
dap_chain_datum_tx_voting_params_t *l_voting_params = DAP_NEW_Z(dap_chain_datum_tx_voting_params_t);
char *l_buf_string;
byte_t *l_item; size_t l_tx_item_size;
TX_ITEM_ITER_TX(l_item, l_tx_item_size, a_tx) {
......@@ -41,29 +41,31 @@ dap_chain_datum_tx_voting_params_t *dap_chain_datum_tx_voting_parse_tsd(dap_chai
switch(l_tsd->type){
case VOTING_TSD_TYPE_QUESTION:
l_buf_string = DAP_NEW_Z_SIZE(char, l_tsd->size + 1);
l_voting_parms->question = memcpy(l_buf_string, l_tsd->data, l_tsd->size);
l_voting_params->question = memcpy(l_buf_string, l_tsd->data, l_tsd->size);
break;
case VOTING_TSD_TYPE_OPTION:
l_buf_string = DAP_NEW_Z_SIZE(char, l_tsd->size + 1);
l_voting_parms->options = dap_list_append(l_voting_parms->options, memcpy(l_buf_string, l_tsd->data, l_tsd->size));
l_voting_params->options = dap_list_append(l_voting_params->options, memcpy(l_buf_string, l_tsd->data, l_tsd->size));
break;
case VOTING_TSD_TYPE_EXPIRE:
l_voting_parms->voting_expire = *(dap_time_t*)l_tsd->data;
l_voting_params->voting_expire = *(dap_time_t*)l_tsd->data;
break;
case VOTING_TSD_TYPE_MAX_VOTES_COUNT:
l_voting_parms->votes_max_count = *(uint64_t*)l_tsd->data;
l_voting_params->votes_max_count = *(uint64_t*)l_tsd->data;
break;
case VOTING_TSD_TYPE_DELEGATED_KEY_REQUIRED:
l_voting_parms->delegate_key_required = *l_tsd->data;
l_voting_params->delegate_key_required = *l_tsd->data;
break;
case VOTING_TSD_TYPE_VOTE_CHANGING_ALLOWED:
l_voting_parms->vote_changing_allowed = *l_tsd->data;
l_voting_params->vote_changing_allowed = *l_tsd->data;
break;
case VOTING_TSD_TYPE_TOKEN:
strcpy(l_voting_params->token_ticker, (char *)l_tsd->data);
default:
break;
}
}
return l_voting_parms;
return l_voting_params;
}
void dap_chain_datum_tx_voting_params_delete(dap_chain_datum_tx_voting_params_t *a_params)
......@@ -131,6 +133,18 @@ dap_chain_tx_tsd_t* dap_chain_datum_voting_vote_changing_allowed_tsd_create(bool
return l_tsd;
}
dap_chain_tx_tsd_t *dap_chain_datum_voting_token_tsd_create(const char *a_token_ticker)
{
dap_return_val_if_fail(a_token_ticker && *a_token_ticker, NULL);
size_t l_ticker_len = strlen(a_token_ticker);
if (l_ticker_len >= DAP_CHAIN_TICKER_SIZE_MAX) {
log_it(L_ERROR, "Ticker len %zu is too big", l_ticker_len);
return NULL;
}
dap_chain_tx_tsd_t *l_tsd = dap_chain_datum_tx_item_tsd_create((char *)a_token_ticker, VOTING_TSD_TYPE_TOKEN, l_ticker_len);
return l_tsd;
}
dap_chain_tx_tsd_t* dap_chain_datum_voting_vote_tx_cond_tsd_create(dap_chain_hash_fast_t a_tx_hash, int a_out_idx)
{
dap_chain_tx_voting_tx_cond_t l_temp = {
......@@ -184,6 +198,9 @@ json_object *dap_chain_datum_tx_item_voting_tsd_to_json(dap_chain_datum_tx_t* a_
case VOTING_TSD_TYPE_OPTION:
json_object_array_add(l_answer_array_object, json_object_new_string_len((char*)l_tsd->data, l_tsd->size));
break;
case VOTING_TSD_TYPE_TOKEN:
json_object_object_add(l_object, "token", json_object_new_string_len((char*)l_tsd->data, l_tsd->size));
break;
case VOTING_TSD_TYPE_EXPIRE:
json_object_object_add(l_object, "exired", json_object_new_uint64(*(uint64_t*)l_tsd->data));
break;
......
......@@ -341,7 +341,6 @@ typedef struct dap_chain_datum_token_emission {
#define DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_SIGNATURS 0x000E
#define DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_UNIQUE_ID 0x000F
#define DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_BASE_TX_HASH 0x0010
#define DAP_CHAIN_DATUM_EMISSION_TSD_TYPE_TAG 0x0011
// TSD sections with transfer additional params
#define DAP_CHAIN_DATUM_TRANSFER_TSD_TYPE_OUT_COUNT 0x0013
......
......@@ -188,7 +188,8 @@ dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_stake_lock(
dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_emit_delegate(dap_chain_srv_uid_t a_srv_uid, uint256_t a_value,
uint32_t a_signs_min, dap_hash_fast_t *a_pkey_hashes,
size_t a_pkey_hashes_count);
size_t a_pkey_hashes_count, const char *a_tag_str);
/**
* Create item dap_chain_tx_sig_t
*
......
......@@ -57,6 +57,8 @@ typedef byte_t dap_chain_tx_out_cond_subtype_t;
#define DAP_CHAIN_TX_OUT_COND_TSD_ADDR 0xf001
// Chain hash
#define DAP_CHAIN_TX_OUT_COND_TSD_HASH 0xf002
// Custom str
#define DAP_CHAIN_TX_OUT_COND_TSD_STR 0xf003
/**
* @struct dap_chain_tx_out
......
......@@ -7,6 +7,7 @@
#define DAP_CHAIN_DATUM_TX_TSD_TYPE_HARDFORK_TICKER 0xf001
#define DAP_CHAIN_DATUM_TX_TSD_TYPE_HARDFORK_TX_HASH 0xf002
#define DAP_CHAIN_DATUM_TX_TSD_TYPE_HARDFORK_TRACKER 0xf0fa
#define DAP_CHAIN_DATUM_TX_TSD_TYPE_HARDFORK_VOTING_HASH 0xf0fe
typedef struct dap_chain_tx_tsd {
struct {
......
......@@ -39,7 +39,8 @@ typedef enum dap_chain_datum_voting_tsd_type {
VOTING_TSD_TYPE_DELEGATED_KEY_REQUIRED,
VOTING_TSD_TYPE_VOTE_CHANGING_ALLOWED,
VOTING_TSD_TYPE_VOTE_TX_COND,
VOTING_TSD_TYPE_VOTE
VOTING_TSD_TYPE_TOKEN,
VOTING_TSD_TYPE_VOTE = 0xfa // hardfork related
} dap_chain_datum_voting_tsd_type_t;
typedef struct dap_chain_tx_voting {
......@@ -58,12 +59,13 @@ typedef struct dap_chain_tx_vote {
} DAP_ALIGN_PACKED dap_chain_tx_vote_t;
typedef struct dap_chain_datum_tx_voting_params {
char *question;
char *question;
dap_list_t *options;
dap_time_t voting_expire;
uint64_t votes_max_count;
bool delegate_key_required;
bool vote_changing_allowed;
char token_ticker[DAP_CHAIN_TICKER_SIZE_MAX];
} dap_chain_datum_tx_voting_params_t;
#ifdef __cplusplus
......@@ -80,6 +82,7 @@ dap_chain_tx_tsd_t* dap_chain_datum_voting_max_votes_count_tsd_create(uint64_t a
dap_chain_tx_tsd_t *dap_chain_datum_voting_delegated_key_required_tsd_create(bool a_delegated_key_required);
dap_chain_tx_tsd_t* dap_chain_datum_voting_vote_changing_allowed_tsd_create(bool a_vote_changing_allowed);
dap_chain_tx_tsd_t* dap_chain_datum_voting_vote_tx_cond_tsd_create(dap_chain_hash_fast_t a_tx_hash, int a_out_idx);
dap_chain_tx_tsd_t *dap_chain_datum_voting_token_tsd_create(const char *a_token_ticker);
dap_chain_tx_voting_t *dap_chain_datum_tx_item_voting_create(void);
json_object *dap_chain_datum_tx_item_voting_tsd_to_json(dap_chain_datum_tx_t* a_tx);
......@@ -91,4 +94,4 @@ char *dap_chain_datum_tx_voting_get_answer_text_by_idx(dap_chain_datum_tx_t *a_t
#ifdef __cplusplus
}
#endif
\ No newline at end of file
#endif
......@@ -1171,51 +1171,6 @@ uint256_t dap_ledger_calc_balance(dap_ledger_t *a_ledger, const dap_chain_addr_t
return false;
}
/**
* Get the transaction in the cache by the public key that signed the transaction,
* starting from the next hash after a_tx_first_hash
*
* a_public_key[in] public key that signed the transaction
* a_public_key_size[in] public key size
* a_tx_first_hash [in/out] hash of the initial transaction/ found transaction, if 0 start from the beginning
*/
const dap_chain_datum_tx_t* dap_ledger_tx_find_by_pkey(dap_ledger_t *a_ledger,
char *a_public_key, size_t a_public_key_size, dap_chain_hash_fast_t *a_tx_first_hash)
{
if(!a_public_key || !a_tx_first_hash)
return NULL;
dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
dap_chain_datum_tx_t *l_cur_tx = NULL;
bool is_null_hash = dap_hash_fast_is_blank(a_tx_first_hash);
bool is_search_enable = is_null_hash;
dap_ledger_tx_item_t *l_iter_current, *l_item_tmp;
pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock);
HASH_ITER(hh, l_ledger_pvt->ledger_items , l_iter_current, l_item_tmp) {
dap_chain_datum_tx_t *l_tx_tmp = l_iter_current->tx;
dap_chain_hash_fast_t *l_tx_hash_tmp = &l_iter_current->tx_hash_fast;
// start searching from the next hash after a_tx_first_hash
if (!is_search_enable) {
is_search_enable = dap_hash_fast_compare(l_tx_hash_tmp, a_tx_first_hash);
continue;
}
// Get sign item from transaction
dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t*) dap_chain_datum_tx_item_get(l_tx_tmp, NULL,
NULL, TX_ITEM_TYPE_SIG, NULL);
// Get dap_sign_t from item
dap_sign_t *l_sig = dap_chain_datum_tx_item_sig_get_sign(l_tx_sig);
if(l_sig) {
// compare public key in transaction with a_public_key
if(a_public_key_size == l_sig->header.sign_pkey_size &&
!memcmp(a_public_key, l_sig->pkey_n_sign, a_public_key_size)) {
l_cur_tx = l_tx_tmp;
memcpy(a_tx_first_hash, l_tx_hash_tmp, sizeof(dap_chain_hash_fast_t));
break;
}
}
}
pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock);
return l_cur_tx;
}
/**
* @brief dap_ledger_find_pkey_by_hash
* @param a_ledger to search
......@@ -1274,92 +1229,6 @@ dap_list_t* dap_ledger_tx_cache_find_out_cond_all(dap_ledger_t *a_ledger, dap_ch
return l_ret;
}
/**
* Get the transaction in the cache with the out_cond item
*
* a_addr[in] wallet address, whose owner can use the service
*/
dap_chain_datum_tx_t* dap_ledger_tx_cache_find_out_cond(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_t a_cond_type,
dap_chain_hash_fast_t *a_tx_first_hash, dap_chain_tx_out_cond_t **a_out_cond, int *a_out_cond_idx, char *a_token_ticker)
{
if (!a_tx_first_hash)
return NULL;
dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
dap_chain_datum_tx_t *l_cur_tx = NULL;
bool is_null_hash = dap_hash_fast_is_blank(a_tx_first_hash);
bool is_search_enable = is_null_hash;
dap_ledger_tx_item_t *l_iter_current = NULL, *l_item_tmp = NULL;
dap_chain_tx_out_cond_t *l_tx_out_cond = NULL;
int l_tx_out_cond_idx = 0;
pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock);
HASH_ITER(hh, l_ledger_pvt->ledger_items, l_iter_current, l_item_tmp) {
dap_chain_datum_tx_t *l_tx_tmp = l_iter_current->tx;
dap_chain_hash_fast_t *l_tx_hash_tmp = &l_iter_current->tx_hash_fast;
// start searching from the next hash after a_tx_first_hash
if (!is_search_enable) {
is_search_enable = dap_hash_fast_compare(l_tx_hash_tmp, a_tx_first_hash);
continue;
}
// Get out_cond item from transaction
l_tx_out_cond = dap_chain_datum_tx_out_cond_get(l_tx_tmp, a_cond_type, &l_tx_out_cond_idx);
if(l_tx_out_cond) {
l_cur_tx = l_tx_tmp;
memcpy(a_tx_first_hash, l_tx_hash_tmp, sizeof(dap_chain_hash_fast_t));
if (a_token_ticker) {
strcpy(a_token_ticker, l_iter_current->cache_data.token_ticker);
}
break;
}
}
pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock);
if (a_out_cond) {
*a_out_cond = l_tx_out_cond;
}
if (a_out_cond_idx) {
*a_out_cond_idx = l_tx_out_cond_idx;
}
return l_cur_tx;
}
/**
* Get the value from all transactions in the cache with out_cond item
*
* a_addr[in] wallet address, whose owner can use the service
* a_sign [in] signature of a_addr hash for check valid key
* a_sign_size [in] signature size
*
* a_public_key[in] public key that signed the transaction
* a_public_key_size[in] public key size
*/
uint256_t dap_ledger_tx_cache_get_out_cond_value(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_t a_cond_type,
dap_chain_addr_t *a_addr, dap_chain_tx_out_cond_t **tx_out_cond)
{
uint256_t l_ret_value = {};
dap_chain_datum_tx_t *l_tx_tmp;
dap_chain_hash_fast_t l_tx_first_hash = { 0 }; // start hash
/* size_t l_pub_key_size = a_key_from->pub_key_data_size;
uint8_t *l_pub_key = dap_enc_key_serialize_pub_key(a_key_from, &l_pub_key_size);*/
dap_chain_tx_out_cond_t *l_tx_out_cond;
// Find all transactions
do {
l_tx_tmp = dap_ledger_tx_cache_find_out_cond(a_ledger, a_cond_type, &l_tx_first_hash, &l_tx_out_cond, NULL, NULL);
// Get out_cond item from transaction
if(l_tx_tmp) {
UNUSED(a_addr);
// TODO check relations a_addr with cond_data and public key
if(l_tx_out_cond) {
l_ret_value = l_tx_out_cond->header.value;
if(tx_out_cond)
*tx_out_cond = l_tx_out_cond;
}
}
} while(l_tx_tmp);
return l_ret_value;
}
dap_list_t *dap_ledger_get_list_tx_outs(dap_ledger_t *a_ledger, const char *a_token_ticker, const dap_chain_addr_t *a_addr_from,
uint256_t *a_value_transfer)
{
......@@ -1411,7 +1280,8 @@ dap_list_t *dap_ledger_get_list_tx_outs(dap_ledger_t *a_ledger, const char *a_to
}
}
}
if (a_value_transfer) *a_value_transfer = l_value_transfer;
if (a_value_transfer)
*a_value_transfer = l_value_transfer;
return l_list_used_out;
}
......@@ -1498,7 +1368,7 @@ dap_chain_datum_tx_t *dap_ledger_datum_iter_get_last(dap_ledger_datum_iter_t *a_
{
dap_ledger_private_t *l_ledger_pvt = PVT(a_iter->net->pub.ledger);
pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock);
a_iter->cur_ledger_tx_item = l_ledger_pvt->ledger_items->hh.prev;
a_iter->cur_ledger_tx_item = HASH_LAST(l_ledger_pvt->ledger_items);
a_iter->cur = ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->tx;
a_iter->cur_hash = ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->tx_hash_fast;
a_iter->is_unspent = ((dap_ledger_tx_item_t *)(a_iter->cur_ledger_tx_item))->cache_data.ts_spent ? false : true;
......@@ -1531,69 +1401,125 @@ dap_chain_tx_used_out_item_t *dap_ledger_get_tx_cond_out(dap_ledger_t *a_ledger,
/**
* @brief dap_ledger_get_list_tx_cond_outs_with_val
* @param a_ledger
* @param a_token_ticker
* @param a_addr_from
* @param a_subtype
* @param a_value_need
* @param a_value_transfer
* @return
* Get the transaction in the cache by the addr in sig item
*
* a_addr[in] public key that signed the transaction
* a_tx_first_hash [in/out] hash of the initial transaction/ found transaction, if 0 start from the beginning
*/
dap_list_t *dap_ledger_get_list_tx_cond_outs_with_val(dap_ledger_t *a_ledger, const char *a_token_ticker, const dap_chain_addr_t *a_addr_from,
dap_chain_tx_out_cond_subtype_t a_subtype, uint256_t a_value_need, uint256_t *a_value_transfer)
dap_chain_tx_out_cond_t *dap_ledger_out_cond_unspent_find_by_addr(dap_ledger_t *a_ledger, const char *a_token, dap_chain_tx_out_cond_subtype_t a_subtype,
const dap_chain_addr_t *a_addr, dap_chain_hash_fast_t *a_tx_first_hash, int *a_out_idx)
{
dap_list_t *l_list_used_out = NULL; // list of transaction with 'out' items
dap_chain_hash_fast_t l_tx_cur_hash = { 0 };
uint256_t l_value_transfer = { };
dap_chain_datum_tx_t *l_tx;
while( compare256(l_value_transfer, a_value_need) == -1
&& ( l_tx = dap_ledger_tx_find_by_addr(a_ledger, a_token_ticker, a_addr_from, &l_tx_cur_hash)) )
{
byte_t *it; size_t l_size; int i, l_out_idx_tmp = -1;
TX_ITEM_ITER_TX_TYPE(it, TX_ITEM_TYPE_OUT_COND, l_size, i, l_tx) {
++l_out_idx_tmp;
dap_chain_tx_out_cond_t *l_out_cond = (dap_chain_tx_out_cond_t*) it;
if (a_subtype != l_out_cond->header.subtype || IS_ZERO_256(l_out_cond->header.value) )
continue;
dap_chain_tx_used_out_item_t *l_item = DAP_NEW_Z(dap_chain_tx_used_out_item_t);
*l_item = (dap_chain_tx_used_out_item_t) { l_tx_cur_hash, (uint32_t)l_out_idx_tmp, l_out_cond->header.value };
l_list_used_out = dap_list_append(l_list_used_out, l_item);
SUM_256_256(l_value_transfer, l_item->value, &l_value_transfer);
// already accumulated the required value, finish the search for 'out' items
if ( compare256(l_value_transfer, a_value_need) != -1 ) {
break;
if (!a_addr || !a_token)
return NULL;
dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger);
dap_chain_tx_out_cond_t *ret = NULL;
dap_ledger_tx_item_t *l_iter_start = NULL, *it;
pthread_rwlock_rdlock(&l_ledger_pvt->ledger_rwlock);
if (a_tx_first_hash && !dap_hash_fast_is_blank(a_tx_first_hash)) {
HASH_FIND(hh, l_ledger_pvt->ledger_items, a_tx_first_hash, sizeof(dap_hash_t), l_iter_start);
if (!l_iter_start || !l_iter_start->hh.next) {
pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock);
return NULL;
}
// start searching from the next hash after a_tx_first_hash
l_iter_start = l_iter_start->hh.next;
} else
l_iter_start = l_ledger_pvt->ledger_items;
for (it = l_iter_start; it; it = it->hh.next, ret = NULL) {
// If a_token is setup we check if its not our token - miss it
if (*it->cache_data.token_ticker && dap_strcmp(it->cache_data.token_ticker, a_token))
continue;
ret = NULL;
// Get 'out_cond' item from transaction
byte_t *l_item; size_t l_size; int i, l_out_idx = 0;
TX_ITEM_ITER_TX_TYPE(l_item, TX_ITEM_TYPE_OUT_ALL, l_size, i, it->tx) {
if (*l_item == TX_ITEM_TYPE_OUT_COND) {
dap_chain_tx_out_cond_subtype_t l_subtype = ((dap_chain_tx_out_cond_t *)l_item)->header.subtype;
if (l_subtype == a_subtype ||
(a_subtype == DAP_CHAIN_TX_OUT_COND_SUBTYPE_ALL && l_subtype != DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE)) {
ret = (dap_chain_tx_out_cond_t *)l_item;
break;
}
}
l_out_idx++;
}
// Don't return regular tx or spent conditions
if (!ret || !dap_hash_fast_is_blank(&it->out_metadata[l_out_idx].tx_spent_hash_fast))
continue;
dap_hash_fast_t l_owner_tx_hash = dap_ledger_get_first_chain_tx_hash(a_ledger, a_subtype, &it->tx_hash_fast);
dap_chain_datum_tx_t *l_tx = dap_hash_fast_is_blank(&l_owner_tx_hash) ? it->tx
: dap_ledger_tx_find_by_hash(a_ledger, &l_owner_tx_hash);
if (!l_tx) {
log_it(L_ERROR, "Can't find owner for tx %s", dap_hash_fast_to_str_static(&it->tx_hash_fast));
continue;
}
// Get sign item from transaction
dap_chain_tx_sig_t *l_tx_sig = (dap_chain_tx_sig_t*) dap_chain_datum_tx_item_get(l_tx, NULL, NULL, TX_ITEM_TYPE_SIG, NULL);
// Get dap_sign_t from item
dap_sign_t *l_sign = dap_chain_datum_tx_item_sig_get_sign(l_tx_sig);
// compare public key in transaction with a_public_key
dap_chain_hash_fast_t l_sign_hash = {};
dap_sign_get_pkey_hash(l_sign, &l_sign_hash);
if (dap_hash_fast_compare(&l_sign_hash, &a_addr->data.hash_fast)) {
if (a_tx_first_hash)
*a_tx_first_hash = it->tx_hash_fast;
if (a_out_idx)
*a_out_idx = l_out_idx;
break;
}
}
return compare256(l_value_transfer, a_value_need) > -1 && l_list_used_out
? ({ if (a_value_transfer) *a_value_transfer = l_value_transfer; l_list_used_out; })
: ( dap_list_free_full(l_list_used_out, NULL), NULL );
pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock);
return ret;
}
dap_list_t *dap_ledger_get_list_tx_cond_outs(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr_from)
dap_list_t *dap_ledger_get_list_tx_cond_outs(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_t a_subtype,
const char *a_token_ticker, const dap_chain_addr_t *a_addr_from)
{
dap_list_t *l_list_used_out = NULL; // list of transaction with 'out' items
dap_chain_hash_fast_t l_tx_cur_hash = { };
dap_chain_datum_tx_t *l_tx;
while(( l_tx = dap_ledger_tx_find_by_addr(a_ledger, a_ledger->net->pub.native_ticker, a_addr_from, &l_tx_cur_hash) )) {
byte_t *it; size_t l_size; int i, l_out_idx_tmp = -1;
TX_ITEM_ITER_TX_TYPE(it, TX_ITEM_TYPE_OUT_COND, l_size, i, l_tx) {
++l_out_idx_tmp;
dap_chain_tx_out_cond_t *l_out_cond = (dap_chain_tx_out_cond_t *)it;
if ( DAP_CHAIN_TX_OUT_COND_SUBTYPE_FEE == l_out_cond->header.subtype || IS_ZERO_256(l_out_cond->header.value) )
continue;
if (dap_ledger_tx_hash_is_used_out_item(a_ledger, &l_tx_cur_hash, l_out_idx_tmp, NULL))
continue; // TODO Move this check to dap_ledger_tx_find_by_addr() to avoid double search
dap_chain_tx_used_out_item_t *l_item = DAP_NEW_Z(dap_chain_tx_used_out_item_t);
*l_item = (dap_chain_tx_used_out_item_t) { l_tx_cur_hash, (uint32_t)l_out_idx_tmp, l_out_cond->header.value };
l_list_used_out = dap_list_append(l_list_used_out, l_item);
}
int l_out_idx;
dap_chain_tx_out_cond_t *l_cond;
while ( (l_cond = dap_ledger_out_cond_unspent_find_by_addr(a_ledger, a_token_ticker, a_subtype, a_addr_from, &l_tx_cur_hash, &l_out_idx)) ) {
dap_chain_tx_used_out_item_t *l_item = DAP_NEW_Z(dap_chain_tx_used_out_item_t);
*l_item = (dap_chain_tx_used_out_item_t) { l_tx_cur_hash, (uint32_t)l_out_idx, l_cond->header.value };
l_list_used_out = dap_list_append(l_list_used_out, l_item);
}
return l_list_used_out;
}
bool dap_ledger_check_condition_owner(dap_ledger_t *a_ledger, dap_hash_fast_t *a_tx_hash, dap_chain_tx_out_cond_subtype_t a_cond_subtype,
int a_out_idx, dap_sign_t *a_owner_sign)
{
dap_return_val_if_fail(a_ledger && a_tx_hash && a_owner_sign, false);
// Get first tx
dap_chain_datum_tx_t *l_check_tx = dap_ledger_tx_find_by_hash(a_ledger, a_tx_hash);
if (!l_check_tx) {
log_it(L_ERROR, "Can't find tx %s", dap_hash_fast_to_str_static(a_tx_hash));
return false;
}
if (!dap_chain_datum_tx_out_cond_get(l_check_tx, a_cond_subtype, NULL)) {
log_it(L_ERROR, "Can't find owner for tx %s", dap_hash_fast_to_str_static(a_tx_hash));
return false;
}
dap_hash_fast_t l_first_tx_hash = dap_ledger_get_first_chain_tx_hash(a_ledger, a_cond_subtype, a_tx_hash);
dap_chain_datum_tx_t *l_first_tx = dap_hash_fast_is_blank(&l_first_tx_hash) ? l_check_tx
: dap_ledger_tx_find_by_hash(a_ledger, &l_first_tx_hash);
if (!l_first_tx) {
log_it(L_ERROR, "Can't find owner tx %s", dap_hash_fast_to_str_static(&l_first_tx_hash));
return false;
}
dap_chain_tx_sig_t *l_first_tx_sig = (dap_chain_tx_sig_t *)dap_chain_datum_tx_item_get(l_first_tx, NULL, NULL, TX_ITEM_TYPE_SIG, NULL);
dap_sign_t *l_sign = dap_chain_datum_tx_item_sig_get_sign((dap_chain_tx_sig_t *)l_first_tx_sig);
if (!l_sign) {
log_it(L_ERROR, "Can't find signature for tx %s", dap_hash_fast_to_str_static(&l_first_tx_hash));
return false;
}
return dap_sign_compare_pkeys(a_owner_sign, l_sign);
}
bool dap_ledger_cache_enabled(dap_ledger_t *a_ledger)
{
return is_ledger_cached(PVT(a_ledger));
......
......@@ -670,8 +670,11 @@ const char *l_ban_addr;
return -105;
}
l_policy = DAP_DUP_SIZE_RET_VAL_IF_FAIL(l_policy, dap_chain_policy_get_size(l_policy), -106);
if (DAP_FLAG_CHECK(l_policy->activate.flags, DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_BLOCK_NUM))
l_policy->activate.chain_union.chain = dap_chain_find_by_id(a_net->pub.id, l_policy->activate.chain_union.chain_id);
if (l_policy->type == DAP_CHAIN_POLICY_ACTIVATE) {
dap_chain_policy_activate_t *l_policy_activate = (dap_chain_policy_activate_t *)l_policy->data;
if(DAP_FLAG_CHECK(l_policy_activate->flags, DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_BLOCK_NUM))
l_policy_activate->chain_union.chain = dap_chain_find_by_id(a_net->pub.id, l_policy_activate->chain_union.chain_id);
}
return dap_chain_policy_add(l_policy, a_net->pub.id.uint64);
}
default:
......
This diff is collapsed.
......@@ -47,10 +47,21 @@ typedef struct dap_ledger {
void *_internal;
} dap_ledger_t;
typedef struct dap_ledger_tracker_item {
dap_hash_fast_t pkey_hash;
uint256_t coloured_value;
struct dap_ledger_tracker_item *prev, *next;
} dap_ledger_tracker_item_t;
typedef struct dap_ledger_tracker {
dap_hash_fast_t voting_hash;
uint256_t colored_value;
} DAP_ALIGN_PACKED dap_ledger_tracker_t;
dap_ledger_tracker_item_t *items;
} dap_ledger_tracker_t;
typedef struct dap_ledger_hardfork_tracker {
dap_hash_fast_t pkey_hash;
uint256_t coloured_value;
} DAP_ALIGN_PACKED dap_ledger_hardfork_tracker_t;
typedef struct dap_ledger_hardfork_balances {
dap_chain_addr_t addr;
......@@ -290,7 +301,8 @@ typedef void (*dap_ledger_cond_out_delete_callback_t)(dap_ledger_t *a_ledger, da
typedef void (* dap_ledger_tx_add_notify_t)(void *a_arg, dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_ledger_notify_opcodes_t a_opcode);
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, dap_ledger_notify_opcodes_t a_opcode);
typedef bool (*dap_ledger_cache_tx_check_callback_t)(dap_ledger_t *a_ledger, dap_hash_fast_t *a_tx_hash);
typedef int (*dap_ledger_voting_callback_t)(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_type, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, bool a_apply);
typedef int (*dap_ledger_voting_callback_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, bool a_apply);
typedef int (*dap_ledger_vote_callback_t)(dap_ledger_t *a_ledger, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash, dap_hash_fast_t *a_pkey_hash, bool a_apply);
typedef bool (*dap_ledger_voting_delete_callback_t)(dap_ledger_t *a_ledger, dap_chain_tx_item_type_t a_type, dap_chain_datum_tx_t *a_tx, dap_hash_fast_t *a_tx_hash);
typedef dap_time_t (*dap_ledger_voting_expire_callback_t)(dap_ledger_t *a_ledger, dap_hash_fast_t *a_voting_hash);
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);
......@@ -445,38 +457,29 @@ dap_chain_datum_tx_t* dap_ledger_tx_find_by_addr(dap_ledger_t *a_ledger, const c
bool dap_ledger_tx_check_recipient(dap_ledger_t* a_ledger, dap_chain_hash_fast_t* a_tx_prev_hash, dap_chain_addr_t *a_addr);
// Get the transaction in the cache by the public key that signed the transaction, starting with a_tx_first_hash
const dap_chain_datum_tx_t* dap_ledger_tx_find_by_pkey(dap_ledger_t *a_ledger,
char *a_public_key, size_t a_public_key_size, dap_chain_hash_fast_t *a_tx_first_hash);
// Get the transaction in the cache with the out_cond item
dap_chain_datum_tx_t* dap_ledger_tx_cache_find_out_cond(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_t a_cond_type,
dap_chain_hash_fast_t *a_tx_first_hash, dap_chain_tx_out_cond_t **a_out_cond,
int *a_out_cond_idx, char *a_token_ticker);
// Get all transactions from the cache with the specified out_cond items
dap_list_t* dap_ledger_tx_cache_find_out_cond_all(dap_ledger_t *a_ledger, dap_chain_srv_uid_t a_srv_uid);
// Get the value from all transactions in the cache with out_cond item
uint256_t dap_ledger_tx_cache_get_out_cond_value(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_t a_cond_type, dap_chain_addr_t *a_addr,
dap_chain_tx_out_cond_t **tx_out_cond);
// Get first tx with type a_subtype
dap_chain_tx_used_out_item_t *dap_ledger_get_tx_cond_out(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr_from, dap_chain_tx_out_cond_subtype_t a_subtype);
dap_chain_tx_out_cond_t *dap_ledger_out_cond_unspent_find_by_addr(dap_ledger_t *a_ledger, const char *a_token, dap_chain_tx_out_cond_subtype_t a_subtype,
const dap_chain_addr_t *a_addr, dap_chain_hash_fast_t *a_tx_first_hash, int *a_out_idx);
dap_list_t *dap_ledger_get_list_tx_outs(dap_ledger_t *a_ledger, const char *a_token_ticker, const dap_chain_addr_t *a_addr_from,
uint256_t *a_value_transfer);
// Get the list of 'out_cond' items with summary value >= than a_value_need
dap_list_t *dap_ledger_get_list_tx_cond_outs_with_val(dap_ledger_t *a_ledger, const char *a_token_ticker, const dap_chain_addr_t *a_addr_from,
dap_chain_tx_out_cond_subtype_t a_subtype, uint256_t a_value_need, uint256_t *a_value_transfer);
dap_list_t *dap_ledger_get_list_tx_cond_outs(dap_ledger_t *a_ledger, const dap_chain_addr_t *a_addr_from);
dap_list_t *dap_ledger_get_list_tx_cond_outs(dap_ledger_t *a_ledger, dap_chain_tx_out_cond_subtype_t a_subtype, const char *a_token_ticker, const dap_chain_addr_t *a_addr_from);
bool dap_ledger_check_condition_owner(dap_ledger_t *a_ledger, dap_hash_fast_t *a_tx_hash, dap_chain_tx_out_cond_subtype_t a_cond_subtype, int a_out_idx, dap_sign_t *a_owner_sign);
// Add new verificator callback with associated subtype. Returns 1 if callback replaced, overwise returns 0
int dap_ledger_verificator_add(dap_chain_tx_out_cond_subtype_t a_subtype,
dap_ledger_cond_in_verify_callback_t a_callback_in_verify, dap_ledger_cond_out_verify_callback_t a_callback_out_verify,
dap_ledger_cond_in_add_callback_t a_callback_in_add, dap_ledger_cond_out_add_callback_t a_callback_out_add,
dap_ledger_cond_in_delete_callback_t a_callback_in_delete, dap_ledger_cond_out_delete_callback_t a_callback_out_delete);
// Add new verificator callback for voting. Returns 1 if callback replaced, overwise returns 0
int dap_ledger_voting_verificator_add(dap_ledger_voting_callback_t a_callback, dap_ledger_voting_delete_callback_t a_callback_delete, dap_ledger_voting_expire_callback_t a_callback_expire);
int dap_ledger_voting_verificator_add(dap_ledger_voting_callback_t a_voting_callback, dap_ledger_vote_callback_t a_vote_callback,
dap_ledger_voting_delete_callback_t a_callback_delete, dap_ledger_voting_expire_callback_t a_callback_expire);
int dap_ledger_tax_callback_set(dap_ledger_tax_callback_t a_callback);
// Getting a list of transactions from the ledger.
dap_list_t * dap_ledger_get_txs(dap_ledger_t *a_ledger, size_t a_count, size_t a_page, bool a_reverse, bool a_unspent_only);
......@@ -521,9 +524,12 @@ int dap_ledger_anchor_purge(dap_ledger_t *a_ledger, dap_chain_id_t a_chain_id);
dap_ledger_hardfork_balances_t *dap_ledger_states_aggregate(dap_ledger_t *a_ledger, dap_time_t a_hardfork_decree_creation_time, dap_ledger_hardfork_condouts_t **l_cond_outs_list, json_object* a_changed_addrs);
dap_ledger_hardfork_anchors_t *dap_ledger_anchors_aggregate(dap_ledger_t *a_ledger, dap_chain_id_t a_chain_id);
uint256_t dap_ledger_coin_get_uncoloured_value(dap_ledger_t *a_ledger, dap_hash_fast_t *a_voting_hash, dap_hash_fast_t *a_tx_hash, int a_out_idx);
uint256_t dap_ledger_coin_get_uncoloured_value(dap_ledger_t *a_ledger, dap_hash_fast_t *a_voting_hash,
dap_hash_fast_t *a_tx_hash, int a_out_idx, dap_hash_fast_t *a_pkey_hash);
dap_list_t *dap_ledger_tx_get_trackers(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_tx_hash, uint32_t a_out_idx);
void dap_ledger_tx_clear_colour(dap_ledger_t *a_ledger, dap_hash_fast_t *a_tx_hash);
void dap_ledger_colour_clear_callback(void *a_list_data);
dap_pkey_t *dap_ledger_find_pkey_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_pkey_hash);
dap_list_t *dap_ledger_decrees_get_by_type(dap_ledger_t *a_ledger, int a_type);
......
......@@ -774,19 +774,30 @@ static dap_chain_net_t *s_net_new(const char *a_net_name, dap_config_t *a_cfg)
return NULL;
}
// activate policy
uint32_t l_policy_num = dap_config_get_item_uint32(a_cfg, "policy", "activate");
uint64_t l_policy_num = dap_config_get_item_uint64(a_cfg, "policy", "activate");
dap_chain_policy_t *l_new_policy = NULL;
if (l_policy_num) {
dap_chain_policy_t *l_new_policy = DAP_NEW_Z_RET_VAL_IF_FAIL(dap_chain_policy_t, NULL, l_ret->pub.name, l_ret);
l_new_policy->version = DAP_CHAIN_POLICY_VERSION;
l_new_policy->activate.num = l_policy_num;
l_new_policy->activate.flags = DAP_FLAG_ADD(l_new_policy->activate.flags, DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_CONFIG);
dap_chain_policy_add(l_new_policy, l_ret->pub.id.uint64);
if (!dap_chain_policy_num_is_valid(l_policy_num)) {
log_it(L_ERROR, "Can't add policy CN-%"DAP_UINT64_FORMAT_U, l_policy_num);
} else {
dap_chain_policy_t *l_new_policy = NULL;
l_new_policy = DAP_NEW_Z_SIZE_RET_VAL_IF_FAIL(dap_chain_policy_t, dap_chain_policy_activate_calc_size(), NULL, l_ret->pub.name, l_ret);
l_new_policy->version = DAP_CHAIN_POLICY_VERSION;
((dap_chain_policy_activate_t *)(l_new_policy->data))->num = l_policy_num;
((dap_chain_policy_activate_t *)(l_new_policy->data))->flags = DAP_FLAG_ADD(((dap_chain_policy_activate_t *)(l_new_policy->data))->flags, DAP_CHAIN_POLICY_FLAG_ACTIVATE_BY_CONFIG);
dap_chain_policy_add(l_new_policy, l_ret->pub.id.uint64);
}
}
// deactivate policy
uint16_t l_policy_count = 0;
const char **l_policy_str = dap_config_get_array_str(a_cfg, "policy", "deactivate", &l_policy_count);
for (uint16_t i = 0; i < l_policy_count; ++i) {
dap_chain_policy_add_to_exception_list(strtoll(l_policy_str[i], NULL, 10), l_ret->pub.id.uint64);
l_policy_num = strtoull(l_policy_str[i], NULL, 10);
if (!dap_chain_policy_num_is_valid(l_policy_num)) {
log_it(L_ERROR, "Can't add policy CN-%"DAP_UINT64_FORMAT_U" to exception list", l_policy_num);
} else {
dap_chain_policy_add_to_exception_list(l_policy_num, l_ret->pub.id.uint64);
}
}
l_ret->pub.config = a_cfg;
......@@ -2122,7 +2133,7 @@ static void *s_net_load(void *a_arg)
l_net->pub.name, dap_guuid_compose(l_net->pub.id.uint64, 0),
l_net->pub.gdb_nodes, 7200, true,
DAP_GDB_MEMBER_ROLE_GUEST,
DAP_CLUSTER_TYPE_EMBEDDED); // TODO 7200
DAP_CLUSTER_TYPE_EMBEDDED);
dap_return_val_if_fail_err(l_net_pvt->nodes_cluster, NULL, "Net \"%s\" loading error %d: can't initialize nodes cluster",
l_net->pub.name, -6);
dap_chain_net_add_auth_nodes_to_cluster(l_net, l_net_pvt->nodes_cluster);
......@@ -3005,7 +3016,6 @@ static void s_ch_out_pkt_callback(dap_stream_ch_t *a_ch, uint8_t a_type, const v
default:
break;
}
l_net_pvt->sync_context.stage_last_activity = dap_time_now();
debug_if(s_debug_more, L_DEBUG, "Sent OUT sync packet type %hhu size %zu to addr " NODE_ADDR_FP_STR,
a_type, a_data_size, NODE_ADDR_FP_ARGS_S(a_ch->stream->node));
}
......
......@@ -543,28 +543,36 @@ void dap_chain_net_balancer_request(void *a_arg)
* @param a_net - net to report
* @return if error NULL, other - report
*/
dap_string_t *dap_chain_net_balancer_get_node_str(dap_chain_net_t *a_net)
json_object *dap_chain_net_balancer_get_node_str(dap_chain_net_t *a_net)
{
// sanity check
dap_return_val_if_pass(!a_net, NULL);
// func work
json_object *l_jobj_out = json_object_new_object();
if (!l_jobj_out) return dap_json_rpc_allocation_put(l_jobj_out);
json_object *l_jobj_list_array = json_object_new_array();
if (!l_jobj_list_array) return dap_json_rpc_allocation_put(l_jobj_out);
json_object_object_add(l_jobj_out, "links_list", l_jobj_list_array);
dap_net_links_t *l_links_info_list = s_get_node_addrs(a_net, 0, NULL, false); // TODO
dap_string_t *l_ret = dap_string_new(
"-----------------------------------------------------------------\n"
"|\t\tNode addr\t|\tHost addr\t\t|\n"
"--Send in balancer http response---------------------------------\n");
uint64_t l_node_num = l_links_info_list ? l_links_info_list->count_node : 0;
for (uint64_t i = 0; i < l_node_num; ++i) {
dap_link_info_t *l_link_info = (dap_link_info_t *)l_links_info_list->nodes_info + i;
dap_string_append_printf(l_ret, "|\t"NODE_ADDR_FP_STR"\t|\t%-16s:%u\t|\n",
NODE_ADDR_FP_ARGS_S(l_link_info->node_addr),
l_link_info->uplink_addr, l_link_info->uplink_port);
json_object *l_jobj_link = json_object_new_object();
if (!l_jobj_link) return dap_json_rpc_allocation_put(l_jobj_out);
char * l_node_addr = dap_strdup_printf(""NODE_ADDR_FP_STR"",NODE_ADDR_FP_ARGS_S(l_link_info->node_addr));
json_object_object_add(l_jobj_link, "node_addr", json_object_new_string(l_node_addr));
DAP_DELETE(l_node_addr);
char * l_uplink_addr = dap_strdup_printf("%-16s", l_link_info->uplink_addr);
json_object_object_add(l_jobj_link, "host_addr", json_object_new_string(l_uplink_addr));
DAP_DELETE(l_uplink_addr);
json_object_object_add(l_jobj_link, "port", json_object_new_uint64(l_link_info->uplink_port));
if(i + 1 == s_max_links_response_count && i + 1 < l_node_num) {
dap_string_append_printf(l_ret, "--Not send in http balancer response-----------------------------\n");
json_object_object_add(l_jobj_link, "status", json_object_new_string("Not send in http balancer response"));
}
json_object_array_add(l_jobj_list_array, l_jobj_link);
}
dap_string_prepend_printf(l_ret, "Balancer link list for total %" DAP_UINT64_FORMAT_U " records:\n", l_node_num);
dap_string_append(l_ret, "-----------------------------------------------------------------\n");
json_object_object_add(l_jobj_out, "links total", json_object_new_uint64(l_node_num));
DAP_DELETE(l_links_info_list);
return l_ret;
return l_jobj_out;
}
......@@ -1657,7 +1657,7 @@ int dap_chain_net_tx_to_json(dap_chain_datum_tx_t *a_tx, json_object *a_out_json
json_object_object_add(json_obj_item,"type", json_object_new_string("voting"));
json_object_object_add(json_obj_item,"voting_question", json_object_new_string(l_voting_params->question));
json_object_object_add(json_obj_item,"answer_options", json_object_new_string(""));
json_object_object_add(json_obj_item, "token", json_object_new_string(l_voting_params->token_ticker));
dap_list_t *l_temp = l_voting_params->options;
uint8_t l_index = 0;
while (l_temp) {
......@@ -1672,12 +1672,10 @@ int dap_chain_net_tx_to_json(dap_chain_datum_tx_t *a_tx, json_object *a_out_json
if (l_voting_params->votes_max_count) {
json_object_object_add(json_obj_item, "votes_max_count", json_object_new_uint64(l_voting_params->votes_max_count));
}
json_object_object_add(json_obj_item,"changing_vote_is", l_voting_params->vote_changing_allowed ? json_object_new_string("available") :
json_object_new_string("not available"));
l_voting_params->delegate_key_required ?
json_object_object_add(json_obj_item,"delegated_key_for_participating_in_voting", json_object_new_string("required")):
json_object_object_add(json_obj_item,"delegated_key_for_participating_in_voting", json_object_new_string("not required"));
json_object_object_add(json_obj_item, "changing_vote_is",
json_object_new_string(l_voting_params->vote_changing_allowed ? "available" : "not available"));
json_object_object_add(json_obj_item, "delegated_key_for_participating_in_voting",
json_object_new_string(l_voting_params->delegate_key_required ? "required" : "not required"));
dap_list_free_full(l_voting_params->options, NULL);
DAP_DELETE(l_voting_params->question);
DAP_DELETE(l_voting_params);
......