From 4d156a2fd416f2975c65ad7c025e09ad9fa7e093 Mon Sep 17 00:00:00 2001 From: Dmtiriy Gerasimov <naeper@demlabs.net> Date: Thu, 25 Apr 2019 10:29:56 +0700 Subject: [PATCH] [*] Refactoring, renames, added authors --- client_mempool.c | 24 ++++++ client_mempool.h | 24 ++++++ dap_chain_mempool.c | 204 +++++++++++++++++++++++++++++++++++++++++++- dap_chain_mempool.h | 11 ++- 4 files changed, 258 insertions(+), 5 deletions(-) diff --git a/client_mempool.c b/client_mempool.c index 2a0d93c..bc11f73 100755 --- a/client_mempool.c +++ b/client_mempool.c @@ -1,3 +1,27 @@ +/* + * Authors: + * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net> + * Alexander Lysikov <alexander.lysikov@demlabs.net> + * DeM Labs Inc. https://demlabs.net + * Kelvin Project https://github.com/kelvinblockchain + * Copyright (c) 2017-2019 + * All rights reserved. + + This file is part of DAP (Deus Applications Prototypes) the open source project + + DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + DAP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. +*/ #include <stdlib.h> #include <stdio.h> #include <string.h> diff --git a/client_mempool.h b/client_mempool.h index fd4cd1b..475a02a 100755 --- a/client_mempool.h +++ b/client_mempool.h @@ -1,3 +1,27 @@ +/* + * Authors: + * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net> + * Alexander Lysikov <alexander.lysikov@demlabs.net> + * DeM Labs Inc. https://demlabs.net + * Kelvin Project https://github.com/kelvinblockchain + * Copyright (c) 2017-2019 + * All rights reserved. + + This file is part of DAP (Deus Applications Prototypes) the open source project + + DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + DAP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. +*/ #pragma once #include <pthread.h> diff --git a/dap_chain_mempool.c b/dap_chain_mempool.c index 3d9f797..038eb33 100755 --- a/dap_chain_mempool.c +++ b/dap_chain_mempool.c @@ -1,8 +1,34 @@ +/* + * Authors: + * Dmitriy A. Gearasimov <gerasimov.dmitriy@demlabs.net> + * Alexander Lysikov <alexander.lysikov@demlabs.net> + * DeM Labs Inc. https://demlabs.net + * Kelvin Project https://github.com/kelvinblockchain + * Copyright (c) 2017-2019 + * All rights reserved. + + This file is part of DAP (Deus Applications Prototypes) the open source project + + DAP (Deus Applicaions Prototypes) is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + DAP is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. +*/ #include <stddef.h> #include <stdio.h> #include <string.h> #include <stdio.h> #include <assert.h> +#include <memory.h> + //#include <dap_http_simple.h> //#include <http_status_code.h> #include "dap_common.h" @@ -22,7 +48,176 @@ #include <dap_enc_ks.h> #include "dap_chain_mempool.h" -#define LOG_TAG "MEMPOOL" +#include "dap_common.h" +#include "dap_list.h" +#include "dap_chain_sign.h" +#include "dap_chain_datum_tx.h" +#include "dap_chain_utxo.h" +#include "dap_chain_datum_tx_items.h" + +#define LOG_TAG "dap_chain_mempool" + +typedef struct list_used_item { + dap_chain_hash_fast_t tx_hash_fast; + int num_idx_out; + uint64_t value; + + //dap_chain_tx_out_t *tx_out; +} list_used_item_t; + +const char* c_dap_datum_mempool_gdb_group = NULL; + + +int dap_datum_mempool_init() +{ + c_dap_datum_mempool_gdb_group = dap_config_get_item_str_default(g_config,"mempool","gdb_group","datum-pool"); + return 0; +} + + +/** + * @brief dap_chain_mempool_datum_add + * @param a_datum + * @return + */ +int dap_chain_mempool_datum_add(dap_chain_datum_t * a_datum) +{ + return 0; +} + + +/** + * Make transfer transaction & insert to cache + * + * return 1 Ok, 0 not enough funds to transfer, -1 other Error + */ +int dap_chain_mempool_tx_create(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_fee, + const char a_token_ticker[10], + uint64_t a_value, uint64_t a_value_fee) +{ + // check valid param + if(!a_key_from || !a_key_from->priv_key_data || !a_key_from->priv_key_data_size || + !dap_chain_addr_check_sum(a_addr_from) || !dap_chain_addr_check_sum(a_addr_to) || + (a_addr_fee && !dap_chain_addr_check_sum(a_addr_fee)) || !a_value) + return -1; + + // find the transactions from which to take away coins + dap_list_t *l_list_used_out = NULL; // list of transaction with 'out' items + uint64_t l_value_transfer = 0; // how many coins to transfer + { + dap_chain_hash_fast_t l_tx_cur_hash = { 0 }; + uint64_t l_value_need = a_value + a_value_fee; + while(l_value_transfer < l_value_need) + { + // Get the transaction in the cache by the addr in out item + const dap_chain_datum_tx_t *l_tx = dap_chain_utxo_tx_find_by_addr(a_addr_from, + &l_tx_cur_hash); + if(!l_tx) + break; + // Get all item from transaction by type + int l_item_count = 0; + dap_list_t *l_list_out_items = dap_chain_datum_tx_items_get((dap_chain_datum_tx_t*) l_tx, TX_ITEM_TYPE_OUT, + &l_item_count); + dap_list_t *l_list_tmp = l_list_out_items; + int l_out_idx_tmp = 0; // current index of 'out' item + while(l_list_tmp) { + dap_chain_tx_out_t *out_item = l_list_tmp->data; + // if 'out' item has addr = a_addr_from + if(out_item && &out_item->addr && !memcmp(a_addr_from, &out_item->addr, sizeof(dap_chain_addr_t))) { + + // Check whether used 'out' items + if(!dap_chain_utxo_tx_hash_is_used_out_item(&l_tx_cur_hash, l_out_idx_tmp)) { + + list_used_item_t *item = DAP_NEW(list_used_item_t); + memcpy(&item->tx_hash_fast, &l_tx_cur_hash, sizeof(dap_chain_hash_fast_t)); + item->num_idx_out = l_out_idx_tmp; + item->value = out_item->header.value; + l_list_used_out = dap_list_append(l_list_used_out, item); + l_value_transfer += item->value; + // already accumulated the required value, finish the search for 'out' items + if(l_value_transfer >= l_value_need){ + break; + } + } + } + // go to the next 'out' item in l_tx transaction + l_out_idx_tmp++; + l_list_tmp = dap_list_next(l_list_tmp); + } + dap_list_free(l_list_out_items); + } + + // nothing to tranfer (not enough funds) + if(!l_list_used_out || l_value_transfer < l_value_need) { + dap_list_free_full(l_list_used_out, free); + return 0; + } + } + + // create empty transaction + dap_chain_datum_tx_t *l_tx = dap_chain_datum_tx_create(); + // add 'in' items + { + dap_list_t *l_list_tmp = l_list_used_out; + uint64_t l_value_to_items = 0; // how many coins to transfer + while(l_list_tmp) { + list_used_item_t *item = l_list_tmp->data; + if(dap_chain_datum_tx_add_in_item(&l_tx, &item->tx_hash_fast, item->num_idx_out) == 1) { + l_value_to_items += item->value; + } + l_list_tmp = dap_list_next(l_list_tmp); + } + assert(l_value_to_items == l_value_transfer); + dap_list_free_full(l_list_used_out, free); + } + // add 'out' items + { + uint64_t l_value_pack = 0; // how much coin add to 'out' items + if(dap_chain_datum_tx_add_out_item(&l_tx, a_addr_to, a_value) == 1) { + l_value_pack += a_value; + // transaction fee + if(a_addr_fee) { + if(dap_chain_datum_tx_add_out_item(&l_tx, a_addr_fee, a_value_fee) == 1) + l_value_pack += a_value_fee; + } + } + // coin back + uint64_t l_value_back = l_value_transfer - l_value_pack; + if(l_value_back) { + if(dap_chain_datum_tx_add_out_item(&l_tx, a_addr_from, l_value_back) != 1) { + dap_chain_datum_tx_delete(l_tx); + return -1; + } + } + } + + // add 'sign' items + if(dap_chain_datum_tx_add_sign_item(&l_tx, a_key_from) != 1) { + dap_chain_datum_tx_delete(l_tx); + return -1; + } + + size_t l_datum_data_size = dap_chain_datum_tx_get_size(l_tx); + dap_chain_datum_t * l_datum = DAP_NEW_Z_SIZE(dap_chain_datum_t, sizeof(l_datum->header) + l_datum_data_size ); + memcpy (l_datum->data, l_tx, l_datum_data_size); + l_datum->header.data_size = l_datum_data_size; + l_datum->header.version_id = DAP_CHAIN_DATUM_VERSION; + DAP_DELETE(l_tx); + + dap_chain_hash_fast_t l_key_hash; + dap_hash_fast(l_datum,l_datum_data_size+sizeof(l_datum->header),&l_key_hash); + char * l_key_str = dap_chain_hash_fast_to_str_new(&l_key_hash); + if(dap_chain_global_db_gr_set(l_key_str,(uint8_t *) l_datum, l_datum_data_size + , c_dap_datum_mempool_gdb_group)) { + log_it (L_NOTICE, "Transaction %s placed in mempool",l_key_str); + } + DAP_DELETE( l_key_str ); + + return 0; +} + uint8_t* dap_datum_mempool_serialize(dap_datum_mempool_t *datum_mempool, size_t *size) { @@ -193,7 +388,8 @@ void chain_mempool_proc(struct dap_http_simple *cl_st, void * arg) case DAP_DATUM_MEMPOOL_ADD: // add datum in base //a_value = DAP_NEW_Z_SIZE(char, request_size * 2); //bin2hex((char*) a_value, (const unsigned char*) request_str, request_size); - if(dap_chain_global_db_gr_set(a_key, request_str, request_size, DAP_CHAIN_GDB_GROUP_DATUM_POOL)) { + if(dap_chain_global_db_gr_set(a_key, request_str, request_size, + dap_config_get_item_str_default(g_config,"mempool","gdb_group","datum-pool" ) )) { *return_code = Http_Status_OK; } log_it(L_INFO, "Insert hash: key=%s result:%s", a_key, @@ -204,7 +400,7 @@ void chain_mempool_proc(struct dap_http_simple *cl_st, void * arg) case DAP_DATUM_MEMPOOL_CHECK: // check datum in base strcpy(cl_st->reply_mime, "text/text"); - char *str = dap_chain_global_db_gr_get((const char*) a_key, NULL,DAP_CHAIN_GDB_GROUP_DATUM_POOL); + char *str = dap_chain_global_db_gr_get((const char*) a_key, NULL,dap_config_get_item_str_default(g_config,"mempool","gdb_group","datum-pool" )); if(str) { dg->response = strdup("1"); DAP_DELETE(str); @@ -222,7 +418,7 @@ void chain_mempool_proc(struct dap_http_simple *cl_st, void * arg) case DAP_DATUM_MEMPOOL_DEL: // delete datum in base strcpy(cl_st->reply_mime, "text/text"); - if(dap_chain_global_db_gr_del( ((const char*) a_key),DAP_CHAIN_GDB_GROUP_DATUM_POOL) ) { + if(dap_chain_global_db_gr_del( ((const char*) a_key),dap_config_get_item_str_default(g_config,"mempool","gdb_group","datum-pool" )) ) { dg->response = strdup("1"); DAP_DELETE(str); log_it(L_INFO, "Delete hash: key=%s result: Ok", a_key); diff --git a/dap_chain_mempool.h b/dap_chain_mempool.h index 2289b51..7615e14 100755 --- a/dap_chain_mempool.h +++ b/dap_chain_mempool.h @@ -15,7 +15,6 @@ */ #define DAP_DATUM_MEMPOOL_VERSION "01" -#define DAP_CHAIN_GDB_GROUP_DATUM_POOL "datum_pool" // action enum { @@ -29,6 +28,10 @@ typedef struct dap_datum_mempool { dap_chain_datum_t **data;// mass of datums }DAP_ALIGN_PACKED dap_datum_mempool_t; +int dap_datum_mempool_init(); + +extern const char* c_dap_datum_mempool_gdb_group; + uint8_t* dap_datum_mempool_serialize(dap_datum_mempool_t *datum_mempool, size_t *size); dap_datum_mempool_t * dap_datum_mempool_deserialize(uint8_t *datum_mempool_str, size_t size); @@ -37,3 +40,9 @@ void dap_datum_mempool_free(dap_datum_mempool_t *datum); void dap_chain_mempool_add_proc(struct dap_http * sh, const char * url); +int dap_chain_mempool_tx_create(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_fee, + const char a_token_ticker[10], + uint64_t a_value, uint64_t a_value_fee); + +int dap_chain_mempool_datum_add(dap_chain_datum_t * a_datum); -- GitLab