From dc8c74d46eb48bb1da7e556e5162f34b8d510094 Mon Sep 17 00:00:00 2001 From: "pavel.uhanov" <pavel.uhanov@demlabs.net> Date: Wed, 19 Feb 2025 06:39:27 +0000 Subject: [PATCH] backport-13637 --- modules/chain/tests/dap_chain_ledger_tests.c | 10 +- .../dap_stream_ch_chain_net_srv.c | 2 +- .../chain-net/dap_stream_ch_chain_net.c | 2 +- modules/common/dap_chain_datum_decree.c | 54 ++- modules/common/dap_chain_datum_token.c | 2 +- modules/common/dap_chain_datum_tx_items.c | 22 +- modules/common/dap_chain_datum_tx_receipt.c | 2 +- .../common/include/dap_chain_datum_decree.h | 11 +- .../common/include/dap_chain_datum_tx_items.h | 6 +- .../include/dap_chain_datum_tx_out_cond.h | 1 + .../consensus/esbocs/dap_chain_cs_esbocs.c | 8 +- modules/net/dap_chain_ledger.c | 36 ++ modules/net/dap_chain_net_decree.c | 15 +- modules/net/dap_chain_net_tx.c | 11 +- modules/net/dap_chain_node_cli_cmd.c | 5 +- modules/net/dap_chain_node_cli_cmd_tx.c | 6 +- modules/net/include/dap_chain_ledger.h | 3 +- modules/net/srv/dap_chain_net_srv_order.c | 2 +- .../dap_chain_net_srv_stake_pos_delegate.c | 336 ++++++++++++++++-- .../dap_chain_net_srv_stake_pos_delegate.h | 4 +- modules/type/blocks/dap_chain_block.c | 2 +- modules/type/blocks/dap_chain_cs_blocks.c | 2 +- modules/type/dag/dap_chain_cs_dag_event.c | 6 +- modules/wallet/dap_chain_wallet.c | 10 +- modules/wallet/include/dap_chain_wallet.h | 2 + 25 files changed, 482 insertions(+), 78 deletions(-) diff --git a/modules/chain/tests/dap_chain_ledger_tests.c b/modules/chain/tests/dap_chain_ledger_tests.c index 0a2bd59726..e3b22cdbea 100644 --- a/modules/chain/tests/dap_chain_ledger_tests.c +++ b/modules/chain/tests/dap_chain_ledger_tests.c @@ -41,8 +41,7 @@ dap_chain_datum_token_t *dap_ledger_test_create_datum_update(dap_cert_t *a_cert, l_token = DAP_REALLOC(l_token, sizeof(dap_chain_datum_token_t) + a_size_tsd_section); memcpy(l_token->tsd_n_signs, a_tsd_section, a_size_tsd_section); } - dap_sign_t * l_sign = dap_cert_sign(a_cert,l_token, - sizeof(*l_token) + a_size_tsd_section, 0); + dap_sign_t * l_sign = dap_cert_sign(a_cert, l_token, sizeof(*l_token) + a_size_tsd_section); if (l_sign) { size_t l_sign_size = dap_sign_get_size(l_sign); l_token = DAP_REALLOC(l_token, sizeof(dap_chain_datum_token_t) + a_size_tsd_section + l_sign_size); @@ -76,8 +75,7 @@ dap_chain_datum_token_t *dap_ledger_test_create_datum_decl(dap_cert_t *a_cert, l_token = DAP_REALLOC(l_token, sizeof(dap_chain_datum_token_t) + a_size_tsd_section); memcpy(l_token->tsd_n_signs, a_tsd_section, a_size_tsd_section); } - dap_sign_t * l_sign = dap_cert_sign(a_cert,l_token, - sizeof(*l_token) + a_size_tsd_section, 0); + dap_sign_t * l_sign = dap_cert_sign(a_cert, l_token, sizeof(*l_token) + a_size_tsd_section); if (l_sign) { size_t l_sign_size = dap_sign_get_size(l_sign); l_token = DAP_REALLOC(l_token, sizeof(dap_chain_datum_token_t) + a_size_tsd_section + l_sign_size); @@ -363,7 +361,7 @@ int dap_ledger_test_create_reward_decree(dap_chain_t *a_chain, dap_chain_net_id_ l_tsd->size = sizeof(uint256_t); *(uint256_t*)(l_tsd->data) = a_value; // Sign it - dap_sign_t *l_sign = dap_cert_sign(a_cert, l_decree, l_decree_size, 0); + dap_sign_t *l_sign = dap_cert_sign(a_cert, l_decree, l_decree_size); if (!l_sign) { DAP_DELETE(l_decree); return -2; @@ -912,7 +910,7 @@ void dap_ledger_test_write_back_list(dap_ledger_t *a_ledger, dap_cert_t *a_cert, // memcpy(l_datum_token_update->tsd_n_signs + l_offset, l_tsd_dis_flags, dap_tsd_size(l_tsd_dis_flags)); // l_offset += dap_tsd_size(l_tsd_dis_flags); // dap_sign_t * l_sign = dap_cert_sign(a_cert, l_datum_token_update, -// sizeof(*l_datum_token_update) - sizeof(uint16_t), 0); +// sizeof(*l_datum_token_update) - sizeof(uint16_t)); // if (l_sign) { // size_t l_sign_size = dap_sign_get_size(l_sign); // l_datum_token_update = DAP_REALLOC(l_datum_token_update, sizeof(dap_chain_datum_token_t) + l_offset + l_sign_size); diff --git a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c index 116237d740..4d58731978 100644 --- a/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c +++ b/modules/channel/chain-net-srv/dap_stream_ch_chain_net_srv.c @@ -1265,7 +1265,7 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void *a_arg) } pkt_test_t *l_request = (pkt_test_t*)l_ch_pkt->data; if (dap_chain_net_srv_get(l_request->srv_uid) == NULL){ - log_it(L_WARNING, "Can't find service with id %"DAP_UINT64_FORMAT_U, l_request->srv_uid); + log_it(L_WARNING, "Can't find service with id %"DAP_UINT64_FORMAT_U, l_request->srv_uid.uint64); l_err.code = DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR_CODE_SERVICE_NOT_FOUND; dap_stream_ch_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_NET_SRV_PKT_TYPE_RESPONSE_ERROR, &l_err, sizeof(l_err)); return false; diff --git a/modules/channel/chain-net/dap_stream_ch_chain_net.c b/modules/channel/chain-net/dap_stream_ch_chain_net.c index a5b86b1dd2..8a9669782a 100644 --- a/modules/channel/chain-net/dap_stream_ch_chain_net.c +++ b/modules/channel/chain-net/dap_stream_ch_chain_net.c @@ -231,7 +231,7 @@ static bool s_stream_ch_packet_in(dap_stream_ch_t *a_ch, void* a_arg) if (l_enc_key_pvt) { flags = flags | F_CERT;//faund sert - l_sign = dap_sign_create(l_enc_key_pvt, (uint8_t*)l_ch_chain_net_pkt->data, l_ch_chain_net_pkt->hdr.data_size, 0); + l_sign = dap_sign_create(l_enc_key_pvt, (uint8_t*)l_ch_chain_net_pkt->data, l_ch_chain_net_pkt->hdr.data_size); if (l_sign) { sign_s = dap_sign_get_size(l_sign); flags = flags | D_SIGN;//data signed diff --git a/modules/common/dap_chain_datum_decree.c b/modules/common/dap_chain_datum_decree.c index 007bfdc1bb..2f61eab671 100644 --- a/modules/common/dap_chain_datum_decree.c +++ b/modules/common/dap_chain_datum_decree.c @@ -39,6 +39,25 @@ #define LOG_TAG "dap_chain_datum_decree" + +static bool s_find_pkey(dap_chain_datum_decree_t *a_decree, dap_pkey_t *a_pkey) +{ + dap_return_val_if_pass(!a_decree || !a_pkey || !a_pkey->header.size, false); + dap_sign_t *l_signs_section = (dap_sign_t*)(a_decree->data_n_signs + a_decree->header.data_size); + size_t l_sign_size = 0; + bool l_ret = false; + for (uint64_t l_offset = 0; !l_ret && l_offset + sizeof(dap_sign_t) < a_decree->header.signs_size; l_offset += l_sign_size) { + dap_sign_t *l_sign = (dap_sign_t *)(a_decree->data_n_signs + a_decree->header.data_size + l_offset); + l_sign_size = dap_sign_get_size(l_sign); + if (l_offset + l_sign_size <= l_offset || l_offset + l_sign_size > a_decree->header.signs_size) + break; + size_t l_pkey_ser_size = 0; + const uint8_t *l_pkey_ser = dap_sign_get_pkey(l_sign, &l_pkey_ser_size); + l_ret = (l_pkey_ser_size == a_pkey->header.size) && !memcmp(l_pkey_ser, a_pkey->pkey, l_pkey_ser_size); + } + return l_ret; +} + dap_sign_t *dap_chain_datum_decree_get_signs(dap_chain_datum_decree_t *a_decree, size_t* a_signs_size) { dap_return_val_if_fail(a_decree && a_signs_size, NULL); @@ -149,6 +168,20 @@ int dap_chain_datum_decree_get_ban_addr(dap_chain_datum_decree_t *a_decree, cons return l_tsd ? ( *a_addr = dap_tsd_get_string_const(l_tsd), !dap_strcmp(*a_addr, DAP_TSD_CORRUPTED_STRING) ) : 1; } +/** + * @brief get pkey from decree tsd + * @param a_decree + * @return pointer to dap_pkey_t if find, if not or error - NULL + */ +dap_pkey_t *dap_chain_datum_decree_get_pkey(dap_chain_datum_decree_t *a_decree) +{ + dap_return_val_if_fail(a_decree, NULL); + dap_tsd_t *l_tsd = dap_tsd_find(a_decree->data_n_signs, a_decree->header.data_size, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_PKEY); + if (!l_tsd) + return NULL; + return dap_pkey_get_size((dap_pkey_t *)l_tsd->data) == l_tsd->size ? (dap_pkey_t *)l_tsd->data : NULL; +} + void dap_chain_datum_decree_dump_json(json_object *a_json_out, dap_chain_datum_decree_t *a_decree, size_t a_decree_size, const char *a_hash_out_type) { char *l_type_str; @@ -309,6 +342,13 @@ void dap_chain_datum_decree_dump_json(json_object *a_json_out, dap_chain_datum_d dap_sign_type_t l_sign_type = { .type = l_type }; json_object_object_add(a_json_out, "Signature type", json_object_new_string(dap_sign_type_to_str(l_sign_type))); break; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_PKEY: + if (l_tsd->size != dap_pkey_get_size((dap_pkey_t *)(l_tsd->data))) { + json_object_object_add(a_json_out, "pkey type", json_object_new_string("WRONG SIZE")); + break; + } + json_object_object_add(a_json_out, "pkey type", json_object_new_string( dap_pkey_type_to_str(((dap_pkey_t *)(l_tsd->data))->header.type) )); + break; default: json_object_object_add(a_json_out, "UNKNOWN_TYPE_TSD_SECTION", json_object_new_string("")); break; @@ -376,10 +416,18 @@ dap_chain_datum_decree_t *dap_chain_datum_decree_sign_in_cycle(dap_cert_t **a_ce { size_t l_cur_sign_offset = a_datum_decree->header.data_size + a_datum_decree->header.signs_size; size_t l_total_signs_size = a_datum_decree->header.signs_size, l_total_sign_count = 0; - for(size_t i = 0; i < a_certs_count; i++) { - dap_sign_t * l_sign = dap_cert_sign(a_certs[i], a_datum_decree, - sizeof(dap_chain_datum_decree_t) + a_datum_decree->header.data_size, 0); + dap_pkey_t *l_cur_pkey = dap_cert_to_pkey(a_certs[i]); + if (s_find_pkey(a_datum_decree, l_cur_pkey)) { + dap_chain_hash_fast_t l_pkey_hash = { }; + dap_pkey_get_hash(l_cur_pkey, &l_pkey_hash); + log_it(L_ERROR, "Sign with %s pkey already exist in decree", dap_hash_fast_to_str_static(&l_pkey_hash)); + DAP_DELETE(l_cur_pkey); + continue;; + } + DAP_DELETE(l_cur_pkey); + dap_sign_t *l_sign = dap_cert_sign(a_certs[i], a_datum_decree, + sizeof(dap_chain_datum_decree_t) + a_datum_decree->header.data_size); if (!l_sign) { log_it(L_ERROR, "Decree signing failed"); DAP_DELETE(a_datum_decree); diff --git a/modules/common/dap_chain_datum_token.c b/modules/common/dap_chain_datum_token.c index cd066fca13..423e44a0ff 100644 --- a/modules/common/dap_chain_datum_token.c +++ b/modules/common/dap_chain_datum_token.c @@ -427,7 +427,7 @@ dap_chain_datum_token_emission_t *dap_chain_datum_emission_add_sign(dap_enc_key_ } a_emission->data.type_auth.signs_count = 0; a_emission->data.type_auth.tsd_n_signs_size = 0; - dap_sign_t *l_new_sign = dap_sign_create(a_sign_key, a_emission, sizeof(dap_chain_datum_token_emission_t) + a_emission->data.type_auth.tsd_total_size, 0); + dap_sign_t *l_new_sign = dap_sign_create(a_sign_key, a_emission, sizeof(dap_chain_datum_token_emission_t) + a_emission->data.type_auth.tsd_total_size); if (!l_new_sign) return NULL; size_t l_emission_size = dap_chain_datum_emission_get_size((uint8_t *)a_emission); diff --git a/modules/common/dap_chain_datum_tx_items.c b/modules/common/dap_chain_datum_tx_items.c index e47b0c38b5..b694961e23 100644 --- a/modules/common/dap_chain_datum_tx_items.c +++ b/modules/common/dap_chain_datum_tx_items.c @@ -307,12 +307,15 @@ dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_xchange(dap dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_stake(dap_chain_net_srv_uid_t a_srv_uid, uint256_t a_value, dap_chain_addr_t *a_signing_addr, dap_chain_node_addr_t *a_signer_node_addr, - dap_chain_addr_t *a_sovereign_addr, uint256_t a_sovereign_tax) + dap_chain_addr_t *a_sovereign_addr, uint256_t a_sovereign_tax, dap_pkey_t *a_pkey) { if (IS_ZERO_256(a_value)) return NULL; - size_t l_tsd_total_size = a_sovereign_addr && !dap_chain_addr_is_blank(a_sovereign_addr) ? - dap_chain_datum_tx_item_out_cond_create_srv_stake_get_tsd_size() : 0; + bool l_tsd_sovereign_addr = a_sovereign_addr && !dap_chain_addr_is_blank(a_sovereign_addr); + // size_t l_pkey_size = dap_pkey_get_size(a_pkey); commited only for release 5.3 and less + size_t l_pkey_size = 0; + size_t l_tsd_total_size = dap_chain_datum_tx_item_out_cond_create_srv_stake_get_tsd_size(l_tsd_sovereign_addr, l_pkey_size); + 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; @@ -322,8 +325,15 @@ dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_stake(dap_c l_item->subtype.srv_stake_pos_delegate.signer_node_addr = *a_signer_node_addr; if (l_tsd_total_size) { l_item->tsd_size = l_tsd_total_size; - byte_t *l_next_tsd_ptr = dap_tsd_write(l_item->tsd, DAP_CHAIN_TX_OUT_COND_TSD_ADDR, a_sovereign_addr, sizeof(*a_sovereign_addr)); - dap_tsd_write(l_next_tsd_ptr, DAP_CHAIN_TX_OUT_COND_TSD_VALUE, &a_sovereign_tax, sizeof(a_sovereign_tax)); + byte_t *l_next_tsd_ptr = l_item->tsd; + if (l_tsd_sovereign_addr) { + l_next_tsd_ptr = dap_tsd_write(l_next_tsd_ptr, DAP_CHAIN_TX_OUT_COND_TSD_ADDR, a_sovereign_addr, sizeof(*a_sovereign_addr)); + l_next_tsd_ptr = dap_tsd_write(l_next_tsd_ptr, DAP_CHAIN_TX_OUT_COND_TSD_VALUE, &a_sovereign_tax, sizeof(a_sovereign_tax)); + } + if (l_pkey_size) { + dap_tsd_write(l_next_tsd_ptr, DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_ADD, a_pkey, l_pkey_size); + l_item->subtype.srv_stake_pos_delegate.flags = DAP_SIGN_ADD_PKEY_HASHING_FLAG(l_item->subtype.srv_stake_pos_delegate.flags); + } } return l_item; } @@ -396,7 +406,7 @@ dap_sign_t *dap_chain_datum_tx_sign_create(dap_enc_key_t *a_key, const dap_chain : a_tx->header.tx_items_size); dap_chain_datum_tx_t *l_tx = DAP_DUP_SIZE_RET_VAL_IF_FAIL((dap_chain_datum_tx_t *)a_tx, l_tx_size, NULL); l_tx->header.tx_items_size = 0; - dap_sign_t *ret = dap_sign_create(a_key, l_tx, l_tx_size, 0); + dap_sign_t *ret = dap_sign_create(a_key, l_tx, l_tx_size); DAP_DELETE(l_tx); return ret; } diff --git a/modules/common/dap_chain_datum_tx_receipt.c b/modules/common/dap_chain_datum_tx_receipt.c index f677b34c07..7a97c20d1a 100644 --- a/modules/common/dap_chain_datum_tx_receipt.c +++ b/modules/common/dap_chain_datum_tx_receipt.c @@ -71,7 +71,7 @@ dap_chain_datum_tx_receipt_t *dap_chain_datum_tx_receipt_sign_add(dap_chain_datu return NULL; } - dap_sign_t *l_sign = dap_sign_create(a_key, &a_receipt->receipt_info, sizeof(a_receipt->receipt_info), 0); + dap_sign_t *l_sign = dap_sign_create(a_key, &a_receipt->receipt_info, sizeof(a_receipt->receipt_info)); size_t l_sign_size = l_sign ? dap_sign_get_size(l_sign) : 0; if (!l_sign || !l_sign_size) { log_it(L_ERROR, "Can't sign the receipt, may be smth with key?"); diff --git a/modules/common/include/dap_chain_datum_decree.h b/modules/common/include/dap_chain_datum_decree.h index 19e956cbbd..f8a49f0a39 100644 --- a/modules/common/include/dap_chain_datum_decree.h +++ b/modules/common/include/dap_chain_datum_decree.h @@ -75,6 +75,7 @@ DAP_STATIC_INLINE size_t dap_chain_datum_decree_get_size(dap_chain_datum_decree_ #define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_MAX_WEIGHT 0x000C #define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_EMERGENCY_VALIDATORS 0x000D #define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_CHECK_SIGNS_STRUCTURE 0x000E +#define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_PKEY_UPDATE 0x0010 // DECREE TSD types #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE 0x0100 @@ -93,6 +94,7 @@ DAP_STATIC_INLINE size_t dap_chain_datum_decree_get_size(dap_chain_datum_decree_ #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STRING 0x0115 #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_ACTION 0x010A #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGNATURE_TYPE 0x010B +#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_PKEY 0x010D #ifdef __cplusplus @@ -128,6 +130,8 @@ DAP_STATIC_INLINE const char *dap_chain_datum_decree_subtype_to_str(uint16_t a_d return "DECREE_COMMON_SUBTYPE_EMERGENCY_VALIDATORS"; case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_CHECK_SIGNS_STRUCTURE: return "DECREE_COMMON_SUBTYPE_CHECK_SIGNS_STRUCTURE"; + case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_PKEY_UPDATE: + return "DECREE_COMMON_SUBTYPE_STAKE_UPDATE"; default: return "DECREE_SUBTYPE_UNKNOWN"; } @@ -160,6 +164,8 @@ DAP_STATIC_INLINE uint16_t dap_chain_datum_decree_type_from_str(const char *a_de return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_EMERGENCY_VALIDATORS; } else if (!dap_strcmp(a_decree_type, "check_signs_structure")) { return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_CHECK_SIGNS_STRUCTURE; + } else if (!dap_strcmp(a_decree_type, "stake_update")) { + return DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_PKEY_UPDATE; } else { return 0; } @@ -199,6 +205,8 @@ DAP_STATIC_INLINE const char *dap_chain_datum_decree_tsd_type_to_str(uint16_t a_ return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_ACTION"; case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGNATURE_TYPE: return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_SIGNATURE_TYPE"; + case DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_PKEY: + return "DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_PKEY"; default: return "DECREE_TSD_TYPE_UNKNOWN"; } @@ -306,6 +314,7 @@ int dap_chain_datum_decree_get_stake_min_signers_count(dap_chain_datum_decree_t int dap_chain_datum_decree_get_action(dap_chain_datum_decree_t *a_decree, uint8_t *a_action); int dap_chain_datum_decree_get_signature_type(dap_chain_datum_decree_t *a_decree, uint32_t *a_signature_type); int dap_chain_datum_decree_get_ban_addr(dap_chain_datum_decree_t *a_decree, const char **a_addr); +dap_pkey_t *dap_chain_datum_decree_get_pkey(dap_chain_datum_decree_t *a_decree); /** * @breif dap_chain_datum_decree_dump Dump information about decree @@ -352,4 +361,4 @@ dap_chain_datum_decree_t* dap_chain_datum_decree_sign_in_cycle(dap_cert_t ** a_c #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/modules/common/include/dap_chain_datum_tx_items.h b/modules/common/include/dap_chain_datum_tx_items.h index aaf0f8d5ae..3039494890 100644 --- a/modules/common/include/dap_chain_datum_tx_items.h +++ b/modules/common/include/dap_chain_datum_tx_items.h @@ -192,8 +192,8 @@ dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_xchange(dap const char *a_token, uint256_t a_value_rate, const dap_chain_addr_t *a_seller_addr, const void *a_params, uint32_t a_params_size); -DAP_STATIC_INLINE uint32_t dap_chain_datum_tx_item_out_cond_create_srv_stake_get_tsd_size() { - return sizeof(dap_chain_addr_t) + sizeof(uint256_t) + 2 * sizeof(dap_tsd_t); +DAP_STATIC_INLINE uint32_t dap_chain_datum_tx_item_out_cond_create_srv_stake_get_tsd_size(bool a_sovereign_addr, uint32_t a_pkey_size) { + return (a_sovereign_addr ? sizeof(dap_chain_addr_t) + sizeof(uint256_t) + 2 * sizeof(dap_tsd_t) : 0) + (a_pkey_size ? a_pkey_size + sizeof(dap_tsd_t) : 0); } /** @@ -203,7 +203,7 @@ DAP_STATIC_INLINE uint32_t dap_chain_datum_tx_item_out_cond_create_srv_stake_get */ dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_stake(dap_chain_net_srv_uid_t a_srv_uid, uint256_t a_value, dap_chain_addr_t *a_signing_addr, dap_chain_node_addr_t *a_signer_node_addr, - dap_chain_addr_t *a_sovereign_addr, uint256_t a_sovereign_tax); + dap_chain_addr_t *a_sovereign_addr, uint256_t a_sovereign_tax, dap_pkey_t *a_pkey); // Create cond out dap_chain_tx_out_cond_t *dap_chain_datum_tx_item_out_cond_create_srv_stake_lock(dap_chain_net_srv_uid_t a_srv_uid, 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 b5988638c9..1014316a43 100644 --- a/modules/common/include/dap_chain_datum_tx_out_cond.h +++ b/modules/common/include/dap_chain_datum_tx_out_cond.h @@ -105,6 +105,7 @@ typedef struct dap_chain_tx_out_cond { dap_chain_addr_t signing_addr; // Node address of signer with this stake dap_chain_node_addr_t signer_node_addr; + uint32_t flags; } DAP_ALIGN_PACKED srv_stake_pos_delegate; struct { dap_time_t time_unlock; diff --git a/modules/consensus/esbocs/dap_chain_cs_esbocs.c b/modules/consensus/esbocs/dap_chain_cs_esbocs.c index 099d9b29d3..72a7bc2212 100644 --- a/modules/consensus/esbocs/dap_chain_cs_esbocs.c +++ b/modules/consensus/esbocs/dap_chain_cs_esbocs.c @@ -298,7 +298,7 @@ static int s_callback_new(dap_chain_t *a_chain, dap_config_t *a_chain_cfg) dap_hash_fast_t l_stake_tx_hash = {}; uint256_t l_weight = dap_chain_net_srv_stake_get_allowed_min_value(a_chain->net_id); dap_chain_net_srv_stake_key_delegate(l_net, &l_signing_addr, &l_stake_tx_hash, - l_weight, &l_signer_node_addr); + l_weight, &l_signer_node_addr, dap_pkey_from_enc_key(l_cert_cur->enc_key)); } } if (!i) @@ -728,7 +728,7 @@ int dap_chain_esbocs_set_min_validators_count(dap_chain_t *a_chain, uint16_t a_n for (dap_list_t *it = l_esbocs_pvt->poa_validators; it; it = it->next) { dap_chain_esbocs_validator_t *l_validator = it->data; dap_chain_net_srv_stake_key_delegate(l_net, &l_validator->signing_addr, &l_stake_tx_hash, - l_weight, &l_validator->node_addr); + l_weight, &l_validator->node_addr, NULL); } l_esbocs_pvt->min_validators_count = l_esbocs_pvt->start_validators_min; } @@ -2519,7 +2519,7 @@ static void s_session_packet_in(dap_chain_esbocs_session_t *a_session, dap_chain l_message->hdr.attempt_num, l_candidate_hash_str); size_t l_offset = dap_chain_block_get_sign_offset(l_store->candidate, l_store->candidate_size); dap_sign_t *l_candidate_sign = dap_sign_create(PVT(l_session->esbocs)->blocks_sign_key, - l_store->candidate, l_offset + sizeof(l_store->candidate->hdr), 0); + l_store->candidate, l_offset + sizeof(l_store->candidate->hdr)); size_t l_candidate_sign_size = dap_sign_get_size(l_candidate_sign); s_message_send(l_session, DAP_CHAIN_ESBOCS_MSG_TYPE_COMMIT_SIGN, l_candidate_hash, l_candidate_sign, l_candidate_sign_size, l_session->cur_round.validators_list); @@ -2724,7 +2724,7 @@ static void s_message_send(dap_chain_esbocs_session_t *a_session, uint8_t a_mess NODE_ADDR_FP_ARGS_S(l_validator->node_addr)); l_message->hdr.recv_addr = l_validator->node_addr; l_message->hdr.sign_size = 0; - dap_sign_t *l_sign = dap_sign_create( PVT(a_session->esbocs)->blocks_sign_key, l_message, l_message_size, 0 ); + dap_sign_t *l_sign = dap_sign_create( PVT(a_session->esbocs)->blocks_sign_key, l_message, l_message_size); size_t l_sign_size = dap_sign_get_size(l_sign); l_message->hdr.sign_size = l_sign_size; dap_chain_esbocs_message_t *l_message_signed = DAP_REALLOC_RET_IF_FAIL(l_message, l_message_size + l_sign_size, l_sign, l_message); diff --git a/modules/net/dap_chain_ledger.c b/modules/net/dap_chain_ledger.c index bff172b625..adf20db1bc 100644 --- a/modules/net/dap_chain_ledger.c +++ b/modules/net/dap_chain_ledger.c @@ -5923,3 +5923,39 @@ dap_chain_token_ticker_str_t dap_ledger_tx_calculate_main_ticker_(dap_ledger_t * *a_ledger_rc = l_rc; return l_ret; } + +/** + * @brief dap_ledger_find_pkey_by_hash + * @param a_ledger to search + * @param a_pkey_hash - pkey hash + * @return pointer to dap_pkey_t if finded, other - NULL + */ +dap_pkey_t *dap_ledger_find_pkey_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_pkey_hash) +{ + dap_return_val_if_pass(!a_pkey_hash || dap_hash_fast_is_blank(a_pkey_hash), NULL); + + dap_ledger_private_t *l_ledger_pvt = PVT(a_ledger); + dap_ledger_tx_item_t *l_iter_current, *l_item_tmp; + dap_pkey_t *l_ret = NULL; + 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; + // 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_sign_get_sig(l_tx_sig); + if(l_sig) { + // compare public key in transaction with a_public_key + dap_chain_hash_fast_t l_sign_hash = {}; + dap_sign_get_pkey_hash(l_sig, &l_sign_hash); + if(!memcmp(&l_sign_hash, a_pkey_hash, sizeof(dap_chain_hash_fast_t))) { + l_ret = dap_pkey_get_from_sign(l_sig); + break; + } + } + } + pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock); + return l_ret; +} diff --git a/modules/net/dap_chain_net_decree.c b/modules/net/dap_chain_net_decree.c index 97f53dabd7..509e4e6af5 100644 --- a/modules/net/dap_chain_net_decree.c +++ b/modules/net/dap_chain_net_decree.c @@ -451,7 +451,20 @@ static int s_common_decree_handler(dap_chain_datum_decree_t *a_decree, dap_chain } if (!a_apply) break; - dap_chain_net_srv_stake_key_delegate(a_net, &l_addr, &l_hash, l_value, &l_node_addr); + + dap_chain_net_srv_stake_key_delegate(a_net, &l_addr, &l_hash, l_value, &l_node_addr, dap_chain_datum_decree_get_pkey(a_decree)); + break; + case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_PKEY_UPDATE: + if (!a_anchored) + break; + if (!a_apply) + break; + dap_pkey_t *l_pkey = NULL; + if (! (l_pkey = dap_chain_datum_decree_get_pkey(a_decree)) ){ + log_it(L_WARNING,"Can't get pkey from decree."); + return -105; + } + dap_chain_net_srv_stake_pkey_update(a_net, l_pkey); break; case DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_INVALIDATE: { if (dap_chain_datum_decree_get_stake_signing_addr(a_decree, &l_addr)){ diff --git a/modules/net/dap_chain_net_tx.c b/modules/net/dap_chain_net_tx.c index a93a1fac68..addcb27c56 100644 --- a/modules/net/dap_chain_net_tx.c +++ b/modules/net/dap_chain_net_tx.c @@ -1128,10 +1128,10 @@ int dap_chain_net_tx_create_by_json(json_object *a_tx_json, dap_chain_net_t *a_n const char *l_signing_addr_str = s_json_get_text(l_json_item_obj, "signing_addr"); dap_chain_addr_t *l_signing_addr = dap_chain_addr_from_str(l_signing_addr_str); if(!l_signing_addr) { - { log_it(L_ERROR, "Json TX: bad signing_addr in OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE"); break; - } + } + dap_chain_node_addr_t l_signer_node_addr; const char *l_node_addr_str = s_json_get_text(l_json_item_obj, "node_addr"); if(!l_node_addr_str || dap_chain_node_addr_from_str(&l_signer_node_addr, l_node_addr_str)) { @@ -1139,7 +1139,8 @@ int dap_chain_net_tx_create_by_json(json_object *a_tx_json, dap_chain_net_t *a_n break; } dap_chain_tx_out_cond_t *l_out_cond_item = dap_chain_datum_tx_item_out_cond_create_srv_stake(l_srv_uid, l_value, l_signing_addr, - &l_signer_node_addr, NULL, uint256_0); + &l_signer_node_addr, NULL, uint256_0, NULL); + DAP_DELETE(l_signing_addr); l_item = (const uint8_t*) l_out_cond_item; // Save value for using in In item if(l_item) { @@ -1149,8 +1150,8 @@ int dap_chain_net_tx_create_by_json(json_object *a_tx_json, dap_chain_net_t *a_n "can of type %s described in item %zu.", l_subtype_str, i); json_object *l_jobj_err = json_object_new_string(l_err_str); DAP_DELETE(l_err_str); - if (l_jobj_errors) json_object_array_add(l_jobj_errors, l_jobj_err); - } + if (l_jobj_errors) + json_object_array_add(l_jobj_errors, l_jobj_err); } } break; diff --git a/modules/net/dap_chain_node_cli_cmd.c b/modules/net/dap_chain_node_cli_cmd.c index 62a0a69108..a5db76bcfe 100644 --- a/modules/net/dap_chain_node_cli_cmd.c +++ b/modules/net/dap_chain_node_cli_cmd.c @@ -2317,8 +2317,7 @@ static dap_chain_datum_token_t * s_sign_cert_in_cycle(dap_cert_t ** l_certs, dap for(size_t i = 0; i < l_certs_count; i++) { - dap_sign_t * l_sign = dap_cert_sign(l_certs[i], l_datum_token, - sizeof(*l_datum_token) + l_tsd_size, 0); + dap_sign_t * l_sign = dap_cert_sign(l_certs[i], l_datum_token, sizeof(*l_datum_token) + l_tsd_size); if (l_sign) { size_t l_sign_size = dap_sign_get_size(l_sign); dap_chain_datum_token_t *l_datum_token_new @@ -7842,7 +7841,7 @@ static int s_sign_file(const char *a_filename, dap_sign_signer_file_t a_flags, c DAP_DELETE(l_buffer); return -8; } - *a_signed = dap_sign_create(l_cert->enc_key, l_data, l_full_size_for_sign, 0); + *a_signed = dap_sign_create(l_cert->enc_key, l_data, l_full_size_for_sign); if (*a_signed == NULL) { DAP_DELETE(l_buffer); return -9; diff --git a/modules/net/dap_chain_node_cli_cmd_tx.c b/modules/net/dap_chain_node_cli_cmd_tx.c index 9a64adb2fe..0748ba83ce 100644 --- a/modules/net/dap_chain_node_cli_cmd_tx.c +++ b/modules/net/dap_chain_node_cli_cmd_tx.c @@ -1396,8 +1396,7 @@ static dap_chain_datum_anchor_t * s_sign_anchor_in_cycle(dap_cert_t ** a_certs, for(size_t i = 0; i < a_certs_count; i++) { - dap_sign_t * l_sign = dap_cert_sign(a_certs[i], a_datum_anchor, - sizeof(dap_chain_datum_anchor_t) + a_datum_anchor->header.data_size, 0); + dap_sign_t * l_sign = dap_cert_sign(a_certs[i], a_datum_anchor, sizeof(dap_chain_datum_anchor_t) + a_datum_anchor->header.data_size); if (l_sign) { size_t l_sign_size = dap_sign_get_size(l_sign); @@ -1801,8 +1800,7 @@ int cmd_decree(int a_argc, char **a_argv, void **a_str_reply) l_chain?l_chain->name:"<undefined>"); return -5; } - DAP_DELETE(l_datum_hash_hex_str); - DAP_DELETE(l_datum_hash_base58_str); + DAP_DEL_MULTY(l_datum_hash_hex_str, l_datum_hash_base58_str); } else { dap_cli_server_cmd_set_reply_text(a_str_reply, "decree sign need -datum <datum hash> argument"); return -2; diff --git a/modules/net/include/dap_chain_ledger.h b/modules/net/include/dap_chain_ledger.h index ea410925d1..f2e43d962d 100644 --- a/modules/net/include/dap_chain_ledger.h +++ b/modules/net/include/dap_chain_ledger.h @@ -471,7 +471,8 @@ bool dap_ledger_cache_enabled(dap_ledger_t *a_ledger); void dap_ledger_set_cache_tx_check_callback(dap_ledger_t *a_ledger, dap_ledger_cache_tx_check_callback_t a_callback); dap_chain_tx_out_cond_t* dap_chain_ledger_get_tx_out_cond_linked_to_tx_in_cond(dap_ledger_t *a_ledger, dap_chain_tx_in_cond_t *a_in_cond); void dap_ledger_load_end(dap_ledger_t *a_ledger); +dap_pkey_t *dap_ledger_find_pkey_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_pkey_hash); #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/modules/net/srv/dap_chain_net_srv_order.c b/modules/net/srv/dap_chain_net_srv_order.c index 66ff78bd4a..d584f33e9a 100644 --- a/modules/net/srv/dap_chain_net_srv_order.c +++ b/modules/net/srv/dap_chain_net_srv_order.c @@ -325,7 +325,7 @@ dap_chain_net_srv_order_t *dap_chain_net_srv_order_compose(dap_chain_net_t *a_ne if ( a_price_ticker) strncpy(l_order->price_ticker, a_price_ticker, DAP_CHAIN_TICKER_SIZE_MAX - 1); l_order->units = a_units; - dap_sign_t *l_sign = dap_sign_create(a_key, l_order, sizeof(dap_chain_net_srv_order_t) + l_order->ext_size, 0); + dap_sign_t *l_sign = dap_sign_create(a_key, l_order, sizeof(dap_chain_net_srv_order_t) + l_order->ext_size); if (!l_sign) { DAP_DELETE(l_order); return NULL; diff --git a/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c b/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c index 2d6760c62d..41b477185d 100644 --- a/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c +++ b/modules/service/stake/dap_chain_net_srv_stake_pos_delegate.c @@ -135,6 +135,17 @@ static bool s_tag_check_key_delegation(dap_ledger_t *a_ledger, dap_chain_datum_t return false; } +static dap_pkey_t *s_get_pkey_by_hash_callback(const uint8_t *a_hash) +{ + + dap_chain_net_srv_stake_item_t *l_stake = NULL; + for (dap_list_t *l_srv_stake_list = s_srv_stake_list; l_srv_stake_list && !l_stake; l_srv_stake_list = l_srv_stake_list->next) { + dap_chain_net_srv_stake_t *l_srv_stake = l_srv_stake_list->data; + HASH_FIND(hh, l_srv_stake->itemlist, a_hash, sizeof(dap_hash_fast_t), l_stake); + } + return l_stake ? l_stake->pkey : NULL; +} + /** * @brief dap_stream_ch_vpn_init Init actions for VPN stream channel * @return 0 if everything is okay, lesser then zero if errors @@ -157,7 +168,7 @@ int dap_chain_net_srv_stake_pos_delegate_init() "srv_stake order remove -net <net_name> -order <order_hash>\n" "\tRemove order with specified hash\n" "\t\t === Commands for work with stake delegate ===\n" - "srv_stake delegate {[-cert <pub_cert_name> | -pkey <pkey> -sign_type <sign_type>] -value <datoshi> | " + "srv_stake delegate {[-cert <pub_cert_name> | {-pkey <pkey_hash> | -pkey_full <pkey>}-sign_type <sign_type>] -value <datoshi> | " "-order <order_hash> {[-tax_addr <wallet_addr_for_tax_collecting>] | " "-cert <priv_cert_name> [-node_addr <for_validator_node>]}}" " -net <net_name> -w <wallet_name> -fee <value>\n" @@ -185,6 +196,8 @@ int dap_chain_net_srv_stake_pos_delegate_init() dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_ID }; dap_ledger_service_add(l_uid, "pos_delegate", s_tag_check_key_delegation); + s_debug_more = dap_config_get_item_bool_default(g_config, "stake", "debug_more", s_debug_more); + dap_sign_set_pkey_by_hash_callback(s_get_pkey_by_hash_callback); return 0; } @@ -229,7 +242,7 @@ static void s_stake_net_clear(dap_chain_net_t *a_net) HASH_ITER(hh, l_srv_stake->itemlist, l_stake, l_tmp) { // Clang bug at this, l_stake should change at every loop cycle HASH_DEL(l_srv_stake->itemlist, l_stake); - DAP_DELETE(l_stake); + DAP_DEL_MULTY(l_stake->pkey, l_stake); } dap_chain_net_srv_stake_cache_item_t *l_cache_item = NULL, *l_cache_tmp = NULL; HASH_ITER(hh, l_srv_stake->cache, l_cache_item, l_cache_tmp) { @@ -438,7 +451,7 @@ static void s_stake_recalculate_weights(dap_chain_net_id_t a_net_id) } void dap_chain_net_srv_stake_key_delegate(dap_chain_net_t *a_net, dap_chain_addr_t *a_signing_addr, dap_hash_fast_t *a_stake_tx_hash, - uint256_t a_value, dap_chain_node_addr_t *a_node_addr) + uint256_t a_value, dap_chain_node_addr_t *a_node_addr, dap_pkey_t *a_pkey) { dap_return_if_fail(a_net && a_signing_addr && a_node_addr && a_stake_tx_hash); dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_net->pub.id); @@ -460,6 +473,7 @@ void dap_chain_net_srv_stake_key_delegate(dap_chain_net_t *a_net, dap_chain_addr l_stake->value = l_stake->locked_value = a_value; l_stake->tx_hash = *a_stake_tx_hash; l_stake->is_active = true; + l_stake->pkey = DAP_DUP_SIZE(a_pkey, dap_pkey_get_size(a_pkey)); if (!l_found) HASH_ADD(hh, l_srv_stake->itemlist, signing_addr.data.hash_fast, sizeof(dap_hash_fast_t), l_stake); if (!dap_hash_fast_is_blank(a_stake_tx_hash)) { @@ -467,7 +481,7 @@ void dap_chain_net_srv_stake_key_delegate(dap_chain_net_t *a_net, dap_chain_addr dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_hash(a_net->pub.ledger, a_stake_tx_hash); if (l_tx) { dap_chain_tx_out_cond_t *l_cond = dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE, NULL); - if (l_cond && l_cond->tsd_size == dap_chain_datum_tx_item_out_cond_create_srv_stake_get_tsd_size()) { + if (l_cond && (l_cond->tsd_size == dap_chain_datum_tx_item_out_cond_create_srv_stake_get_tsd_size(true, dap_pkey_get_size(l_stake->pkey)))) { dap_tsd_t *l_tsd = dap_tsd_find(l_cond->tsd, l_cond->tsd_size, DAP_CHAIN_TX_OUT_COND_TSD_ADDR); l_stake->sovereign_addr = dap_tsd_get_scalar(l_tsd, dap_chain_addr_t); l_tsd = dap_tsd_find(l_cond->tsd, l_cond->tsd_size, DAP_CHAIN_TX_OUT_COND_TSD_VALUE); @@ -530,6 +544,28 @@ void dap_chain_net_srv_stake_key_update(dap_chain_addr_t *a_signing_addr, uint25 s_stake_recalculate_weights(a_signing_addr->net_id); } +/** + * @brief add pkey to dap_chain_net_srv_stake_item_t + * @param a_net to add + * @param a_pkey + */ +void dap_chain_net_srv_stake_pkey_update(dap_chain_net_t *a_net, dap_pkey_t *a_pkey) +{ + dap_return_if_pass(!a_net || !a_pkey); + dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_net->pub.id); + if (!l_srv_stake) + return log_it(L_ERROR, "Can't update pkey: no stake service found by net id %"DAP_UINT64_FORMAT_U, a_net->pub.id.uint64); + dap_hash_fast_t l_pkey_hash = {}; + dap_pkey_get_hash(a_pkey, &l_pkey_hash); + dap_chain_net_srv_stake_item_t *l_stake = NULL; + HASH_FIND(hh, l_srv_stake->itemlist, &l_pkey_hash, sizeof(dap_hash_fast_t), l_stake); + if (!l_stake) + return log_it(L_WARNING, "No delegated found to update pkey %s", dap_hash_fast_to_str_static(&l_pkey_hash)); + if (l_stake->pkey) + return log_it(L_INFO, "pkey %s to update already exist", dap_hash_fast_to_str_static(&l_pkey_hash)); + l_stake->pkey = DAP_DUP_SIZE(a_pkey, dap_pkey_get_size(a_pkey)); +} + void dap_chain_net_srv_stake_set_allowed_min_value(dap_chain_net_id_t a_net_id, uint256_t a_value) { dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(a_net_id); @@ -736,10 +772,9 @@ static dap_chain_datum_tx_t *s_stake_tx_create(dap_chain_net_t * a_net, dap_enc_ uint256_t a_value, uint256_t a_fee, dap_chain_addr_t *a_signing_addr, dap_chain_node_addr_t *a_node_addr, dap_chain_addr_t *a_sovereign_addr, uint256_t a_sovereign_tax, - dap_chain_datum_tx_t *a_prev_tx) + dap_chain_datum_tx_t *a_prev_tx, dap_pkey_t *a_pkey) { - if (!a_net || !a_key || IS_ZERO_256(a_value) || !a_signing_addr || !a_node_addr) - return NULL; + dap_return_val_if_pass (!a_net || !a_key || IS_ZERO_256(a_value) || !a_signing_addr || !a_node_addr, NULL); const char *l_native_ticker = a_net->pub.native_ticker; char l_delegated_ticker[DAP_CHAIN_TICKER_SIZE_MAX]; @@ -805,7 +840,8 @@ static dap_chain_datum_tx_t *s_stake_tx_create(dap_chain_net_t * a_net, dap_enc_ // add 'out_cond' & 'out_ext' items dap_chain_net_srv_uid_t l_uid = { .uint64 = DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_ID }; dap_chain_tx_out_cond_t *l_tx_out = dap_chain_datum_tx_item_out_cond_create_srv_stake(l_uid, a_value, a_signing_addr, a_node_addr, - a_sovereign_addr, a_sovereign_tax); + a_sovereign_addr, a_sovereign_tax, a_pkey); + if (!l_tx_out) { log_it(L_ERROR, "Can't compose the transaction conditional output"); goto tx_fail; @@ -999,7 +1035,7 @@ static dap_chain_datum_tx_t *s_order_tx_create(dap_chain_net_t * a_net, dap_enc_ dap_chain_node_addr_t l_node_addr = {}; return s_stake_tx_create(a_net, a_key, a_value, a_fee, (dap_chain_addr_t *)&c_dap_chain_addr_blank, &l_node_addr, - a_sovereign_addr, a_sovereign_tax, NULL); + a_sovereign_addr, a_sovereign_tax, NULL, NULL); } // Put the transaction to mempool @@ -1097,13 +1133,30 @@ dap_chain_datum_decree_t *dap_chain_net_srv_stake_decree_approve(dap_chain_net_t *(dap_chain_addr_t*)(l_tsd->data) = l_tx_out_cond->subtype.srv_stake_pos_delegate.signing_addr; l_tsd_list = dap_list_append(l_tsd_list, l_tsd); + if (DAP_SIGN_GET_PKEY_HASHING_FLAG(l_tx_out_cond->subtype.srv_stake_pos_delegate.flags)) { + dap_tsd_t *l_tsd = dap_tsd_find(l_tx_out_cond->tsd, l_tx_out_cond->tsd_size, DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_ADD); + if (!l_tsd) { + log_it(L_WARNING, "NULL tsd pkey in tx_out_cond with active PKEY_HASHING_FLAG"); + } else { + l_total_tsd_size += dap_tsd_size(l_tsd); + l_tsd = DAP_DUP_SIZE(l_tsd, dap_tsd_size(l_tsd)); + if (!l_tsd) { + log_it(L_CRITICAL, "%s", c_error_memory_alloc); + dap_list_free_full(l_tsd_list, NULL); + return NULL; + } + l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_PKEY; + l_tsd_list = dap_list_append(l_tsd_list, l_tsd); + } + } + l_total_tsd_size += sizeof(dap_tsd_t) + sizeof(dap_chain_node_addr_t); l_tsd = DAP_NEW_Z_SIZE(dap_tsd_t, l_total_tsd_size); if (!l_tsd) { log_it(L_CRITICAL, "%s", c_error_memory_alloc); dap_list_free_full(l_tsd_list, NULL); return NULL; - } + } l_tsd->type = DAP_CHAIN_DATUM_DECREE_TSD_TYPE_NODE_ADDR; l_tsd->size = sizeof(dap_chain_node_addr_t); *(dap_chain_node_addr_t*)(l_tsd->data) = l_tx_out_cond->subtype.srv_stake_pos_delegate.signer_node_addr; @@ -1146,7 +1199,7 @@ dap_chain_datum_decree_t *dap_chain_net_srv_stake_decree_approve(dap_chain_net_t size_t l_total_signs_size = l_decree->header.signs_size; dap_sign_t * l_sign = dap_cert_sign(a_cert, l_decree, - sizeof(dap_chain_datum_decree_t) + l_decree->header.data_size, 0); + sizeof(dap_chain_datum_decree_t) + l_decree->header.data_size); if (l_sign) { size_t l_sign_size = dap_sign_get_size(l_sign); @@ -1167,6 +1220,55 @@ dap_chain_datum_decree_t *dap_chain_net_srv_stake_decree_approve(dap_chain_net_t return l_decree; } +static dap_chain_datum_decree_t *s_decree_pkey_update(dap_chain_net_t *a_net, dap_cert_t *a_cert, dap_pkey_t *a_pkey) +{ + dap_return_val_if_pass(!a_net || !a_cert || !a_pkey, NULL); + // create updating decree + dap_chain_datum_decree_t *l_decree = NULL; + + size_t l_total_tsd_size = sizeof(dap_tsd_t) + dap_pkey_get_size(a_pkey); + + l_decree = DAP_NEW_Z_SIZE(dap_chain_datum_decree_t, sizeof(dap_chain_datum_decree_t) + l_total_tsd_size); + if (!l_decree) { + log_it(L_CRITICAL, "%s", c_error_memory_alloc); + return NULL; + } + l_decree->decree_version = DAP_CHAIN_DATUM_DECREE_VERSION; + l_decree->header.ts_created = dap_time_now(); + l_decree->header.type = DAP_CHAIN_DATUM_DECREE_TYPE_COMMON; + l_decree->header.common_decree_params.net_id = a_net->pub.id; + dap_chain_t *l_chain = dap_chain_net_get_default_chain_by_chain_type(a_net, CHAIN_TYPE_ANCHOR); + if (!l_chain) + l_chain = dap_chain_net_get_chain_by_chain_type(a_net, CHAIN_TYPE_ANCHOR); + if (!l_chain) { + log_it(L_ERROR, "No chain supported anchor datum type"); + DAP_DEL_Z(l_decree); + return NULL; + } + l_decree->header.common_decree_params.chain_id = l_chain->id; + l_decree->header.common_decree_params.cell_id = *dap_chain_net_get_cur_cell(a_net); + l_decree->header.sub_type = DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_PKEY_UPDATE; + l_decree->header.data_size = l_total_tsd_size; + l_decree->header.signs_size = 0; + dap_tsd_write((byte_t*)l_decree->data_n_signs, DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_PKEY, a_pkey, dap_pkey_get_size(a_pkey)); + + dap_sign_t *l_sign = dap_cert_sign(a_cert, l_decree, sizeof(dap_chain_datum_decree_t) + l_decree->header.data_size); + + if (l_sign) { + l_decree->header.signs_size = dap_sign_get_size(l_sign); + l_decree = DAP_REALLOC_RET_VAL_IF_FAIL(l_decree, sizeof(dap_chain_datum_decree_t) + l_decree->header.data_size + l_decree->header.signs_size, NULL, l_decree, l_sign); + memcpy((byte_t*)l_decree->data_n_signs + l_decree->header.data_size, l_sign, l_decree->header.signs_size); + DAP_DELETE(l_sign); + log_it(L_DEBUG,"<-- Signed with '%s'", a_cert->name); + } else { + log_it(L_ERROR, "Decree signing failed"); + DAP_DELETE(l_decree); + return NULL; + } + + return l_decree; +} + // Put the decree to mempool static char *s_stake_decree_put(dap_chain_datum_decree_t *a_decree, dap_chain_net_t *a_net) { @@ -1383,7 +1485,7 @@ static dap_chain_datum_decree_t *s_stake_decree_invalidate(dap_chain_net_t *a_ne size_t l_total_signs_size = l_decree->header.signs_size; dap_sign_t * l_sign = dap_cert_sign(a_cert, l_decree, - sizeof(dap_chain_datum_decree_t) + l_decree->header.data_size, 0); + sizeof(dap_chain_datum_decree_t) + l_decree->header.data_size); if (l_sign) { size_t l_sign_size = dap_sign_get_size(l_sign); @@ -1927,13 +2029,24 @@ static int s_cli_srv_stake_order(int a_argc, char **a_argv, int a_arg_index, voi dap_chain_datum_tx_t *l_tx = dap_ledger_tx_find_by_hash(l_net->pub.ledger, &l_order->tx_cond_hash); if (l_tx) { dap_chain_tx_out_cond_t *l_cond = dap_chain_datum_tx_out_cond_get(l_tx, DAP_CHAIN_TX_OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE, NULL); - if (l_cond && l_cond->tsd_size == dap_chain_datum_tx_item_out_cond_create_srv_stake_get_tsd_size()) { - dap_tsd_t *l_tsd = dap_tsd_find(l_cond->tsd, l_cond->tsd_size, DAP_CHAIN_TX_OUT_COND_TSD_ADDR); - l_addr = dap_tsd_get_scalar(l_tsd, dap_chain_addr_t); - l_tsd = dap_tsd_find(l_cond->tsd, l_cond->tsd_size, DAP_CHAIN_TX_OUT_COND_TSD_VALUE); - l_tax = dap_tsd_get_scalar(l_tsd, uint256_t); - MULT_256_256(l_tax, GET_256_FROM_64(100), &l_tax); - l_error = false; + if (l_cond) { + dap_pkey_t *l_pkey = NULL; + if (DAP_SIGN_GET_PKEY_HASHING_FLAG(l_cond->subtype.srv_stake_pos_delegate.flags)) { + dap_tsd_t *l_tsd = dap_tsd_find(l_cond->tsd, l_cond->tsd_size, DAP_CHAIN_DATUM_TOKEN_TSD_TYPE_TOTAL_PKEYS_ADD); + if (!l_tsd) { + log_it(L_WARNING, "NULL tsd pkey in tx_out_cond with active PKEY_HASHING_FLAG"); + } else { + l_pkey = (dap_pkey_t *)l_tsd->data; + } + } + if (l_cond->tsd_size == dap_chain_datum_tx_item_out_cond_create_srv_stake_get_tsd_size(true, dap_pkey_get_size(l_pkey))) { + dap_tsd_t *l_tsd = dap_tsd_find(l_cond->tsd, l_cond->tsd_size, DAP_CHAIN_TX_OUT_COND_TSD_ADDR); + l_addr = dap_tsd_get_scalar(l_tsd, dap_chain_addr_t); + l_tsd = dap_tsd_find(l_cond->tsd, l_cond->tsd_size, DAP_CHAIN_TX_OUT_COND_TSD_VALUE); + l_tax = dap_tsd_get_scalar(l_tsd, uint256_t); + MULT_256_256(l_tax, GET_256_FROM_64(100), &l_tax); + l_error = false; + } } } if (!l_error) { @@ -2016,11 +2129,14 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index, *l_wallet_str = NULL, *l_cert_str = NULL, *l_pkey_str = NULL, + *l_pkey_full_str = NULL, *l_sign_type_str = NULL, *l_value_str = NULL, *l_fee_str = NULL, *l_node_addr_str = NULL, *l_order_hash_str = NULL; + + dap_pkey_t *l_pkey = NULL; dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-net", &l_net_str); if (!l_net_str) { dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_PARAM_ERR, "Command 'delegate' requires parameter -net"); @@ -2049,14 +2165,20 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index, uint256_t l_sovereign_tax = uint256_0; dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-cert", &l_cert_str); dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-pkey", &l_pkey_str); + dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-pkey_full", &l_pkey_full_str); dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-sign_type", &l_sign_type_str); dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-order", &l_order_hash_str); - if (!l_cert_str && !l_order_hash_str && !l_pkey_str) { + if (!l_cert_str && !l_order_hash_str && !l_pkey_str && !l_pkey_full_str) { dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_PARAM_ERR, "Command 'delegate' requires parameter -cert and/or -order and/or -pkey"); dap_enc_key_delete(l_enc_key); - return -13; + return DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_PARAM_ERR; } - if (l_pkey_str && !l_sign_type_str) { + if (l_pkey_str && l_pkey_full_str) { + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_PARAM_ERR, "Command 'delegate' requires only one, -pkey or -pkey_full"); + dap_enc_key_delete(l_enc_key); + return DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_PARAM_ERR; + } + if ((l_pkey_str || l_pkey_full_str) && !l_sign_type_str) { dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_PARAM_ERR, "Command 'delegate' requires parameter -sign_type for pkey"); dap_enc_key_delete(l_enc_key); return DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_PARAM_ERR; @@ -2090,16 +2212,34 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index, dap_enc_key_delete(l_enc_key); return DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_WRONG_CERT_ERR; } + l_pkey = dap_pkey_from_enc_key(l_signing_cert->enc_key); dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-node_addr", &l_node_addr_str); - } else if (l_pkey_str) { - dap_chain_hash_fast_t l_hash_public_key = {0}; + } else if (l_pkey_str || l_pkey_full_str) { dap_sign_type_t l_type = dap_sign_type_from_str(l_sign_type_str); if (l_type.type == SIG_TYPE_NULL) { dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_WRONG_SIGN_ERR, "Wrong sign type"); dap_enc_key_delete(l_enc_key); return DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_WRONG_SIGN_ERR; } - if (dap_chain_hash_fast_from_str(l_pkey_str, &l_hash_public_key)) { + if (l_pkey_full_str) { + l_pkey = dap_pkey_get_from_str(l_pkey_full_str); + } else { + dap_hash_fast_t l_pkey_hash = {}; + if (!dap_chain_hash_fast_from_str(l_pkey_str, &l_pkey_hash)) + l_pkey = dap_ledger_find_pkey_by_hash(l_net->pub.ledger, &l_pkey_hash); + } + if (!l_pkey) { + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_INVALID_PKEY_ERR, "Invalid pkey string format, can't get pkey_full"); + dap_enc_key_delete(l_enc_key); + return DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_INVALID_PKEY_ERR; + } + if (l_pkey->header.type.type != dap_pkey_type_from_sign_type(l_type).type) { + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_INVALID_PKEY_ERR, "pkey and sign types is different"); + dap_enc_key_delete(l_enc_key); + return DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_INVALID_PKEY_ERR; + } + dap_chain_hash_fast_t l_hash_public_key = {0}; + if (!dap_pkey_get_hash(l_pkey, &l_hash_public_key)) { dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_INVALID_PKEY_ERR, "Invalid pkey hash format"); dap_enc_key_delete(l_enc_key); return DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_INVALID_PKEY_ERR; @@ -2162,7 +2302,7 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index, log_it(L_WARNING, "Requested conditional transaction have another ticker (not %s)", l_delegated_ticker); return DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_ANOTHER_TICKER_ERR; } - if (l_cond->tsd_size != dap_chain_datum_tx_item_out_cond_create_srv_stake_get_tsd_size()) { + if (l_cond->tsd_size != dap_chain_datum_tx_item_out_cond_create_srv_stake_get_tsd_size(true, 0)) { dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_INVALID_COND_TX_FORMAT_ERR, "The order's conditional transaction has invalid format"); dap_enc_key_delete(l_enc_key); DAP_DELETE(l_order); @@ -2247,6 +2387,7 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index, return DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_UNSIGNED_ORDER_ERR; } dap_chain_addr_fill_from_sign(&l_signing_addr, l_sign, l_net->pub.id); + l_pkey = dap_pkey_get_from_sign(l_sign); char l_delegated_ticker_str[DAP_CHAIN_TICKER_SIZE_MAX]; dap_chain_datum_token_get_delegated_ticker(l_delegated_ticker_str, l_net->pub.native_ticker); if (dap_strcmp(l_order->price_ticker, l_delegated_ticker_str)) { @@ -2266,6 +2407,11 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index, } DIV_256(l_sovereign_tax, GET_256_FROM_64(100), &l_sovereign_tax); } + if (!l_pkey) { + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_INVALID_PKEY_ERR, "pkey not defined"); + dap_enc_key_delete(l_enc_key); + return DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_INVALID_PKEY_ERR; + } int l_check_result = dap_chain_net_srv_stake_verify_key_and_node(&l_signing_addr, &l_node_addr); if (l_check_result) { @@ -2296,8 +2442,9 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index, // Create conditional transaction dap_chain_datum_tx_t *l_tx = s_stake_tx_create(l_net, l_enc_key, l_value, l_fee, &l_signing_addr, &l_node_addr, - l_order_hash_str ? &l_sovereign_addr : NULL, l_sovereign_tax, l_prev_tx); + l_order_hash_str ? &l_sovereign_addr : NULL, l_sovereign_tax, l_prev_tx, l_pkey); dap_enc_key_delete(l_enc_key); + DAP_DELETE(l_pkey); char *l_tx_hash_str; if (!l_tx || !(l_tx_hash_str = s_stake_tx_put(l_tx, l_net, a_hash_out_type))) { dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_STAKE_ERR, "Stake transaction error"); @@ -2315,6 +2462,61 @@ static int s_cli_srv_stake_delegate(int a_argc, char **a_argv, int a_arg_index, return 0; } +static int s_cli_srv_stake_pkey_show(int a_argc, char **a_argv, int a_arg_index, void **a_str_reply, const char *a_hash_out_type) +{ + json_object **a_json_arr_reply = (json_object **)a_str_reply; + const char *l_net_str = NULL, + *l_pkey_hash_str = NULL; + dap_hash_fast_t l_pkey_hash = {}; + dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-net", &l_net_str); + if (!l_net_str) { + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_PARAM_ERR, "Command 'pkey_show' requires parameter -net"); + return DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_PARAM_ERR; + } + dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str); + if (!l_net) { + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_NET_ERR, "Network %s not found", l_net_str); + return DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_NET_ERR; + } + + dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-pkey", &l_pkey_hash_str); + + if (!l_pkey_hash_str) { + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_PARAM_ERR, "Command 'pkey_show' requires parameter -pkey"); + return -13; + } + + if (dap_chain_hash_fast_from_str(l_pkey_hash_str, &l_pkey_hash)) { + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_INVALID_PKEY_ERR, "pkey not defined"); + return DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_INVALID_PKEY_ERR; + } + + dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(l_net->pub.id); + if (!l_srv_stake) { + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_INVALID_PKEY_ERR, "Specified net have no stake service activated"); + return -25; + } + // search in curren + dap_chain_net_srv_stake_item_t *l_stake = NULL; + HASH_FIND(hh, l_srv_stake->itemlist, &l_pkey_hash, sizeof(dap_hash_fast_t), l_stake); + dap_pkey_t *l_pkey = l_stake ? l_stake->pkey : NULL; + if (!l_pkey) { + l_pkey = dap_ledger_find_pkey_by_hash(l_net->pub.ledger, &l_pkey_hash); + } + if (!l_pkey) { + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_INVALID_PKEY_ERR, "pkey not finded"); + return -25; + } + const char *l_pkey_str = dap_pkey_to_str(l_pkey, a_hash_out_type); + json_object* l_json_obj_pkey = json_object_new_object(); + json_object_object_add(l_json_obj_pkey, "hash", json_object_new_string(l_pkey_hash_str)); + json_object_object_add(l_json_obj_pkey, "pkey", json_object_new_string(l_pkey_str)); + + json_object_array_add(*a_json_arr_reply, l_json_obj_pkey); + DAP_DELETE(l_pkey_str); + return 0; +} + typedef enum s_cli_srv_stake_update_err{ DAP_CHAIN_NODE_CLI_SRV_STAKE_UPDATE_OK = 0, @@ -2724,6 +2926,9 @@ static void s_srv_stake_print(dap_chain_net_srv_stake_item_t *a_stake, uint256_t char l_node_addr[32]; snprintf(l_node_addr, 32, ""NODE_ADDR_FP_STR"", NODE_ADDR_FP_ARGS_S(a_stake->node_addr)); json_object_object_add(l_json_obj_stake, "pkey_hash", json_object_new_string(l_pkey_hash_str)); + if (s_debug_more) { + json_object_object_add(l_json_obj_stake, "pkey_full", json_object_new_string(a_stake->pkey ? "true" : "false")); + } json_object_object_add(l_json_obj_stake, "stake_value", json_object_new_string(l_balance)); json_object_object_add(l_json_obj_stake, "effective_value", json_object_new_string(l_effective_weight)); json_object_object_add(l_json_obj_stake, "related_weight", json_object_new_string(l_rel_weight_str)); @@ -2901,7 +3106,7 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply) { json_object **a_json_arr_reply = (json_object **)a_str_reply; enum { - CMD_NONE, CMD_ORDER, CMD_DELEGATE, CMD_UPDATE, CMD_APPROVE, CMD_LIST, CMD_INVALIDATE, CMD_MIN_VALUE, CMD_CHECK, CMD_MAX_WEIGHT, CMD_REWARD + CMD_NONE, CMD_ORDER, CMD_DELEGATE, CMD_UPDATE, CMD_APPROVE, CMD_LIST, CMD_INVALIDATE, CMD_MIN_VALUE, CMD_CHECK, CMD_MAX_WEIGHT, CMD_REWARD, CMD_PKEY_SHOW, CMD_PKEY_UPDATE }; int l_arg_index = 1; @@ -2951,6 +3156,12 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply) else if(dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, dap_min(a_argc, l_arg_index + 1), "reward", NULL)) { l_cmd_num = CMD_REWARD; } + else if(dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, dap_min(a_argc, l_arg_index + 1), "pkey_show", NULL)) { + l_cmd_num = CMD_PKEY_SHOW; + } + else if(dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, dap_min(a_argc, l_arg_index + 1), "pkey_update", NULL)) { + l_cmd_num = CMD_PKEY_UPDATE; + } switch (l_cmd_num) { @@ -2965,6 +3176,9 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply) case CMD_INVALIDATE: return s_cli_srv_stake_invalidate(a_argc, a_argv, l_arg_index + 1, a_str_reply, l_hash_out_type); + + case CMD_PKEY_SHOW: + return s_cli_srv_stake_pkey_show(a_argc, a_argv, l_arg_index + 1, a_str_reply, l_hash_out_type); case CMD_CHECK: { @@ -3091,6 +3305,70 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply) DAP_DELETE(l_decree_hash_str); } break; + case CMD_PKEY_UPDATE: { + const char *l_net_str = NULL, *l_tx_hash_str = NULL, *l_cert_str = NULL; + l_arg_index++; + dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-net", &l_net_str); + if (!l_net_str) { + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_PARAM_ERR, "Command 'pkey_update' requires parameter -net"); + return DAP_CHAIN_NODE_CLI_SRV_STAKE_PARAM_ERR; + } + dap_chain_net_t *l_net = dap_chain_net_by_name(l_net_str); + if (!l_net) { + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_NET_ERR, "Network %s not found", l_net_str); + return DAP_CHAIN_NODE_CLI_SRV_STAKE_NET_ERR; + } + dap_chain_net_srv_stake_t *l_srv_stake = s_srv_stake_by_net_id(l_net->pub.id); + if (!l_srv_stake) { + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_NO_STAKE_IN_NET_ERR, "Specified net have no stake service activated"); + return DAP_CHAIN_NODE_CLI_SRV_STAKE_NO_STAKE_IN_NET_ERR; + } + dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-poa_cert", &l_cert_str); + if (!l_cert_str) { + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_PARAM_ERR, "Command 'pkey_update' requires parameter -poa_cert"); + return DAP_CHAIN_NODE_CLI_SRV_STAKE_PARAM_ERR; + } + dap_cert_t *l_cert = dap_cert_find_by_name(l_cert_str); + if (!l_cert) { + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_NO_CERT_ERR, "Specified certificate not found"); + return DAP_CHAIN_NODE_CLI_SRV_STAKE_NO_CERT_ERR; + } + if (!s_srv_stake_is_poa_cert(l_net, l_cert->enc_key)) { + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_NOT_POA_ERR, "Specified certificate is not PoA root one"); + return DAP_CHAIN_NODE_CLI_SRV_STAKE_NOT_POA_ERR; + } + const char *l_pkey_full_str = NULL; + dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "-pkey_full", &l_pkey_full_str); + if (!l_pkey_full_str) { + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_PARAM_ERR, "Command 'pkey_update' requires parameter -pkey_full"); + return DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_PARAM_ERR; + } + dap_pkey_t *l_pkey = dap_pkey_get_from_str(l_pkey_full_str); + dap_hash_fast_t l_pkey_hash = {}; + dap_pkey_get_hash(l_pkey, &l_pkey_hash); + dap_chain_net_srv_stake_item_t *l_stake = NULL; + HASH_FIND(hh, l_srv_stake->itemlist, &l_pkey_hash, sizeof(dap_hash_fast_t), l_stake); + if (!l_stake) { + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_STAKE_ERR, "Specified pkey hash %s isn't delegated or approved", dap_hash_fast_to_str_static(&l_pkey_hash)); + return DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_STAKE_ERR; + } + if (l_stake->pkey) { + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_STAKE_ERR, "Specified pkey_full already present"); + return DAP_CHAIN_NODE_CLI_SRV_STAKE_DELEGATE_STAKE_ERR; + } + dap_chain_datum_decree_t *l_decree = s_decree_pkey_update(l_net, l_cert, l_pkey); + DAP_DELETE(l_pkey); + char *l_decree_hash_str = NULL; + if (!l_decree || !(l_decree_hash_str = s_stake_decree_put(l_decree, l_net))) { + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_DECREE_ERR, "pkey update decree error"); + return DAP_CHAIN_NODE_CLI_SRV_STAKE_DECREE_ERR; + } + DAP_DELETE(l_decree); + char *l_approve_str = dap_strdup_printf("pkey update decree %s successfully created", l_decree_hash_str); + json_object_array_add(*a_json_arr_reply, json_object_new_string(l_approve_str)); + DAP_DEL_MULTY(l_decree_hash_str, l_approve_str); + } break; + case CMD_LIST: { l_arg_index++; if (dap_cli_server_cmd_find_option_val(a_argv, l_arg_index, a_argc, "keys", NULL)) { @@ -3142,7 +3420,7 @@ static int s_cli_srv_stake(int a_argc, char **a_argv, void **a_str_reply) } l_stake = dap_chain_net_srv_stake_check_pkey_hash(l_net->pub.id, &l_pkey_hash); if (!l_stake) { - dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_HASH_ERR, "Specified pkey hash isn't delegated nor approved"); + dap_json_rpc_error_add(*a_json_arr_reply, DAP_CHAIN_NODE_CLI_SRV_STAKE_HASH_ERR, "Specified pkey hash isn't delegated or approved"); return DAP_CHAIN_NODE_CLI_SRV_STAKE_HASH_ERR; } } diff --git a/modules/service/stake/include/dap_chain_net_srv_stake_pos_delegate.h b/modules/service/stake/include/dap_chain_net_srv_stake_pos_delegate.h index 9f5a21a763..3fb0c4e77b 100644 --- a/modules/service/stake/include/dap_chain_net_srv_stake_pos_delegate.h +++ b/modules/service/stake/include/dap_chain_net_srv_stake_pos_delegate.h @@ -42,6 +42,7 @@ typedef struct dap_chain_net_srv_stake_item { dap_chain_node_addr_t node_addr; dap_chain_addr_t sovereign_addr; uint256_t sovereign_tax; + dap_pkey_t *pkey; UT_hash_handle hh, ht; } dap_chain_net_srv_stake_item_t; @@ -71,9 +72,10 @@ void dap_chain_net_srv_stake_pos_delegate_deinit(); int dap_chain_net_srv_stake_net_add(dap_chain_net_id_t a_net_id); void dap_chain_net_srv_stake_key_delegate(dap_chain_net_t *a_net, dap_chain_addr_t *a_signing_addr, dap_hash_fast_t *a_stake_tx_hash, - uint256_t a_value, dap_chain_node_addr_t *a_node_addr); + uint256_t a_value, dap_chain_node_addr_t *a_node_addr, dap_pkey_t *a_pkey); void dap_chain_net_srv_stake_key_invalidate(dap_chain_addr_t *a_signing_addr); void dap_chain_net_srv_stake_key_update(dap_chain_addr_t *a_signing_addr, uint256_t a_new_value, dap_hash_fast_t *a_new_tx_hash); +void dap_chain_net_srv_stake_pkey_update(dap_chain_net_t *a_net, dap_pkey_t *a_pkey); void dap_chain_net_srv_stake_set_allowed_min_value(dap_chain_net_id_t a_net_id, uint256_t a_value); uint256_t dap_chain_net_srv_stake_get_allowed_min_value(dap_chain_net_id_t a_net_id); void dap_chain_net_srv_stake_set_percent_max(dap_chain_net_id_t a_net_id, uint256_t a_value); diff --git a/modules/type/blocks/dap_chain_block.c b/modules/type/blocks/dap_chain_block.c index 299ceff569..39e8cc0de5 100644 --- a/modules/type/blocks/dap_chain_block.c +++ b/modules/type/blocks/dap_chain_block.c @@ -285,7 +285,7 @@ size_t dap_chain_block_sign_add(dap_chain_block_t **a_block_ptr, size_t a_block_ assert(a_block_ptr); dap_chain_block_t *l_block = *a_block_ptr; size_t l_offset = dap_chain_block_get_sign_offset(l_block, a_block_size); - dap_sign_t *l_block_sign = dap_sign_create(a_key, l_block, l_offset + sizeof(l_block->hdr), 0); + dap_sign_t *l_block_sign = dap_sign_create(a_key, l_block, l_offset + sizeof(l_block->hdr)); size_t l_block_sign_size = dap_sign_get_size(l_block_sign); if (!l_block_sign_size) return 0; diff --git a/modules/type/blocks/dap_chain_cs_blocks.c b/modules/type/blocks/dap_chain_cs_blocks.c index 0d44b815ca..52927f3c92 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -437,7 +437,7 @@ static char *s_blocks_decree_set_reward(dap_chain_net_t *a_net, dap_chain_t *a_c l_tsd->size = sizeof(uint256_t); *(uint256_t*)(l_tsd->data) = a_value; // Sign it - dap_sign_t *l_sign = dap_cert_sign(a_cert, l_decree, l_decree_size, 0); + dap_sign_t *l_sign = dap_cert_sign(a_cert, l_decree, l_decree_size); if (!l_sign) { log_it(L_ERROR, "Decree signing failed"); DAP_DELETE(l_decree); diff --git a/modules/type/dag/dap_chain_cs_dag_event.c b/modules/type/dag/dap_chain_cs_dag_event.c index c15b936a36..511113f0fa 100644 --- a/modules/type/dag/dap_chain_cs_dag_event.c +++ b/modules/type/dag/dap_chain_cs_dag_event.c @@ -66,7 +66,7 @@ dap_chain_cs_dag_event_t *dap_chain_cs_dag_event_new(dap_chain_id_t a_chain_id, memcpy( l_event_new->hashes_n_datum_n_signs + l_hashes_size, a_datum,l_datum_size ); if ( a_key ){ - dap_sign_t *l_sign = dap_sign_create(a_key, l_event_new, l_event_size, 0); + dap_sign_t *l_sign = dap_sign_create(a_key, l_event_new, l_event_size); if ( !l_sign ) return DAP_DELETE(l_event_new), log_it(L_ERROR,"Can't sign dag event!"), NULL; size_t l_sign_size = dap_sign_get_size(l_sign); @@ -151,7 +151,7 @@ size_t dap_chain_cs_dag_event_sign_add(dap_chain_cs_dag_event_t **a_event_ptr, s return log_it(L_DEBUG, "Already signed with pkey %s", dap_get_data_hash_str(l_pub_key, l_pub_key_size).s), DAP_DELETE(l_pub_key), 0; } size_t l_event_size_excl_sign = dap_chain_cs_dag_event_calc_size_excl_signs(l_event, a_event_size); - dap_sign_t *l_sign = dap_sign_create(a_key, l_event, l_event_size_excl_sign, 0); + dap_sign_t *l_sign = dap_sign_create(a_key, l_event, l_event_size_excl_sign); size_t l_sign_size = dap_sign_get_size(l_sign); l_event = DAP_REALLOC_RET_VAL_IF_FAIL(*a_event_ptr, a_event_size + l_sign_size, a_event_size, l_sign); size_t l_event_size = a_event_size - sizeof(l_event->header); @@ -235,7 +235,7 @@ size_t dap_chain_cs_dag_event_round_sign_add(dap_chain_cs_dag_event_round_item_t dap_chain_cs_dag_event_round_item_t *l_round_item = *a_round_item_ptr; if (dap_chain_cs_dag_event_round_sign_exists(l_round_item, a_key)) return 0; - dap_sign_t * l_sign = dap_sign_create(a_key, &l_round_item->round_info.datum_hash, sizeof(dap_chain_hash_fast_t), 0); + dap_sign_t * l_sign = dap_sign_create(a_key, &l_round_item->round_info.datum_hash, sizeof(dap_chain_hash_fast_t)); size_t l_sign_size = dap_sign_get_size(l_sign); l_round_item = DAP_REALLOC_RET_VAL_IF_FAIL(*a_round_item_ptr, a_round_item_size + l_sign_size, a_round_item_size, l_sign); *a_round_item_ptr = l_round_item; diff --git a/modules/wallet/dap_chain_wallet.c b/modules/wallet/dap_chain_wallet.c index 9072beaf61..0438874c44 100644 --- a/modules/wallet/dap_chain_wallet.c +++ b/modules/wallet/dap_chain_wallet.c @@ -1216,6 +1216,14 @@ int dap_chain_wallet_get_pkey_hash(dap_chain_wallet_t *a_wallet, dap_hash_fast_t if (!l_key) return -2; int ret = dap_enc_key_get_pkey_hash(l_key, a_out_hash); - DAP_DELETE(l_key); + dap_enc_key_delete(l_key); return ret; } + +char *dap_chain_wallet_get_pkey_str(dap_chain_wallet_t *a_wallet, const char *a_str_type) +{ + dap_pkey_t *l_pkey = dap_chain_wallet_get_pkey(a_wallet, 0); + char *l_ret = dap_pkey_to_str(l_pkey, a_str_type); + DAP_DELETE(l_pkey); + return l_ret; +} diff --git a/modules/wallet/include/dap_chain_wallet.h b/modules/wallet/include/dap_chain_wallet.h index 0f1daa51e9..824203dafe 100644 --- a/modules/wallet/include/dap_chain_wallet.h +++ b/modules/wallet/include/dap_chain_wallet.h @@ -101,6 +101,8 @@ int dap_chain_wallet_add_wallet_opened_notify(dap_chain_wallet_opened_callback_t int dap_chain_wallet_add_wallet_created_notify(dap_chain_wallet_opened_callback_t a_callback, void *a_arg); dap_list_t* dap_chain_wallet_get_local_addr(); +int dap_chain_wallet_get_pkey_hash(dap_chain_wallet_t *a_wallet, dap_hash_fast_t *a_out_hash); +char *dap_chain_wallet_get_pkey_str(dap_chain_wallet_t *a_wallet, const char *a_str_type); #ifdef __cplusplus } #endif -- GitLab