From b79d87baf8b40a6d86e0864f269ed50e4ed4199f Mon Sep 17 00:00:00 2001 From: Aleksandr Lysikov <lysikov@inbox.ru> Date: Mon, 8 Apr 2019 12:23:43 +0500 Subject: [PATCH] added support for binary data --- dap_chain_global_db.c | 78 ++++++++++++------- dap_chain_global_db.h | 12 ++- dap_chain_global_db_hist.c | 44 ++++++++++- dap_chain_global_db_pvt.c | 141 ++++++++++++++++++++--------------- dap_chain_global_db_pvt.h | 9 ++- dap_chain_global_db_remote.c | 35 +++++++++ dap_chain_global_db_remote.h | 10 +++ 7 files changed, 234 insertions(+), 95 deletions(-) create mode 100644 dap_chain_global_db_remote.c create mode 100644 dap_chain_global_db_remote.h diff --git a/dap_chain_global_db.c b/dap_chain_global_db.c index 83710a1..8d365ed 100644 --- a/dap_chain_global_db.c +++ b/dap_chain_global_db.c @@ -2,8 +2,11 @@ #include <stdio.h> #include <stdint.h> #include <pthread.h> +#include <time.h> + #include "dap_hash.h" #include "dap_chain_common.h" +#include "dap_strfuncs.h" #include "dap_chain_global_db_pvt.h" #include "dap_chain_global_db_hist.h" #include "dap_chain_global_db.h" @@ -16,7 +19,7 @@ static pthread_mutex_t ldb_mutex = PTHREAD_MUTEX_INITIALIZER; */ static bool is_local_group(const char *a_group) { - if(!strcmp(a_group, GROUP_ALIAS)) + if(!strcmp(a_group, GROUP_ALIAS) || !strcmp(a_group, GROUP_REMOTE_NODE)) return true; return false; } @@ -79,8 +82,8 @@ void dap_chain_global_db_deinit(void) /** * Get entry from base * + * return dap_store_obj_t* */ - void* dap_chain_global_db_obj_get(const char *a_key, const char *a_group) { int count = 0; @@ -90,46 +93,52 @@ void* dap_chain_global_db_obj_get(const char *a_key, const char *a_group) char *query = DAP_NEW_Z_SIZE(char, query_len + 1); //char query[32 + strlen(a_key)]; snprintf(query, query_len + 1, "(&(cn=%s)(objectClass=%s))", a_key, a_group); // objectClass != ou pthread_mutex_lock(&ldb_mutex); - pdap_store_obj_t store_data = dap_db_read_data(query, &count, a_group); + dap_store_obj_t *store_data = dap_db_read_data(query, &count, a_group); pthread_mutex_unlock(&ldb_mutex); assert(count <= 1); DAP_DELETE(query); return store_data; } -char * dap_chain_global_db_gr_get(const char *a_key, const char *a_group) +uint8_t * dap_chain_global_db_gr_get(const char *a_key, size_t *a_data_out, const char *a_group) { - char *str = NULL; - int count = 0; + uint8_t *l_ret_value = NULL; + int l_count = 0; if(!a_key) return NULL; - size_t query_len = snprintf(NULL, 0, "(&(cn=%s)(objectClass=%s))", a_key, a_group); - char *query = DAP_NEW_Z_SIZE(char, query_len + 1); //char query[32 + strlen(a_key)]; - snprintf(query, query_len + 1, "(&(cn=%s)(objectClass=%s))", a_key, a_group); // objectClass != ou + size_t l_query_len = snprintf(NULL, 0, "(&(cn=%s)(objectClass=%s))", a_key, a_group); + char *l_query = DAP_NEW_Z_SIZE(char, l_query_len + 1); //char query[32 + strlen(a_key)]; + snprintf(l_query, l_query_len + 1, "(&(cn=%s)(objectClass=%s))", a_key, a_group); // objectClass != ou pthread_mutex_lock(&ldb_mutex); - pdap_store_obj_t store_data = dap_db_read_data(query, &count, a_group); + pdap_store_obj_t store_data = dap_db_read_data(l_query, &l_count, a_group); pthread_mutex_unlock(&ldb_mutex); - if(count == 1 && store_data && !strcmp(store_data->key, a_key)) - str = (store_data->value) ? strdup(store_data->value) : NULL; - dab_db_free_pdap_store_obj_t(store_data, count); - DAP_DELETE(query); - return str; + if(l_count == 1 && store_data && !strcmp(store_data->key, a_key)) { + l_ret_value = (store_data->value) ? DAP_NEW_SIZE(uint8_t, store_data->value_len) : NULL; //ret_value = (store_data->value) ? strdup(store_data->value) : NULL; + memcpy(l_ret_value, store_data->value, store_data->value_len); + if(a_data_out) + *a_data_out = store_data->value_len; + } + dab_db_free_pdap_store_obj_t(store_data, l_count); + DAP_DELETE(l_query); + return l_ret_value; } -char * dap_chain_global_db_get(const char *a_key) +uint8_t * dap_chain_global_db_get(const char *a_key, size_t *a_data_out) { - return dap_chain_global_db_gr_get(a_key, GROUP_NAME_DEFAULT); + return dap_chain_global_db_gr_get(a_key, a_data_out, GROUP_NAME_DEFAULT); } /** * Set one entry to base */ -bool dap_chain_global_db_gr_set(const char *a_key, const char *a_value, const char *a_group) +bool dap_chain_global_db_gr_set(const char *a_key, const uint8_t *a_value, size_t a_value_len, const char *a_group) { pdap_store_obj_t store_data = DAP_NEW_Z_SIZE(dap_store_obj_t, sizeof(struct dap_store_obj)); store_data->key = (char*) a_key; store_data->value = (char*) a_value; + store_data->value_len = (a_value_len == (size_t) -1) ? strlen(a_value) : a_value_len; store_data->group = (char*) a_group; + store_data->timestamp = time(NULL); pthread_mutex_lock(&ldb_mutex); int res = dap_db_add(store_data, 1); if(!res && !is_local_group(a_group)) @@ -141,9 +150,9 @@ bool dap_chain_global_db_gr_set(const char *a_key, const char *a_value, const ch return false; } -bool dap_chain_global_db_set(const char *a_key, const char *a_value) +bool dap_chain_global_db_set(const char *a_key, const uint8_t *a_value, size_t a_value_len) { - return dap_chain_global_db_gr_set(a_key, a_value, GROUP_NAME_DEFAULT); + return dap_chain_global_db_gr_set(a_key, a_value, a_value_len, GROUP_NAME_DEFAULT); } /** * Delete entry from base @@ -189,7 +198,7 @@ dap_global_db_obj_t** dap_chain_global_db_gr_load(const char *a_group, size_t *a pthread_mutex_unlock(&ldb_mutex); DAP_DELETE(query); // Serialization data - dap_store_obj_pkt_t *pkt = dap_store_packet_multiple(store_obj, count); + dap_store_obj_pkt_t *pkt = dap_store_packet_multiple(store_obj, 0, count); dab_db_free_pdap_store_obj_t(store_obj, count); if(pkt) { @@ -228,10 +237,26 @@ dap_global_db_obj_t** dap_chain_global_db_load(size_t *a_data_size_out) */ bool dap_chain_global_db_obj_save(void* a_store_data, size_t a_objs_count) { - dap_store_obj_t* l_store_data = (dap_store_obj_t*)a_store_data; - if(l_store_data && a_objs_count>0) - { + dap_store_obj_t* l_store_data = (dap_store_obj_t*) a_store_data; + if(l_store_data && a_objs_count > 0) { const char *l_group = l_store_data[0].group; + // read data + for(int i = 0; i < a_objs_count; i++) { + dap_store_obj_t* l_obj = l_store_data + i; + int l_count = 0; + char *l_query = dap_strdup_printf("(&(cn=%s)(objectClass=%s))", l_obj->key, l_obj->group); + pthread_mutex_lock(&ldb_mutex); + dap_store_obj_t *l_read_store_data = dap_db_read_data(l_query, &l_count, l_group); + pthread_mutex_unlock(&ldb_mutex); + // don't save obj if (present timestamp) > (new timestamp) + if(l_read_store_data && l_count == 1 && l_read_store_data->timestamp > l_obj->timestamp){ + // mark to not save + l_obj->timestamp = (time_t)-1; + } + DAP_DELETE(l_query); + } + + // save data pthread_mutex_lock(&ldb_mutex); int res = dap_db_add(l_store_data, a_objs_count); if(!res && !is_local_group(l_group)) @@ -252,12 +277,15 @@ bool dap_chain_global_db_gr_save(dap_global_db_obj_t* a_objs, size_t a_objs_coun //pdap_store_obj_t store_data = dap_store_unpacket(pkt, &count); //DAP_DELETE(pkt); dap_store_obj_t *store_data = DAP_NEW_Z_SIZE(dap_store_obj_t, a_objs_count * sizeof(struct dap_store_obj)); + time_t l_timestamp = time(NULL); for(size_t q = 0; q < a_objs_count; ++q) { dap_store_obj_t *store_data_cur = store_data + q; dap_global_db_obj_t *a_obj_cur = a_objs + q; store_data_cur->key = a_obj_cur->key; - store_data_cur->value = a_obj_cur->value; store_data_cur->group = (char*) a_group; + store_data_cur->value = a_obj_cur->value; + store_data_cur->value_len = a_obj_cur->value_len; + store_data_cur->timestamp = l_timestamp; } if(store_data) { diff --git a/dap_chain_global_db.h b/dap_chain_global_db.h index ef3ab4e..cfcd953 100644 --- a/dap_chain_global_db.h +++ b/dap_chain_global_db.h @@ -10,12 +10,14 @@ #define GROUP_NODE "addrs_leased" #define GROUP_ALIAS "aliases_leased" #define GROUP_DATUM "datums" +#define GROUP_REMOTE_NODE "remote_node" #define GROUP_NAME_DEFAULT GROUP_DATUM typedef struct dap_global_db_obj { char *key; char *value; + size_t value_len; }DAP_ALIGN_PACKED dap_global_db_obj_t, *pdap_global_db_obj_t; /** @@ -40,14 +42,14 @@ void dap_chain_global_db_deinit(); * Get entry from base */ void* dap_chain_global_db_obj_get(const char *a_key, const char *a_group); -char * dap_chain_global_db_gr_get(const char *a_key, const char *a_group); -char* dap_chain_global_db_get(const char *a_key); +uint8_t * dap_chain_global_db_gr_get(const char *a_key, size_t *a_data_out, const char *a_group); +uint8_t * dap_chain_global_db_get(const char *a_key, size_t *a_data_out); /** * Set one entry to base */ -bool dap_chain_global_db_gr_set(const char *a_key, const char *a_value, const char *a_group); -bool dap_chain_global_db_set(const char *a_key, const char *a_value); +bool dap_chain_global_db_gr_set(const char *a_key, const uint8_t *a_value, size_t a_value_len, const char *a_group); +bool dap_chain_global_db_set(const char *a_key, const uint8_t *a_value, size_t a_value_len); /** * Delete entry from base @@ -85,6 +87,8 @@ char* dap_chain_global_db_hash_fast(const uint8_t *data, size_t data_size); uint8_t* dap_db_log_pack(dap_global_db_obj_t *a_obj, int *a_data_size_out); // Parse data from dap_db_log_pack() void* dap_db_log_unpack(uint8_t *a_data, int a_data_size, int *a_store_obj_count); +// Get timestamp from dap_db_log_pack() +time_t dap_db_log_unpack_get_timestamp(uint8_t *a_data, int a_data_size); // Get last timestamp in log char *dap_db_log_get_last_timestamp(void); diff --git a/dap_chain_global_db_hist.c b/dap_chain_global_db_hist.c index 9ef5a98..795c97e 100644 --- a/dap_chain_global_db_hist.c +++ b/dap_chain_global_db_hist.c @@ -1,5 +1,6 @@ #include <string.h> #include <stdlib.h> +#include <time.h> #include <dap_common.h> #include <dap_strfuncs.h> @@ -50,6 +51,8 @@ uint8_t* dap_db_log_pack(dap_global_db_obj_t *a_obj, int *a_data_size_out) dap_global_db_hist_t l_rec; if(dap_db_history_unpack_hist(a_obj->value, &l_rec) == -1) return NULL; + time_t l_timestamp = strtoll(a_obj->key, NULL, 10); + // parse global_db records in a history record char **l_keys = dap_strsplit(l_rec.keys, HIST_KEY_SEPARATOR, -1); int l_count = dap_str_countv(l_keys); @@ -64,7 +67,7 @@ uint8_t* dap_db_log_pack(dap_global_db_obj_t *a_obj, int *a_data_size_out) i++; }; // serialize data - dap_store_obj_pkt_t *l_data_out = dap_store_packet_multiple(l_store_obj, l_count); + dap_store_obj_pkt_t *l_data_out = dap_store_packet_multiple(l_store_obj, l_timestamp, l_count); dab_db_free_pdap_store_obj_t(l_store_obj, l_count); dap_strfreev(l_keys); @@ -93,6 +96,17 @@ void* dap_db_log_unpack(uint8_t *a_data, int a_data_size, int *a_store_obj_count return l_obj; } +/** + * Get timestamp from dap_db_log_pack() + */ +time_t dap_db_log_unpack_get_timestamp(uint8_t *a_data, int a_data_size) +{ + dap_store_obj_pkt_t *l_pkt = (dap_store_obj_pkt_t*) a_data; + if(!l_pkt || l_pkt->data_size != (a_data_size - sizeof(dap_store_obj_pkt_t))) + return 0; + return l_pkt->timestamp; +} + /** * Add data to the history log */ @@ -103,16 +117,19 @@ bool dap_db_history_add(char a_type, pdap_store_obj_t a_store_obj, int a_dap_sto dap_global_db_hist_t l_rec; l_rec.keys_count = a_dap_store_count; l_rec.type = a_type; - // TODO Make for keys_count>1 + // group name should be always the same if(l_rec.keys_count >= 1) l_rec.group = a_store_obj->group; if(l_rec.keys_count == 1) l_rec.keys = a_store_obj->key; else { // make keys vector - char **l_keys = DAP_NEW_SIZE(char*, sizeof(char*) * (a_dap_store_count + 1)); + char **l_keys = DAP_NEW_Z_SIZE(char*, sizeof(char*) * (a_dap_store_count + 1)); int i; for(i = 0; i < a_dap_store_count; i++) { + // if it is marked, the data has not been saved + if(a_store_obj[i].timestamp == (time_t) -1) + continue; l_keys[i] = a_store_obj[i].key; } l_keys[i] = NULL; @@ -127,7 +144,9 @@ bool dap_db_history_add(char a_type, pdap_store_obj_t a_store_obj, int a_dap_sto // value - keys of added/deleted data l_store_data.key = dap_db_history_timestamp(); l_store_data.value = (char*) l_str; + l_store_data.value_len = l_str_len; l_store_data.group = GROUP_HISTORY; + l_store_data.timestamp = time(NULL); int l_res = dap_db_add(&l_store_data, 1); if(l_rec.keys_count > 1) DAP_DELETE(l_rec.keys); @@ -168,6 +187,14 @@ char *dap_db_log_get_last_timestamp(void) return l_ret_str; } +static int compare_items(const void * l_a, const void * l_b) +{ + dap_global_db_obj_t *l_item_a = (dap_global_db_obj_t*) l_a; + dap_global_db_obj_t *l_item_b = (dap_global_db_obj_t*) l_b; + int l_ret = strcmp(l_item_a->key, l_item_b->key); + return l_ret; +} + /** * Get log diff as list */ @@ -186,6 +213,17 @@ dap_list_t* dap_db_log_get_list(time_t first_timestamp) l_list = dap_list_append(l_list, l_item); } } + // sort list by key (time str) + dap_list_sort(l_list, (DapCompareFunc) compare_items); + + /*/ dbg - sort result + l_data_size_out = dap_list_length(l_list); + for(size_t i = 0; i < l_data_size_out; i++) { + dap_list_t *l_list_tmp = dap_list_nth(l_list, i); + dap_global_db_obj_t *l_item = l_list_tmp->data; + printf("2 %d %s\n", i, l_item->key); + }*/ + DAP_DELETE(l_first_key); dap_chain_global_db_objs_delete(l_objs); return l_list; diff --git a/dap_chain_global_db_pvt.c b/dap_chain_global_db_pvt.c index 7a6cac6..d65269d 100644 --- a/dap_chain_global_db_pvt.c +++ b/dap_chain_global_db_pvt.c @@ -1,6 +1,8 @@ #include <string.h> #include <stdio.h> #include <assert.h> +#include <time.h> + //#include "talloc.h" #include "dap_chain_global_db_pvt.h" @@ -194,7 +196,15 @@ pdap_store_obj_t dap_db_read_data(const char *query, int *count, const char *gro store_data[q].group = strdup(ldb_msg_find_attr_as_string(data_message->msgs[q], "objectClass", "")); //strdup(group); store_data[q].type = 1; store_data[q].key = strdup(ldb_msg_find_attr_as_string(data_message->msgs[q], "cn", "")); - store_data[q].value = strdup(ldb_msg_find_attr_as_string(data_message->msgs[q], "time", "")); + store_data[q].timestamp = ldb_msg_find_attr_as_uint64(data_message->msgs[q], "time", 5); + const struct ldb_val *l_val = ldb_msg_find_ldb_val(data_message->msgs[q], "time"); + + l_val = ldb_msg_find_ldb_val(data_message->msgs[q], "val"); + if(l_val) { + store_data[q].value_len = l_val->length; + store_data[q].value = DAP_NEW_SIZE(uint8_t, l_val->length); + memcpy(store_data[q].value, l_val->data, l_val->length); + } log_it(L_INFO, "Record %s read successfully", ldb_dn_get_linearized(data_message->msgs[q]->dn)); } talloc_free(data_message); @@ -272,7 +282,7 @@ pdap_store_obj_t dap_db_read_file_data(const char *path, const char *group) */ int dap_db_add(pdap_store_obj_t a_store_obj, int a_store_count) { - int ret = 0; + int l_ret = 0; if(a_store_obj == NULL) { log_it(L_ERROR, "Invalid Dap store objects passed"); return -1; @@ -281,15 +291,20 @@ int dap_db_add(pdap_store_obj_t a_store_obj, int a_store_count) log_it(L_ERROR, "Couldn't connect to database"); return -2; } - log_it(L_INFO, "We're about to put %d records into database", a_store_count); - struct ldb_message *msg; + //log_it(L_INFO, "We're about to put %d records into database", a_store_count); + struct ldb_message *l_msg; int q; if(a_store_count == 0) { a_store_count = 1; } for(q = 0; q < a_store_count; q++) { // level 3: leased address, single whitelist entity - msg = ldb_msg_new(ldb); + + // if it is marked, don't save + if(a_store_obj[q].timestamp == (time_t) -1) + continue; + + l_msg = ldb_msg_new(ldb); char dn[256]; memset(dn, '\0', 256); strcat(dn, "cn="); @@ -298,17 +313,28 @@ int dap_db_add(pdap_store_obj_t a_store_obj, int a_store_count) strcat(dn, ",ou="); strcat(dn, a_store_obj[q].group); strcat(dn, ",dc=kelvin_nodes"); - msg->dn = ldb_dn_new(mem_ctx, ldb, dn); - ldb_msg_add_string(msg, "cn", a_store_obj[q].key); - ldb_msg_add_string(msg, "objectClass", a_store_obj[q].group); - ldb_msg_add_string(msg, "section", "kelvin_nodes"); - ldb_msg_add_string(msg, "description", "Approved Kelvin node"); - ldb_msg_add_string(msg, "time", a_store_obj[q].value); - ret += dap_db_add_msg(msg); // accumulation error codes - talloc_free(msg->dn); - talloc_free(msg); + l_msg->dn = ldb_dn_new(mem_ctx, ldb, dn); + int l_res = ldb_msg_add_string(l_msg, "cn", a_store_obj[q].key); + ldb_msg_add_string(l_msg, "objectClass", a_store_obj[q].group); + ldb_msg_add_string(l_msg, "section", "kelvin_nodes"); + ldb_msg_add_string(l_msg, "description", "Approved Kelvin node"); + + struct ldb_val l_val; + struct ldb_message_element *return_el; + l_val.data = (uint8_t*) &a_store_obj[q].timestamp; + l_val.length = sizeof(time_t); + l_res = ldb_msg_add_value(l_msg, "time", &l_val, &return_el); + ldb_msg_remove_element(l_msg, return_el); + + l_val.data = a_store_obj[q].value; + l_val.length = a_store_obj[q].value_len; + l_res = ldb_msg_add_steal_value(l_msg, "val", &l_val); + + l_ret += dap_db_add_msg(l_msg); // accumulation error codes + talloc_free(l_msg->dn); + talloc_free(l_msg); } - return ret; + return l_ret; } /* @@ -327,7 +353,7 @@ int dap_db_delete(pdap_store_obj_t store_obj, int a_store_count) log_it(L_ERROR, "Couldn't connect to database"); return -2; } - log_it(L_INFO, "We're delete %d records from database", a_store_count); + //log_it(L_INFO, "We're delete %d records from database", a_store_count); struct ldb_message *msg; int q; if(a_store_count == 0) { @@ -376,60 +402,55 @@ static size_t dap_db_get_size_pdap_store_obj_t(pdap_store_obj_t store_obj) /** * serialization - * @param store_obj_count count of structures store_obj - * @param size_out[out] size of output structure + * @param a_store_obj_count count of structures store_obj + * @param a_timestamp create data time + * @param a_size_out[out] size of output structure * @return NULL in case of an error */ -dap_store_obj_pkt_t *dap_store_packet_multiple(pdap_store_obj_t store_obj, int store_obj_count) +dap_store_obj_pkt_t *dap_store_packet_multiple(pdap_store_obj_t a_store_obj, time_t a_timestamp, int a_store_obj_count) { - if(!store_obj || store_obj_count < 1) + if(!a_store_obj || a_store_obj_count < 1) return NULL; - size_t data_size_out = sizeof(uint32_t); // size of output data - int q; + size_t l_data_size_out = sizeof(uint32_t); // size of output data + int l_q; // calculate output structure size - for(q = 0; q < store_obj_count; ++q) - data_size_out += dap_db_get_size_pdap_store_obj_t(&store_obj[q]); - - dap_store_obj_pkt_t *pkt = DAP_NEW_Z_SIZE(dap_store_obj_pkt_t, sizeof(dap_store_obj_pkt_t) + data_size_out); - /* pkt->grp_size = strlen(store_obj[0].group) + 1; - pkt->name_size = strlen(store_obj[0].key) + 1; // useless here since it can differ from one store_obj to another - pkt->sec_size = strlen(store_obj[0].section) + 1; - pkt->type = store_obj[0].type; - memcpy(pkt->data, &store_obj[0].section, pkt->sec_size); - memcpy(pkt->data + pkt->sec_size, &store_obj[0].group, pkt->grp_size); - uint64_t offset = pkt->sec_size + pkt->grp_size;*/ - pkt->data_size = data_size_out; - uint64_t offset = 0; - uint32_t count = (uint32_t) store_obj_count; - memcpy(pkt->data + offset, &count, sizeof(uint32_t)); - offset += sizeof(uint32_t); - for(q = 0; q < store_obj_count; ++q) { - dap_store_obj_t obj = store_obj[q]; + for(l_q = 0; l_q < a_store_obj_count; ++l_q) + l_data_size_out += dap_db_get_size_pdap_store_obj_t(&a_store_obj[l_q]); + + dap_store_obj_pkt_t *l_pkt = DAP_NEW_Z_SIZE(dap_store_obj_pkt_t, sizeof(dap_store_obj_pkt_t) + l_data_size_out); + l_pkt->data_size = l_data_size_out; + l_pkt->timestamp = a_timestamp; + uint64_t l_offset = 0; + uint32_t l_count = (uint32_t) a_store_obj_count; + memcpy(l_pkt->data + l_offset, &l_count, sizeof(uint32_t)); + l_offset += sizeof(uint32_t); + for(l_q = 0; l_q < a_store_obj_count; ++l_q) { + dap_store_obj_t obj = a_store_obj[l_q]; uint16_t section_size = (uint16_t) strlen(obj.section); uint16_t group_size = (uint16_t) strlen(obj.group); uint16_t key_size = (uint16_t) strlen(obj.key); uint16_t value_size = (uint16_t) strlen(obj.value); - memcpy(pkt->data + offset, &obj.type, sizeof(int)); - offset += sizeof(int); - memcpy(pkt->data + offset, §ion_size, sizeof(uint16_t)); - offset += sizeof(uint16_t); - memcpy(pkt->data + offset, obj.section, section_size); - offset += section_size; - memcpy(pkt->data + offset, &group_size, sizeof(uint16_t)); - offset += sizeof(uint16_t); - memcpy(pkt->data + offset, obj.group, group_size); - offset += group_size; - memcpy(pkt->data + offset, &key_size, sizeof(uint16_t)); - offset += sizeof(uint16_t); - memcpy(pkt->data + offset, obj.key, key_size); - offset += key_size; - memcpy(pkt->data + offset, &value_size, sizeof(uint16_t)); - offset += sizeof(uint16_t); - memcpy(pkt->data + offset, obj.value, value_size); - offset += value_size; + memcpy(l_pkt->data + l_offset, &obj.type, sizeof(int)); + l_offset += sizeof(int); + memcpy(l_pkt->data + l_offset, §ion_size, sizeof(uint16_t)); + l_offset += sizeof(uint16_t); + memcpy(l_pkt->data + l_offset, obj.section, section_size); + l_offset += section_size; + memcpy(l_pkt->data + l_offset, &group_size, sizeof(uint16_t)); + l_offset += sizeof(uint16_t); + memcpy(l_pkt->data + l_offset, obj.group, group_size); + l_offset += group_size; + memcpy(l_pkt->data + l_offset, &key_size, sizeof(uint16_t)); + l_offset += sizeof(uint16_t); + memcpy(l_pkt->data + l_offset, obj.key, key_size); + l_offset += key_size; + memcpy(l_pkt->data + l_offset, &value_size, sizeof(uint16_t)); + l_offset += sizeof(uint16_t); + memcpy(l_pkt->data + l_offset, obj.value, value_size); + l_offset += value_size; } - assert(data_size_out == offset); - return pkt; + assert(l_data_size_out == l_offset); + return l_pkt; } /** * deserialization diff --git a/dap_chain_global_db_pvt.h b/dap_chain_global_db_pvt.h index f9c9952..655e361 100644 --- a/dap_chain_global_db_pvt.h +++ b/dap_chain_global_db_pvt.h @@ -5,11 +5,13 @@ #include "ldb.h" typedef struct dap_store_obj { + time_t timestamp; + uint8_t type; char *section; char *group; char *key; - uint8_t type; - char *value; + uint8_t *value; + size_t value_len; }DAP_ALIGN_PACKED dap_store_obj_t, *pdap_store_obj_t; typedef struct dap_store_obj_pkt { @@ -17,6 +19,7 @@ typedef struct dap_store_obj_pkt { uint8_t sec_size; uint8_t grp_size; uint8_t name_size;*/ + time_t timestamp; size_t data_size; uint8_t data[]; }__attribute__((packed)) dap_store_obj_pkt_t; @@ -30,7 +33,7 @@ int dap_db_delete(pdap_store_obj_t a_store_obj, int a_store_count); pdap_store_obj_t dap_db_read_data(const char *a_query, int *a_count, const char *a_group); pdap_store_obj_t dap_db_read_file_data(const char *a_path, const char *a_group); // state of emergency only, if LDB database is inaccessible dap_store_obj_pkt_t *dap_store_packet_single(pdap_store_obj_t a_store_obj); -dap_store_obj_pkt_t *dap_store_packet_multiple(pdap_store_obj_t a_store_obj, int a_store_obj_count); +dap_store_obj_pkt_t *dap_store_packet_multiple(pdap_store_obj_t a_store_obj, time_t a_timestamp, int a_store_obj_count); dap_store_obj_t *dap_store_unpacket(dap_store_obj_pkt_t *a_pkt, int *a_store_obj_count); void dab_db_free_pdap_store_obj_t(pdap_store_obj_t a_store_data, int a_count); diff --git a/dap_chain_global_db_remote.c b/dap_chain_global_db_remote.c new file mode 100644 index 0000000..69b64ec --- /dev/null +++ b/dap_chain_global_db_remote.c @@ -0,0 +1,35 @@ +#include <string.h> +#include <stdlib.h> + +//#include <dap_common.h> +#include <dap_strfuncs.h> +#include "dap_chain_global_db.h" +#include "dap_chain_global_db_remote.h" + +/** + * Set last timestamp for remote node + */ +bool dap_db_log_set_last_timestamp_remote(uint64_t a_node_addr, time_t a_timestamp) +{ + dap_global_db_obj_t l_objs; + l_objs.key = dap_strdup_printf("%lld", a_node_addr); + l_objs.value = dap_strdup_printf("%lld", a_timestamp); + bool l_ret = dap_chain_global_db_gr_save(&l_objs, 1, GROUP_REMOTE_NODE); + DAP_DELETE(l_objs.key); + DAP_DELETE(l_objs.value); + return l_ret; +} + +/** + * Get last timestamp for remote node + */ +time_t dap_db_log_get_last_timestamp_remote(uint64_t a_node_addr) +{ + char *l_node_addr_str = dap_strdup_printf("%lld", a_node_addr); + size_t l_node_addr_str_len = 0; + char *l_timestamp_str = dap_chain_global_db_gr_get((const char*) l_node_addr_str, &l_node_addr_str_len, GROUP_REMOTE_NODE); + time_t l_ret_timestamp = (l_timestamp_str) ? strtoll(l_timestamp_str, NULL,10) : 0; + DAP_DELETE(l_node_addr_str); + DAP_DELETE(l_timestamp_str); + return l_ret_timestamp; +} diff --git a/dap_chain_global_db_remote.h b/dap_chain_global_db_remote.h new file mode 100644 index 0000000..292b871 --- /dev/null +++ b/dap_chain_global_db_remote.h @@ -0,0 +1,10 @@ +#pragma once + +#include <stdbool.h> +#include <time.h> + +// Set last timestamp for remote node +bool dap_db_log_set_last_timestamp_remote(uint64_t a_node_addr, time_t a_timestamp); +// Get last timestamp for remote node +time_t dap_db_log_get_last_timestamp_remote(uint64_t a_node_addr); + -- GitLab