From 89ce98948a323fe83e8a6a75e77892496c95d0bd Mon Sep 17 00:00:00 2001 From: Roman Khlopkov <roman.khlopkov@demlabs.net> Date: Sat, 2 Apr 2022 16:04:58 +0300 Subject: [PATCH] [*] Srv datum frozen --- modules/common/include/dap_chain_common.h | 2 + .../include/dap_chain_datum_tx_out_cond.h | 19 +- modules/mempool/dap_chain_mempool.c | 19 +- modules/mempool/include/dap_chain_mempool.h | 3 + modules/net/srv/dap_chain_net_srv.c | 165 ++++++++++-------- modules/net/srv/dap_chain_net_srv_order.c | 16 +- modules/net/srv/include/dap_chain_net_srv.h | 11 ++ .../service/datum/dap_chain_net_srv_datum.c | 57 +++++- 8 files changed, 187 insertions(+), 105 deletions(-) diff --git a/modules/common/include/dap_chain_common.h b/modules/common/include/dap_chain_common.h index 965c90a460..99f7cb93bd 100644 --- a/modules/common/include/dap_chain_common.h +++ b/modules/common/include/dap_chain_common.h @@ -163,6 +163,7 @@ typedef enum { SERV_UNIT_DAY = 0x00000003, // days SERV_UNIT_KB = 0x00000010, // kilobytes SERV_UNIT_B = 0x00000011, // bytes + SERV_UNIT_PCS = 0x00000022 // pieces } serv_unit_enum_t; DAP_STATIC_INLINE const char *serv_unit_enum_to_str(serv_unit_enum_t *unit_enum){ @@ -173,6 +174,7 @@ DAP_STATIC_INLINE const char *serv_unit_enum_to_str(serv_unit_enum_t *unit_enum) case SERV_UNIT_DAY: return "SERV_UNIT_DAY"; case SERV_UNIT_KB: return "SERV_UNIT_KB"; case SERV_UNIT_B: return "SERV_UNIT_B"; + case SERV_UNIT_PCS: return "SERV_UNIT_PCS"; default: return "UNDEFINED"; } diff --git a/modules/common/include/dap_chain_datum_tx_out_cond.h b/modules/common/include/dap_chain_datum_tx_out_cond.h index f7f57e8241..39a407918d 100644 --- a/modules/common/include/dap_chain_datum_tx_out_cond.h +++ b/modules/common/include/dap_chain_datum_tx_out_cond.h @@ -32,7 +32,8 @@ enum dap_chain_tx_out_cond_subtype { DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY = 0x01, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE = 0x02, - DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE = 0x13, + DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE = 0x3, + DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_FEE = 0x04, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_UPDATE = 0xFA // Virtual type for stake update verificator //TODO change it to new type of callback for ledger tx add }; typedef byte_t dap_chain_tx_out_cond_subtype_t; @@ -41,10 +42,11 @@ DAP_STATIC_INLINE const char *dap_chain_tx_out_cond_subtype_to_str(dap_chain_tx_ switch (a_subtype) { case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY: return "DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY"; case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE: return "DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE"; + case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_FEE: return "DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_FEE"; case DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE: return "DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_XCHANGE"; - default: return "UNDEFINED"; - + default: {} } + return "UNDEFINED"; } /** @@ -57,7 +59,9 @@ typedef struct dap_chain_tx_out_cond { dap_chain_tx_item_type_t item_type; /// Condition subtype dap_chain_tx_out_cond_subtype_t subtype; - /// Number of Datoshis ( DAP/10^9 ) to be reserver for service + /// Service uid that only could be used for this out + dap_chain_net_srv_uid_t srv_uid; + /// Number of Datoshis ( DAP/10^18 ) to be reserved for service uint256_t value; /// When time expires this output could be used only by transaction owner dap_chain_time_t ts_expires; @@ -67,16 +71,12 @@ typedef struct dap_chain_tx_out_cond { struct { /// Public key hash that could use this conditioned outout dap_chain_hash_fast_t pkey_hash; - /// Service uid that only could be used for this outout - dap_chain_net_srv_uid_t srv_uid; /// Price unit thats used to check price max dap_chain_net_srv_price_unit_uid_t unit; /// Maximum price per unit uint256_t unit_price_max_datoshi; } srv_pay; struct { - // Service uid that only could be used for this outout - dap_chain_net_srv_uid_t srv_uid; // Token ticker to change to char token[DAP_CHAIN_TICKER_SIZE_MAX]; // Chain network to change to @@ -85,8 +85,6 @@ typedef struct dap_chain_tx_out_cond { uint256_t value; } srv_xchange; struct { - // Service uid that only could be used for this outout - dap_chain_net_srv_uid_t srv_uid; // Stake holder address dap_chain_addr_t hldr_addr; // Fee address @@ -99,6 +97,7 @@ typedef struct dap_chain_tx_out_cond { dap_chain_node_addr_t signer_node_addr; } srv_stake; } subtype; + byte_t free_space[256]; // for future changes uint32_t params_size; // Condition parameters size uint8_t params[]; // condition parameters, pkey, hash or smth like this } DAP_ALIGN_PACKED dap_chain_tx_out_cond_t; diff --git a/modules/mempool/dap_chain_mempool.c b/modules/mempool/dap_chain_mempool.c index 4aa40a2f6f..bdd5049085 100644 --- a/modules/mempool/dap_chain_mempool.c +++ b/modules/mempool/dap_chain_mempool.c @@ -354,9 +354,9 @@ int dap_chain_mempool_tx_create_massive( dap_chain_t * a_chain, dap_enc_key_t *a } -dap_chain_hash_fast_t* dap_chain_mempool_tx_create_cond_input(dap_chain_net_t * a_net, dap_chain_hash_fast_t *a_tx_prev_hash, - const dap_chain_addr_t* a_addr_to, dap_enc_key_t *a_key_tx_sign, - dap_chain_datum_tx_receipt_t * a_receipt) +dap_chain_datum_t *dap_chain_tx_create_cond_input(dap_chain_net_t * a_net, dap_chain_hash_fast_t *a_tx_prev_hash, + const dap_chain_addr_t* a_addr_to, dap_enc_key_t *a_key_tx_sign, + dap_chain_datum_tx_receipt_t * a_receipt) { dap_ledger_t * l_ledger = a_net ? dap_chain_ledger_by_net_name( a_net->pub.name ) : NULL; if ( ! a_net || ! l_ledger || ! a_addr_to ) @@ -436,7 +436,7 @@ dap_chain_hash_fast_t* dap_chain_mempool_tx_create_cond_input(dap_chain_net_t * l_out_cond->header.value = l_old_val; // add 'sign' items - if (a_key_tx_sign){ + if (a_key_tx_sign) { if(dap_chain_datum_tx_add_sign_item(&l_tx, a_key_tx_sign) != 1) { dap_chain_datum_tx_delete(l_tx); log_it( L_ERROR, "Can't add sign output"); @@ -445,10 +445,17 @@ dap_chain_hash_fast_t* dap_chain_mempool_tx_create_cond_input(dap_chain_net_t * } size_t l_tx_size = dap_chain_datum_tx_get_size( l_tx ); dap_chain_datum_t *l_datum = dap_chain_datum_create( DAP_CHAIN_DATUM_TX, l_tx, l_tx_size ); + DAP_DELETE(l_tx); + return l_datum; +} +dap_chain_hash_fast_t* dap_chain_mempool_tx_create_cond_input(dap_chain_net_t * a_net, dap_chain_hash_fast_t *a_tx_prev_hash, + const dap_chain_addr_t* a_addr_to, dap_enc_key_t *a_key_tx_sign, + dap_chain_datum_tx_receipt_t * a_receipt) +{ + dap_chain_datum_t *l_datum = dap_chain_tx_create_cond_input(a_net, a_tx_prev_hash, a_addr_to, a_key_tx_sign, a_receipt); dap_chain_hash_fast_t *l_key_hash = DAP_NEW_Z( dap_chain_hash_fast_t ); - dap_hash_fast( l_tx, l_tx_size, l_key_hash ); - DAP_DELETE( l_tx ); + dap_hash_fast(l_datum->data, l_datum->header.data_size, l_key_hash); char * l_key_str = dap_chain_hash_fast_to_str_new( l_key_hash ); diff --git a/modules/mempool/include/dap_chain_mempool.h b/modules/mempool/include/dap_chain_mempool.h index a89a68be4b..60b532ac3a 100644 --- a/modules/mempool/include/dap_chain_mempool.h +++ b/modules/mempool/include/dap_chain_mempool.h @@ -58,6 +58,9 @@ dap_chain_hash_fast_t* dap_chain_mempool_tx_create_cond(dap_chain_net_t * a_net, uint256_t a_value, uint256_t a_value_per_unit_max, dap_chain_net_srv_price_unit_uid_t a_unit, dap_chain_net_srv_uid_t a_srv_uid, uint256_t a_value_fee, const void *a_cond, size_t a_cond_size); +dap_chain_datum_t *dap_chain_tx_create_cond_input(dap_chain_net_t * a_net, dap_chain_hash_fast_t *a_tx_prev_hash, + const dap_chain_addr_t* a_addr_to, dap_enc_key_t *a_key_tx_sign, + dap_chain_datum_tx_receipt_t * a_receipt); dap_chain_hash_fast_t* dap_chain_mempool_tx_create_cond_input(dap_chain_net_t * a_net, dap_chain_hash_fast_t *a_tx_prev_hash, const dap_chain_addr_t *a_addr_to, dap_enc_key_t *a_key_tx_sign, dap_chain_datum_tx_receipt_t *a_receipt); diff --git a/modules/net/srv/dap_chain_net_srv.c b/modules/net/srv/dap_chain_net_srv.c index 9edc256250..f1f25554f0 100644 --- a/modules/net/srv/dap_chain_net_srv.c +++ b/modules/net/srv/dap_chain_net_srv.c @@ -610,6 +610,95 @@ bool dap_chain_net_srv_pay_verificator(dap_chain_tx_out_cond_t *a_cond, dap_chai if (!dap_sign_get_pkey_hash(l_sign, &l_pkey_hash)) return false; return dap_hash_fast_compare(&l_pkey_hash, &a_cond->subtype.srv_pay.pkey_hash); + // TODO add comparision a_tx sign pkey with receipt provider sign pkey +} + +int dap_chain_net_srv_parse_pricelist(dap_chain_net_srv_t *a_srv, const char *a_config_section) +{ + int ret = 0; + if (!a_config_section) + return ret; + a_srv->grace_period = dap_config_get_item_uint32_default(g_config, a_config_section, "grace_period", 60); + //! IMPORTANT ! This fetch is single-action and cannot be further reused, since it modifies the stored config data + uint16_t l_pricelist_count = 0; + char **l_pricelist = dap_config_get_array_str(g_config, a_config_section, "pricelist", &l_pricelist_count); + for (uint16_t i = 0; i < l_pricelist_count; i++) { + dap_chain_net_srv_price_t *l_price = DAP_NEW_Z(dap_chain_net_srv_price_t); + short l_iter = 0; + char *l_ctx; + for (char *l_price_token = strtok_r(l_pricelist[i], ":", &l_ctx); l_price_token || l_iter == 6; l_price_token = strtok_r(NULL, ":", &l_ctx), ++l_iter) { + //log_it(L_DEBUG, "Tokenizer: %s", l_price_token); + switch (l_iter) { + case 0: + l_price->net_name = l_price_token; + if (!(l_price->net = dap_chain_net_by_name(l_price->net_name))) { + log_it(L_ERROR, "Error parsing pricelist: can't find network \"%s\"", l_price_token); + DAP_DELETE(l_price); + break; + } + continue; + case 1: + l_price->value_datoshi = dap_chain_uint256_to(dap_chain_coins_to_balance(l_price_token)); + if (!l_price->value_datoshi) { + log_it(L_ERROR, "Error parsing pricelist: text on 2nd position \"%s\" is not floating number", l_price_token); + l_iter = 0; + DAP_DELETE(l_price); + break; + } + continue; + case 2: + dap_stpcpy(l_price->token, l_price_token); + continue; + case 3: + l_price->units = strtoul(l_price_token, NULL, 10); + if (!l_price->units) { + log_it(L_ERROR, "Error parsing pricelist: text on 4th position \"%s\" is not unsigned integer", l_price_token); + l_iter = 0; + DAP_DELETE(l_price); + break; + } + continue; + case 4: + if (!strcmp(l_price_token, "SEC")) + l_price->units_uid.enm = SERV_UNIT_SEC; + else if (!strcmp(l_price_token, "DAY")) + l_price->units_uid.enm = SERV_UNIT_DAY; + else if (!strcmp(l_price_token, "MB")) + l_price->units_uid.enm = SERV_UNIT_MB; + else if (!strcmp(l_price_token, "KB")) + l_price->units_uid.enm = SERV_UNIT_KB; + else if (!strcmp(l_price_token, "B")) + l_price->units_uid.enm = SERV_UNIT_B; + else if (!strcmp(l_price_token, "PCS")) + l_price->units_uid.enm = SERV_UNIT_PCS; + else { + log_it(L_ERROR, "Error parsing pricelist: wrong unit type \"%s\"", l_price_token); + l_iter = 0; + DAP_DELETE(l_price); + break; + } + continue; + case 5: + if (!(l_price->wallet = dap_chain_wallet_open(l_price_token, dap_config_get_item_str_default(g_config, "resources", "wallets_path", NULL)))) { + log_it(L_ERROR, "Error parsing pricelist: can't open wallet \"%s\"", l_price_token); + l_iter = 0; + DAP_DELETE(l_price); + break; + } + continue; + case 6: + log_it(L_INFO, "Price item correct, added to service"); + DL_APPEND(a_srv->pricelist, l_price); + ret++; + break; + default: + break; + } + log_it(L_DEBUG, "Done with price item %d", i); + break; // double break exits tokenizer loop and steps to next price item + } + } + return ret; } /** @@ -646,81 +735,7 @@ dap_chain_net_srv_t* dap_chain_net_srv_add(dap_chain_net_srv_uid_t a_uid, l_sdata = DAP_NEW_Z(service_list_t); memcpy(&l_sdata->uid, &l_uid, sizeof(l_uid)); l_sdata->srv = l_srv; - if (a_config_section) { - l_srv->grace_period = dap_config_get_item_uint32_default(g_config, a_config_section, "grace_period", 60); - //! IMPORTANT ! This fetch is single-action and cannot be further reused, since it modifies the stored config data - uint16_t l_pricelist_count = 0; - char **l_pricelist = dap_config_get_array_str(g_config, a_config_section, "pricelist", &l_pricelist_count); - for (uint16_t i = 0; i < l_pricelist_count; i++) { - dap_chain_net_srv_price_t *l_price = DAP_NEW_Z(dap_chain_net_srv_price_t); - short l_iter = 0; - char *l_ctx; - for (char *l_price_token = strtok_r(l_pricelist[i], ":", &l_ctx); l_price_token || l_iter == 6; l_price_token = strtok_r(NULL, ":", &l_ctx), ++l_iter) { - //log_it(L_DEBUG, "Tokenizer: %s", l_price_token); - switch (l_iter) { - case 0: - l_price->net_name = l_price_token; - if (!(l_price->net = dap_chain_net_by_name(l_price->net_name))) { - log_it(L_ERROR, "Error parsing pricelist: can't find network \"%s\"", l_price_token); - DAP_DELETE(l_price); - break; - } - continue; - case 1: - l_price->value_datoshi = dap_chain_uint256_to(dap_chain_coins_to_balance(l_price_token)); - if (!l_price->value_datoshi) { - log_it(L_ERROR, "Error parsing pricelist: text on 2nd position \"%s\" is not floating number", l_price_token); - l_iter = 0; - DAP_DELETE(l_price); - break; - } - continue; - case 2: - dap_stpcpy(l_price->token, l_price_token); - continue; - case 3: - l_price->units = strtoul(l_price_token, NULL, 10); - if (!l_price->units) { - log_it(L_ERROR, "Error parsing pricelist: text on 4th position \"%s\" is not unsigned integer", l_price_token); - l_iter = 0; - DAP_DELETE(l_price); - break; - } - continue; - case 4: - if (!strcmp(l_price_token, "SEC")) - l_price->units_uid.enm = SERV_UNIT_SEC; - else if (!strcmp(l_price_token, "DAY")) - l_price->units_uid.enm = SERV_UNIT_DAY; - else if (!strcmp(l_price_token, "MB")) - l_price->units_uid.enm = SERV_UNIT_MB; - else { - log_it(L_ERROR, "Error parsing pricelist: wrong unit type \"%s\"", l_price_token); - l_iter = 0; - DAP_DELETE(l_price); - break; - } - continue; - case 5: - if (!(l_price->wallet = dap_chain_wallet_open(l_price_token, dap_config_get_item_str_default(g_config, "resources", "wallets_path", NULL)))) { - log_it(L_ERROR, "Error parsing pricelist: can't open wallet \"%s\"", l_price_token); - l_iter = 0; - DAP_DELETE(l_price); - break; - } - continue; - case 6: - log_it(L_INFO, "Price item correct, added to service"); - DL_APPEND(l_srv->pricelist, l_price); - break; - default: - break; - } - log_it(L_DEBUG, "Done with price item %d", i); - break; // double break exits tokenizer loop and steps to next price item - } - } - } + dap_chain_net_srv_parse_pricelist(l_srv, a_config_section); HASH_ADD(hh, s_srv_list, uid, sizeof(l_srv->uid), l_sdata); }else{ log_it(L_ERROR, "Already present service with 0x%016"DAP_UINT64_FORMAT_X, a_uid.uint64); diff --git a/modules/net/srv/dap_chain_net_srv_order.c b/modules/net/srv/dap_chain_net_srv_order.c index 79ddfab3f4..87ae6a8458 100644 --- a/modules/net/srv/dap_chain_net_srv_order.c +++ b/modules/net/srv/dap_chain_net_srv_order.c @@ -346,10 +346,14 @@ char *dap_chain_net_srv_order_save(dap_chain_net_t *a_net, dap_chain_net_srv_ord return l_order_hash_str; } -dap_chain_net_srv_order_t *dap_chain_net_srv_order_read(byte_t *a_order) +dap_chain_net_srv_order_t *dap_chain_net_srv_order_read(byte_t *a_order, size_t a_order_size) { - if (((dap_chain_net_srv_order_t *)a_order)->version == 3) - return DAP_DUP_SIZE(a_order, dap_chain_net_srv_order_get_size((dap_chain_net_srv_order_t *)a_order)); + dap_chain_net_srv_order_t *l_order = (dap_chain_net_srv_order_t *)a_order; + size_t l_order_size = dap_chain_net_srv_order_get_size((dap_chain_net_srv_order_t *)a_order); + if (l_order->version > 3 || l_order->direction > SERV_DIR_SELL || l_order_size != a_order_size) + return NULL; + if (l_order->version == 3) + return DAP_DUP_SIZE(a_order, l_order_size); dap_chain_net_srv_order_old_t *l_old = (dap_chain_net_srv_order_old_t *)a_order; size_t l_ret_size = dap_chain_net_srv_order_get_size((dap_chain_net_srv_order_t *)l_old) + sizeof(dap_chain_net_srv_order_t) - sizeof(dap_chain_net_srv_order_old_t); @@ -437,10 +441,8 @@ int dap_chain_net_srv_order_find_all_by(dap_chain_net_t * a_net,const dap_chain_ size_t l_orders_size = 0; for (size_t i = 0; i < l_orders_count; i++) { DAP_DEL_Z(l_order); - l_order = dap_chain_net_srv_order_read(l_orders[i].value); - size_t l_order_size = dap_chain_net_srv_order_get_size((dap_chain_net_srv_order_t *)l_orders[i].value); - if (l_order->version > 3 || l_order->direction > SERV_DIR_SELL || - l_order_size != l_orders[i].value_len) { + l_order = dap_chain_net_srv_order_read(l_orders[i].value, l_orders[i].value_len); + if (!l_order) { dap_chain_global_db_gr_del(l_orders[i].key, l_gdb_group_str); continue; // order is corrupted } diff --git a/modules/net/srv/include/dap_chain_net_srv.h b/modules/net/srv/include/dap_chain_net_srv.h index 4c9dc61140..ecbc6070ef 100755 --- a/modules/net/srv/include/dap_chain_net_srv.h +++ b/modules/net/srv/include/dap_chain_net_srv.h @@ -285,6 +285,7 @@ dap_chain_datum_tx_receipt_t * dap_chain_net_srv_issue_receipt(dap_chain_net_srv dap_chain_net_srv_price_t * a_price, const void * a_ext, size_t a_ext_size); uint8_t dap_stream_ch_chain_net_srv_get_id(); +int dap_chain_net_srv_parse_pricelist(dap_chain_net_srv_t *a_srv, const char *a_config_section); DAP_STATIC_INLINE const char * dap_chain_net_srv_price_unit_uid_to_str( dap_chain_net_srv_price_unit_uid_t a_uid ) { @@ -294,6 +295,16 @@ DAP_STATIC_INLINE const char * dap_chain_net_srv_price_unit_uid_to_str( dap_chai case SERV_UNIT_MB: return "MEGABYTE"; case SERV_UNIT_SEC: return "SECOND"; case SERV_UNIT_DAY: return "DAY"; + case SERV_UNIT_PCS: return "PIECES"; default: return "UNKNOWN"; } } + +DAP_STATIC_INLINE dap_chain_net_srv_uid_compare(dap_chain_net_srv_uid_t a, dap_chain_net_srv_uid_t b) +{ +#if DAP_CHAIN_NET_SRV_UID_SIZE == 8 + return a.uint64 == b.uint64; +#else // DAP_CHAIN_NET_SRV_UID_SIZE == 16 + return !memcmp(&a, &b, DAP_CHAIN_NET_SRV_UID_SIZE); +#endif +} diff --git a/modules/service/datum/dap_chain_net_srv_datum.c b/modules/service/datum/dap_chain_net_srv_datum.c index 22298f28a1..9b209bec77 100644 --- a/modules/service/datum/dap_chain_net_srv_datum.c +++ b/modules/service/datum/dap_chain_net_srv_datum.c @@ -33,6 +33,7 @@ #define LOG_TAG "chain_net_srv_datum" +static dap_chain_net_srv *s_srv_datum = NULL; static int s_srv_datum_cli(int argc, char ** argv, char **a_str_reply); void s_order_notficator(void *a_arg, const char a_op_code, const char *a_group, const char *a_key, const void *a_value, const size_t a_value_len); @@ -44,10 +45,12 @@ int dap_chain_net_srv_datum_init() "\tSaving datum from mempool to file.\n\n" "srv_datum -net <chain net name> -chain <chain name> datum load -datum <datum hash>\n" "\tLoad datum custum from file to mempool.\n\n"); - uint16_t l_net_arr_len = 0; - char **l_net_arr_str = dap_config_get_array_str(g_config, "srv_datum", "networks", &l_net_arr_len); - for (int i = 0; i < l_net_arr_len; i++) { - dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_arr_str[i]); + s_srv_datum = DAP_NEW_Z(dap_chain_net_srv_t); + s_srv_datum->uid.uint64 = DAP_CHAIN_NET_SRV_DATUM_ID; + int l_net_count = dap_chain_net_srv_parse_pricelist(s_srv_datum, "srv_datum"); + dap_chain_net_srv_price_t *l_price; + DL_FOREACH(s_srv_datum->pricelist, l_price) { + dap_chain_net_t *l_net = l_price->net; if (!l_net) continue; dap_chain_net_srv_order_add_notify_callback(l_net, s_order_notficator, l_net); @@ -181,12 +184,37 @@ static int s_srv_datum_cli(int argc, char ** argv, char **a_str_reply) { void s_order_notficator(void *a_arg, const char a_op_code, const char *a_group, const char *a_key, const void *a_value, const size_t a_value_len) { + if (a_op_code == DAP_DB$K_OPTYPE_DEL) + return; dap_chain_net_t *l_net = (dap_chain_net_t *)a_arg; - dap_chain_net_srv_order_t *l_order = (dap_chain_net_srv_order_t *)a_value; + dap_chain_net_srv_order_t *l_order = dap_chain_net_srv_order_read(a_value); // Old format comliance + if (!l_order) { + dap_chain_global_db_gr_del(a_key, a_group); + return; // order is corrupted + } + if (!dap_chain_net_srv_uid_compare(l_order->srv_uid, s_srv_datum->uid)) + return; // order from another service + dap_chain_net_srv_price_t *l_price = NULL; + DL_FOREACH(s_srv_datum->pricelist, l_price) { + if (l_price->net == l_net) + break; + } + if (!l_price || l_price->net != l_net) { + log_it(L_DEBUG, "Price for net %s is not set", l_net->pub.name); + return; // price not set for this network + } + if ((l_order->price_unit != SERV_UNIT_PCS) || (l_order->direction != SERV_DIR_BUY) || + (strncmp(l_order->price_ticker, l_price->token, DAP_CHAIN_TICKER_SIZE_MAX)) || + (!compare256(l_order->price, l_price->value_datoshi))) { + log_it(L_DEBUG, "Price from order (%s) is not equal to price from service pricelist (%s)", + dap_chain_balance_to_coins(l_order->price), dap_chain_balance_to_coins(l_price->value_datoshi)); + return; // price from order is not equal with service price + } char l_tx_cond_hash_str[DAP_CHAIN_HASH_FAST_STR_SIZE]; dap_chain_hash_fast_to_str(&l_order->tx_cond_hash, l_tx_cond_hash_str, DAP_CHAIN_HASH_FAST_STR_SIZE); dap_chain_t *l_chain; dap_chain_datum_t *l_datum = NULL; + dap_chain_datum_tx_t *l_tx_cond = NULL; DL_FOREACH(l_net->pub.chains, l_chain) { size_t l_datum_size; char *l_gdb_group = dap_chain_net_get_gdb_group_mempool(l_chain); @@ -194,8 +222,23 @@ void s_order_notficator(void *a_arg, const char a_op_code, const char *a_group, if (l_datum) break; } - if (!l_datum) { - log_it(L_DEBUG, "Invalid tx cond hash"); + if (l_datum) + l_tx_cond = (dap_chain_datum_tx_t *)l_datum->data; + else + l_tx_cond = dap_chain_ledger_tx_find_by_hash(l_net->pub.ledger, &l_order->tx_cond_hash); + if (!l_tx_cond) { + log_it(L_DEBUG, "Invalid tx cond datum hash"); + return; + } + dap_chain_tx_out_cond_t *l_cond_out = (dap_chain_tx_out_cond_t *) + dap_chain_datum_tx_item_get(l_tx_cond, NULL, TX_ITEM_TYPE_OUT_COND, &l_tx_out_cond_size); + if (!l_cond_out || l_cond_out->header.subtype != DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_PAY) { + log_it(L_DEBUG, "Condition with required subtype SRV_PAY not found in requested tx"); + } + dap_hash_fast_t l_sign_hash; + if (!dap_sign_get_pkey_hash(l_order->ext_n_sign[l_order->ext_size], &l_sign_hash)) { + log_it(L_DEBUG, "Wrong order sign"); + return; } } -- GitLab