diff --git a/dap_chain_net_srv.c b/dap_chain_net_srv.c index 0e123c140495c360f1d25c8a3aad191273e4fcb4..5012e438f75db80802f5ee602e45668998ffa143 100755 --- a/dap_chain_net_srv.c +++ b/dap_chain_net_srv.c @@ -83,10 +83,13 @@ int dap_chain_net_srv_init(void) return -1; dap_chain_node_cli_cmd_item_create ("net_srv", s_cli_net_srv, "Network services managment", - "net_srv -net <chain net name> order list [-srv_uid <Service UID>] [-srv_class <Service Class>]\n" + "net_srv -net <chain net name> order find [-srv_uid <Service UID>] [-srv_class <Service Class>] [-price_unit <price unit>]\\\n" + " [-price_min <Price minimum>] [-price_max <Price maximum>]\n" "\tOrders list, all or by UID and/or class\n" - "net_srv -net <chain net name> order delete -id <Proposal ID>\n" + "net_srv -net <chain net name> order delete -hash <Order hash>\n" "\tOrder delete\n" + "net_srv -net <chain net name> order dump -hash <Order hash>\n" + "\tOrder dump info\n" "net_srv -net <chain net name> order create -srv_uid <Service UID> -srv_class <Service Class> -price <Price>\\\n" " -price_unit <Price Unit> -node_addr <Node Address> -tx_cond <TX Cond Hash> \\\n" " [-expires <Unix time when expires>]\\\n" @@ -125,8 +128,7 @@ static int s_cli_net_srv( int argc, char **argv, char **a_str_reply) dap_string_t *l_string_ret = dap_string_new(""); const char *l_order_str = NULL; dap_chain_node_cli_find_option_val(argv, arg_index, argc, "order", &l_order_str); - if ( strcmp( l_order_str, "list" ) == 0 ){ - dap_string_append(l_string_ret,"Orders:\n"); + if ( strcmp( l_order_str, "find" ) == 0 ){ // Select with specified service uid const char *l_srv_uid_str = NULL; @@ -135,7 +137,77 @@ static int s_cli_net_srv( int argc, char **argv, char **a_str_reply) // Select with specified service class const char *l_srv_class_str = NULL; dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-srv_class", &l_srv_class_str); - } else if( strcmp( l_order_str, "create" ) == 0 ){ + + // Select with specified price units + const char* l_price_unit_str = NULL; + dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-price_unit", &l_price_unit_str); + + // Select with price not more than price_min + const char* l_price_min_str = NULL; + dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-price_min", &l_price_min_str); + + // Select with price not more than price_max + const char* l_price_max_str = NULL; + dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-price_max", &l_price_max_str); + + dap_chain_net_srv_uid_t l_srv_uid={{0}}; + dap_chain_net_srv_class_t l_srv_class= SERV_CLASS_UNDEFINED; + uint64_t l_price_min=0, l_price_max =0 ; + dap_chain_net_srv_price_unit_uid_t l_price_unit={{0}}; + + l_srv_uid.uint64 = (uint128_t) atoll( l_srv_uid_str); + l_srv_class = (dap_chain_net_srv_class_t) atoi( l_srv_class_str ); + l_price_min = (uint64_t) atoll ( l_price_min_str ); + l_price_max = (uint64_t) atoll ( l_price_max_str ); + l_price_unit.uint32 = (uint32_t) atol ( l_price_unit_str ); + dap_chain_net_srv_order_t * l_orders; + size_t l_orders_size =0; + if( dap_chain_net_srv_order_find_all_by( l_net,l_srv_uid,l_srv_class,l_price_unit,l_price_min, l_price_max,&l_orders,&l_orders_size) == 0 ){ + dap_string_append_printf(l_string_ret,"Found %u orders:\n",l_orders_size); + for (size_t i = 0; i< l_orders_size; i++){ + dap_chain_net_srv_order_dump_to_string(l_orders+i,l_string_ret); + dap_string_append(l_string_ret,"\n"); + } + ret = 0; + }else{ + ret = -5 ; + dap_string_append(l_string_ret,"Can't get orders: some internal error or wrong params\n"); + } + + }else if( strcmp( l_order_str, "dump" ) == 0 ){ + // Select with specified service uid + const char *l_order_hash_str = NULL; + dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-hash", &l_order_hash_str); + if ( l_order_hash_str ){ + dap_chain_net_srv_order_t * l_order = dap_chain_net_srv_order_find_by_hash( l_net, l_order_hash_str ); + if (l_order){ + dap_chain_net_srv_order_dump_to_string(l_order,l_string_ret); + ret = 0; + }else{ + ret = -7 ; + dap_string_append_printf(l_string_ret,"Can't find order with hash %s\n", l_order_hash_str ); + } + } else{ + ret = -6 ; + dap_string_append(l_string_ret,"need -hash param to obtain what the order we need to dump\n"); + } + }else if( strcmp( l_order_str, "delete" ) == 0 ){ + // Select with specified service uid + const char *l_order_hash_str = NULL; + dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-hash", &l_order_hash_str); + if ( l_order_hash_str ){ + if (dap_chain_net_srv_order_delete_by_hash_str(l_net,l_order_hash_str) == 0){ + ret = 0 ; + dap_string_append_printf(l_string_ret,"Deleted order %s\n", l_order_hash_str ); + }else{ + ret = -8 ; + dap_string_append_printf(l_string_ret,"Can't find order with hash %s\n", l_order_hash_str ); + } + } else{ + ret = -9 ; + dap_string_append(l_string_ret,"need -hash param to obtain what the order we need to dump\n"); + } + }else if( strcmp( l_order_str, "create" ) == 0 ){ const char* l_srv_uid_str = NULL; dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-srv_uid", &l_srv_uid_str); @@ -151,6 +223,9 @@ static int s_cli_net_srv( int argc, char **argv, char **a_str_reply) const char* l_price_str = NULL; dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-price", &l_price_str); + const char* l_expires_str = NULL; + dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-expires", &l_expires_str); + const char* l_price_unit_str = NULL; dap_chain_node_cli_find_option_val(argv, arg_index, argc, "-price_unit", &l_price_unit_str); @@ -162,18 +237,20 @@ static int s_cli_net_srv( int argc, char **argv, char **a_str_reply) dap_chain_net_srv_class_t l_srv_class= SERV_CLASS_UNDEFINED; dap_chain_node_addr_t l_node_addr={0}; dap_chain_hash_fast_t l_tx_cond_hash={{0}}; - uint128_t l_price=0; + dap_chain_time_t l_expires=0; // TS when the service expires + uint64_t l_price=0; dap_chain_net_srv_price_unit_uid_t l_price_unit={{0}}; - - l_srv_uid.uint128 = (uint128_t) atoll( l_srv_uid_str); + if (l_expires_str) + l_expires = (dap_chain_time_t ) atoll( l_expires_str); + l_srv_uid.uint64 = (uint64_t) atoll( l_srv_uid_str); l_srv_class = (dap_chain_net_srv_class_t) atoi( l_srv_class_str ); dap_chain_node_addr_from_str( &l_node_addr, l_node_addr_str ); dap_chain_str_to_hash_fast (l_tx_cond_hash_str, &l_tx_cond_hash); - l_price = (uint128_t) atoll ( l_price_str ); + l_price = (uint64_t) atoll ( l_price_str ); l_price_unit.uint32 = (uint32_t) atol ( l_price_unit_str ); char * l_order_new_hash_str = dap_chain_net_srv_order_create ( - l_net, l_srv_uid, l_srv_class, l_node_addr,l_tx_cond_hash, l_price, l_price_unit, l_comments); + l_net, l_srv_uid, l_srv_class, l_node_addr,l_tx_cond_hash, l_price, l_price_unit, l_expires,l_comments); if (l_order_new_hash_str) dap_string_append_printf( l_string_ret, "Created order %s\n", l_order_new_hash_str); else{ diff --git a/dap_chain_net_srv_common.h b/dap_chain_net_srv_common.h index 3b64cb9ed0b84f54bf74145a1557dcee5a90750d..c2b467a24453ce24dc6d0a0c0dd76d3f302cc6cd 100755 --- a/dap_chain_net_srv_common.h +++ b/dap_chain_net_srv_common.h @@ -31,18 +31,23 @@ #include "dap_stream_ch.h" #include "dap_chain_ledger.h" -#define DAP_CHAIN_NET_SRV_UID_SIZE 16 +#define DAP_CHAIN_NET_SRV_UID_SIZE 8 + typedef union { uint8_t raw[DAP_CHAIN_NET_SRV_UID_SIZE]; - #if DAP_CHAIN_NET_SRV_UID_SIZE == 8 +#if DAP_CHAIN_NET_SRV_UID_SIZE == 8 uint64_t raw_ui64[1]; + uint64_t uint64; #elif DAP_CHAIN_NET_SRV_UID_SIZE == 16 - uint64_t raw_ui64[2]; - dap_uint128_t raw_ui128[1]; + uint64_t raw_ui64[1]; uint128_t uint128; #endif } dap_chain_net_srv_uid_t; +#define DAP_CHAIN_NET_SRV_PRICE_UNIT_BYTE 0x00000001 +#define DAP_CHAIN_NET_SRV_PRICE_UNIT_SECOND 0x00000010 +#define DAP_CHAIN_NET_SRV_PRICE_UNIT_BYTE_PER_SECOND 0x00000100 + typedef union { uint8_t raw[4]; uint32_t raw_ui32[1]; @@ -102,6 +107,16 @@ typedef struct dap_chain_net_srv //void * _inhertor; } dap_chain_net_srv_t; +DAP_STATIC_INLINE const char * dap_chain_net_srv_price_unit_uid_to_str( dap_chain_net_srv_price_unit_uid_t a_uid ) +{ + switch ( a_uid.uint32 ) { + case DAP_CHAIN_NET_SRV_PRICE_UNIT_BYTE: return "BYTE"; + case DAP_CHAIN_NET_SRV_PRICE_UNIT_SECOND: return "SECOND"; + case DAP_CHAIN_NET_SRV_PRICE_UNIT_BYTE_PER_SECOND: return "BYTE_PER_SECOND"; + default: return "UNKNOWN"; + } +} + // Initialize dap_chain_net_srv_abstract_t structure void dap_chain_net_srv_abstract_set(dap_chain_net_srv_abstract_t *a_cond, uint8_t a_class, uint128_t a_type_id, uint64_t a_price, uint8_t a_price_units, const char *a_decription); diff --git a/dap_chain_net_srv_order.c b/dap_chain_net_srv_order.c index acfb73aaa8418338e495c5d6cef2d047c6ecd9f5..282b3dad4e7c05a68fc4e0e4eddda58ca3d82eb2 100644 --- a/dap_chain_net_srv_order.c +++ b/dap_chain_net_srv_order.c @@ -56,6 +56,7 @@ char* dap_chain_net_srv_order_create( dap_chain_hash_fast_t a_tx_cond_hash, // Hash index of conditioned transaction attached with order uint64_t a_price, // service price in datoshi, for SERV_CLASS_ONCE ONCE for the whole service, for SERV_CLASS_PERMANENT for one unit. dap_chain_net_srv_price_unit_uid_t a_price_unit, // Unit of service (seconds, megabytes, etc.) Only for SERV_CLASS_PERMANENT + dap_chain_time_t a_expires, // TS when the service expires const char * a_comments ) { @@ -64,6 +65,7 @@ char* dap_chain_net_srv_order_create( dap_chain_hash_fast_t* l_order_hash = DAP_NEW_Z(dap_chain_hash_fast_t); l_order->version = 1; l_order->srv_uid = a_srv_uid; + l_order->ts_created = (dap_chain_time_t) time(NULL); l_order->srv_class = a_srv_class; l_order->node_addr.uint64 = a_node_addr.uint64; memcpy(&l_order->tx_cond_hash, &a_tx_cond_hash, DAP_CHAIN_HASH_FAST_SIZE); @@ -92,27 +94,24 @@ char* dap_chain_net_srv_order_create( } /** - * @brief dap_chain_net_srv_order_find_by_hash + * @brief dap_chain_net_srv_order_find_by_hash_str * @param a_net - * @param a_hash + * @param a_hash_str * @return */ -dap_chain_net_srv_order_t * dap_chain_net_srv_order_find_by_hash(dap_chain_net_t * a_net, dap_chain_hash_fast_t * a_hash) +dap_chain_net_srv_order_t * dap_chain_net_srv_order_find_by_hash_str(dap_chain_net_t * a_net, const char * a_hash_str) { dap_chain_net_srv_order_t * l_order = NULL; - if ( a_net && a_hash ){ - char * l_order_hash_str = dap_chain_hash_fast_to_str_new(a_hash ); + if ( a_net && a_hash_str ){ char * l_gdb_group_str = dap_chain_net_srv_order_get_gdb_group( a_net); size_t l_order_size =0; - l_order = (dap_chain_net_srv_order_t *) dap_chain_global_db_gr_get(l_order_hash_str, &l_order_size, l_gdb_group_str ); + l_order = (dap_chain_net_srv_order_t *) dap_chain_global_db_gr_get(a_hash_str, &l_order_size, l_gdb_group_str ); if (l_order_size != sizeof (dap_chain_net_srv_order_t) ){ log_it( L_ERROR, "Found wrong size order"); DAP_DELETE( l_order ); - DAP_DELETE( l_order_hash_str ); DAP_DELETE( l_gdb_group_str ); return NULL; } - DAP_DELETE( l_order_hash_str ); DAP_DELETE( l_gdb_group_str ); } return l_order; @@ -131,11 +130,11 @@ int dap_chain_net_srv_order_find_all_by(dap_chain_net_t * a_net, dap_chain_net_s size_t l_order_passed_index; lb_order_pass: l_order_passed_index =0; - for (int i; i< l_orders_count; i++){ + for (size_t i; i< l_orders_count; i++){ dap_chain_net_srv_order_t * l_order = (dap_chain_net_srv_order_t *) l_orders[i].value; // Check srv uid - if ( a_srv_uid.uint128) - if ( l_order->srv_uid.uint128 != a_srv_uid.uint128 ) + if ( a_srv_uid.uint64) + if ( l_order->srv_uid.uint64 != a_srv_uid.uint64 ) continue; // Check srv class if ( a_srv_class != SERV_CLASS_UNDEFINED ) @@ -191,3 +190,38 @@ int dap_chain_net_srv_order_delete_by_hash_str(dap_chain_net_t * a_net, const ch return ret; } +/** + * @brief dap_chain_net_srv_order_dump_to_string + * @param a_orders + * @param a_str_out + */ +void dap_chain_net_srv_order_dump_to_string(dap_chain_net_srv_order_t *a_order,dap_string_t * a_str_out) +{ + if (a_order && a_str_out ){ + dap_chain_hash_fast_t l_hash; + char l_hash_str[DAP_CHAIN_HASH_FAST_SIZE * 2 + 4]; + dap_hash_fast(a_order,sizeof (*a_order),&l_hash ); + dap_chain_hash_fast_to_str(&l_hash,l_hash_str,sizeof(l_hash_str)-1); + dap_string_append_printf(a_str_out, "== Order %s ==\n", l_hash_str); + dap_string_append_printf(a_str_out, " version: %u\n", a_order->version ); + + switch ( a_order->srv_class) { + case SERV_CLASS_ONCE: dap_string_append_printf(a_str_out, " srv_class: SERV_CLASS_ONCE\n" ); break;; + case SERV_CLASS_PERMANENT: dap_string_append_printf(a_str_out, " srv_class: SERV_CLASS_PERMANENT\n" ); break; + case SERV_CLASS_UNDEFINED: dap_string_append_printf(a_str_out, " srv_class: SERV_CLASS_UNDEFINED\n" ); break; + //default: dap_string_append_printf(a_str_out, " srv_class: UNKNOWN\n" ); + } + dap_string_append_printf(a_str_out, " srv_uid: 0x%016llX\n", a_order->srv_uid.uint64 ); + dap_string_append_printf(a_str_out, " price: \u00a0%.3Lf (%llu)\n", dap_chain_balance_to_coins(a_order->price) , a_order->price); + if( a_order->price_unit.uint32 ) + dap_string_append_printf(a_str_out, " price_unit: 0x%016llX\n", dap_chain_net_srv_price_unit_uid_to_str(a_order->price_unit) ); + if ( a_order->node_addr.uint64) + dap_string_append_printf(a_str_out, " node_addr: "NODE_ADDR_FP_STR"\n", NODE_ADDR_FP_ARGS_S(a_order->node_addr) ); + + dap_chain_hash_fast_to_str(&a_order->tx_cond_hash,l_hash_str,sizeof(l_hash_str)-1); + dap_string_append_printf(a_str_out, " tx_cond_hash: %s\n", l_hash_str ); + + if( a_order->comments[0]) + dap_string_append_printf(a_str_out, " comments: \"%s\"\n", a_order->comments ); + } +} diff --git a/dap_chain_net_srv_order.h b/dap_chain_net_srv_order.h index e5daf3cbb6d4fd324437404c392e0d40ff91f9d8..5e870fd5297409edf920ec2e1c0f78896537ffaf 100644 --- a/dap_chain_net_srv_order.h +++ b/dap_chain_net_srv_order.h @@ -24,6 +24,7 @@ along with any DAP based project. If not, see <http://www.gnu.org/licenses/>. #pragma once #include "dap_common.h" +#include "dap_string.h" #include "dap_chain_net.h" #include "dap_chain_net_srv_common.h" @@ -36,6 +37,8 @@ typedef struct dap_chain_net_srv_order dap_chain_hash_fast_t tx_cond_hash; // Hash index of conditioned transaction attached with order uint64_t price; // service price in datoshi, for SERV_CLASS_ONCE ONCE for the whole service, for SERV_CLASS_PERMANENT for one unit. dap_chain_net_srv_price_unit_uid_t price_unit; // Unit of service (seconds, megabytes, etc.) Only for SERV_CLASS_PERMANENT + dap_chain_time_t ts_created; + dap_chain_time_t ts_expires; char comments[128]; } dap_chain_net_srv_order_t; @@ -43,7 +46,17 @@ typedef struct dap_chain_net_srv_order int dap_chain_net_srv_order_init(void); void dap_chain_net_srv_order_deinit(void); -dap_chain_net_srv_order_t * dap_chain_net_srv_order_find_by_hash(dap_chain_net_t * a_net, dap_chain_hash_fast_t * a_hash); +dap_chain_net_srv_order_t * dap_chain_net_srv_order_find_by_hash_str(dap_chain_net_t * a_net, const char * a_hash_str); + +DAP_STATIC_INLINE dap_chain_net_srv_order_t * dap_chain_net_srv_order_find_by_hash(dap_chain_net_t * a_net, dap_chain_hash_fast_t * a_hash) +{ + if ( a_net && a_hash ){ + char l_hash_str[DAP_CHAIN_HASH_FAST_SIZE * 2 + 4]; + dap_chain_hash_fast_to_str(a_hash,l_hash_str,sizeof(l_hash_str)-1); + return dap_chain_net_srv_order_find_by_hash_str(a_net, l_hash_str ); + } +} + int dap_chain_net_srv_order_find_all_by(dap_chain_net_t * a_net,dap_chain_net_srv_uid_t a_srv_uid, dap_chain_net_srv_class_t a_srv_class, dap_chain_net_srv_price_unit_uid_t a_price_unit, uint64_t a_price_min, uint64_t a_price_max, dap_chain_net_srv_order_t ** a_output_orders, size_t * a_output_orders_count); @@ -70,9 +83,11 @@ char* dap_chain_net_srv_order_create( dap_chain_hash_fast_t a_tx_cond_hash, // Hash index of conditioned transaction attached with order uint64_t a_price, // service price in datoshi, for SERV_CLASS_ONCE ONCE for the whole service, for SERV_CLASS_PERMANENT for one unit. dap_chain_net_srv_price_unit_uid_t a_price_unit, // Unit of service (seconds, megabytes, etc.) Only for SERV_CLASS_PERMANENT + dap_chain_time_t a_expires, // TS when the service expires const char * a_comments ); +void dap_chain_net_srv_order_dump_to_string(dap_chain_net_srv_order_t *a_order,dap_string_t * a_str_out); /** * @brief dap_chain_net_srv_order_get_gdb_group_mempool