From e929addc06b73ec7c66a0fde9369c9b6a4722c2a Mon Sep 17 00:00:00 2001 From: "pavel.uhanov" <pavel.uhanov@demlabs.net> Date: Sat, 28 Dec 2024 07:59:04 +0000 Subject: [PATCH] feature-13637 --- dap-sdk | 2 +- modules/chain/dap_chain_srv.c | 2 + modules/chain/tests/dap_chain_ledger_tests.c | 6 +- .../consensus/esbocs/dap_chain_cs_esbocs.c | 8 +- modules/datum/dap_chain_datum_decree.c | 23 +- modules/datum/dap_chain_datum_token.c | 2 +- modules/datum/dap_chain_datum_tx_items.c | 21 +- modules/datum/dap_chain_datum_tx_receipt.c | 2 +- .../datum/include/dap_chain_datum_decree.h | 9 + .../datum/include/dap_chain_datum_tx_items.h | 6 +- .../include/dap_chain_datum_tx_out_cond.h | 1 + modules/ledger/dap_chain_ledger.c | 35 ++ modules/ledger/dap_chain_ledger_decree.c | 15 +- modules/ledger/include/dap_chain_ledger.h | 1 + modules/net-srv/dap_chain_net_srv_order.c | 2 +- modules/net/dap_chain_net_ch.c | 2 +- modules/node-cli/dap_chain_node_cli_cmd.c | 4 +- .../node-cli/dap_chain_node_cli_cmd_token.c | 2 +- modules/node-cli/dap_chain_node_cli_cmd_tx.c | 10 +- .../dap_chain_net_srv_stake_pos_delegate.c | 354 ++++++++++++++++-- .../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 | 3 +- 26 files changed, 471 insertions(+), 63 deletions(-) diff --git a/dap-sdk b/dap-sdk index 16b196ba28..0b186bf875 160000 --- a/dap-sdk +++ b/dap-sdk @@ -1 +1 @@ -Subproject commit 16b196ba28b0bd3caac2a263710093333b271b04 +Subproject commit 0b186bf875b9eac4d0df092f6bb849f73994251b diff --git a/modules/chain/dap_chain_srv.c b/modules/chain/dap_chain_srv.c index f230fc9461..9a405ce2d6 100644 --- a/modules/chain/dap_chain_srv.c +++ b/modules/chain/dap_chain_srv.c @@ -234,6 +234,8 @@ void *dap_chain_srv_get_internal(dap_chain_net_id_t a_net_id, dap_chain_srv_uid_ struct service_list *l_service_item = s_service_find(a_srv_uid); if (!l_service_item) return NULL; + if (a_net_id.uint64 == 0) + return l_service_item->networks; struct network_service *l_service = s_net_service_find(l_service_item, a_net_id); return l_service ? l_service->service : NULL; } diff --git a/modules/chain/tests/dap_chain_ledger_tests.c b/modules/chain/tests/dap_chain_ledger_tests.c index 0d095b8844..6e18ff6e92 100644 --- a/modules/chain/tests/dap_chain_ledger_tests.c +++ b/modules/chain/tests/dap_chain_ledger_tests.c @@ -42,7 +42,7 @@ dap_chain_datum_token_t *dap_ledger_test_create_datum_update(dap_cert_t *a_cert, 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); + sizeof(*l_token) + a_size_tsd_section, DAP_SIGN_HASH_TYPE_DEFAULT); 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); @@ -77,7 +77,7 @@ dap_chain_datum_token_t *dap_ledger_test_create_datum_decl(dap_cert_t *a_cert, 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); + sizeof(*l_token) + a_size_tsd_section, DAP_SIGN_HASH_TYPE_DEFAULT); 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); @@ -365,7 +365,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, DAP_SIGN_HASH_TYPE_DEFAULT); if (!l_sign) { DAP_DELETE(l_decree); return -2; diff --git a/modules/consensus/esbocs/dap_chain_cs_esbocs.c b/modules/consensus/esbocs/dap_chain_cs_esbocs.c index 12c8828be7..ed9be96ca9 100644 --- a/modules/consensus/esbocs/dap_chain_cs_esbocs.c +++ b/modules/consensus/esbocs/dap_chain_cs_esbocs.c @@ -308,7 +308,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) @@ -748,7 +748,7 @@ static int s_callback_purge(dap_chain_t *a_chain) 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; return 0; @@ -2539,7 +2539,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), DAP_SIGN_ADD_PKEY_HASHING_FLAG(DAP_SIGN_HASH_TYPE_DEFAULT)); 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); @@ -2744,7 +2744,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, DAP_SIGN_ADD_PKEY_HASHING_FLAG(DAP_SIGN_HASH_TYPE_DEFAULT) ); 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/datum/dap_chain_datum_decree.c b/modules/datum/dap_chain_datum_decree.c index 007bfdc1bb..e2f613465f 100644 --- a/modules/datum/dap_chain_datum_decree.c +++ b/modules/datum/dap_chain_datum_decree.c @@ -149,6 +149,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 +323,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; @@ -379,7 +400,7 @@ dap_chain_datum_decree_t *dap_chain_datum_decree_sign_in_cycle(dap_cert_t **a_ce 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); + sizeof(dap_chain_datum_decree_t) + a_datum_decree->header.data_size, DAP_SIGN_HASH_TYPE_DEFAULT); if (!l_sign) { log_it(L_ERROR, "Decree signing failed"); DAP_DELETE(a_datum_decree); diff --git a/modules/datum/dap_chain_datum_token.c b/modules/datum/dap_chain_datum_token.c index cd066fca13..a396f9bbeb 100644 --- a/modules/datum/dap_chain_datum_token.c +++ b/modules/datum/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, DAP_SIGN_HASH_TYPE_DEFAULT); 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/datum/dap_chain_datum_tx_items.c b/modules/datum/dap_chain_datum_tx_items.c index b7307dda1b..b3c066ad7f 100644 --- a/modules/datum/dap_chain_datum_tx_items.c +++ b/modules/datum/dap_chain_datum_tx_items.c @@ -340,12 +340,14 @@ 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_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); + 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(dap_chain_tx_out_cond_t, sizeof(dap_chain_tx_out_cond_t) + l_tsd_total_size); if (!l_item) { return NULL; @@ -358,8 +360,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; } @@ -432,7 +441,7 @@ dap_chain_tx_sig_t *dap_chain_datum_tx_item_sign_create(dap_enc_key_t *a_key, da return NULL; } l_tx->header.tx_items_size = 0; - dap_sign_t *l_chain_sign = dap_sign_create(a_key, l_tx, l_tx_size, 0); + dap_sign_t *l_chain_sign = dap_sign_create(a_key, l_tx, l_tx_size, DAP_SIGN_HASH_TYPE_DEFAULT); DAP_DELETE(l_tx); if (!l_chain_sign) return NULL; diff --git a/modules/datum/dap_chain_datum_tx_receipt.c b/modules/datum/dap_chain_datum_tx_receipt.c index 4624ef30e5..52aef80185 100644 --- a/modules/datum/dap_chain_datum_tx_receipt.c +++ b/modules/datum/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), DAP_SIGN_HASH_TYPE_DEFAULT); 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/datum/include/dap_chain_datum_decree.h b/modules/datum/include/dap_chain_datum_decree.h index 075939ce71..da4a463cad 100644 --- a/modules/datum/include/dap_chain_datum_decree.h +++ b/modules/datum/include/dap_chain_datum_decree.h @@ -76,6 +76,7 @@ DAP_STATIC_INLINE size_t dap_chain_datum_decree_get_size(dap_chain_datum_decree_ #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_HARDFORK 0x000F +#define DAP_CHAIN_DATUM_DECREE_COMMON_SUBTYPE_STAKE_PKEY_UPDATE 0x0010 // DECREE TSD types #define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_VALUE 0x0100 @@ -95,6 +96,7 @@ DAP_STATIC_INLINE size_t dap_chain_datum_decree_get_size(dap_chain_datum_decree_ #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_BLOCK_NUM 0x010C +#define DAP_CHAIN_DATUM_DECREE_TSD_TYPE_STAKE_PKEY 0x010D DAP_STATIC_INLINE const char *dap_chain_datum_decree_subtype_to_str(uint16_t a_decree_subtype) { @@ -125,6 +127,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"; } @@ -157,6 +161,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; } @@ -196,6 +202,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"; } @@ -303,6 +311,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 diff --git a/modules/datum/include/dap_chain_datum_tx_items.h b/modules/datum/include/dap_chain_datum_tx_items.h index 25ef0070a4..c8be707da1 100644 --- a/modules/datum/include/dap_chain_datum_tx_items.h +++ b/modules/datum/include/dap_chain_datum_tx_items.h @@ -155,8 +155,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; } /** @@ -166,7 +166,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_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_srv_uid_t a_srv_uid, diff --git a/modules/datum/include/dap_chain_datum_tx_out_cond.h b/modules/datum/include/dap_chain_datum_tx_out_cond.h index 8a9a1b25fa..c765295b49 100644 --- a/modules/datum/include/dap_chain_datum_tx_out_cond.h +++ b/modules/datum/include/dap_chain_datum_tx_out_cond.h @@ -116,6 +116,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/ledger/dap_chain_ledger.c b/modules/ledger/dap_chain_ledger.c index 853193834d..1f1cb90674 100644 --- a/modules/ledger/dap_chain_ledger.c +++ b/modules/ledger/dap_chain_ledger.c @@ -1227,6 +1227,41 @@ const dap_chain_datum_tx_t* dap_ledger_tx_find_by_pkey(dap_ledger_t *a_ledger, pthread_rwlock_unlock(&l_ledger_pvt->ledger_rwlock); return l_cur_tx; } +/** + * @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; +} /** * @brief Get all transactions from the cache with the out_cond item diff --git a/modules/ledger/dap_chain_ledger_decree.c b/modules/ledger/dap_chain_ledger_decree.c index 3ecfd2f963..1756af8d5e 100644 --- a/modules/ledger/dap_chain_ledger_decree.c +++ b/modules/ledger/dap_chain_ledger_decree.c @@ -410,9 +410,22 @@ 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, NULL); dap_chain_net_srv_stake_add_approving_decree_info(a_decree, a_net); 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)){ log_it(L_WARNING,"Can't get signing address from decree."); diff --git a/modules/ledger/include/dap_chain_ledger.h b/modules/ledger/include/dap_chain_ledger.h index 191093ae4a..5892b17f3d 100644 --- a/modules/ledger/include/dap_chain_ledger.h +++ b/modules/ledger/include/dap_chain_ledger.h @@ -506,3 +506,4 @@ dap_ledger_hardfork_anchors_t *dap_ledger_anchors_aggregate(dap_ledger_t *a_ledg uint256_t dap_ledger_coin_get_uncoloured_value(dap_ledger_t *a_ledger, dap_hash_fast_t *a_voting_hash, dap_hash_fast_t *a_tx_prev_hash, int a_out_idx); void dap_ledger_tx_clear_colour(dap_ledger_t *a_ledger, dap_hash_fast_t *a_tx_hash); +dap_pkey_t *dap_ledger_find_pkey_by_hash(dap_ledger_t *a_ledger, dap_chain_hash_fast_t *a_pkey_hash); diff --git a/modules/net-srv/dap_chain_net_srv_order.c b/modules/net-srv/dap_chain_net_srv_order.c index 4767c73355..d49efaf214 100644 --- a/modules/net-srv/dap_chain_net_srv_order.c +++ b/modules/net-srv/dap_chain_net_srv_order.c @@ -360,7 +360,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, DAP_SIGN_HASH_TYPE_DEFAULT); if (!l_sign) { DAP_DELETE(l_order); return NULL; diff --git a/modules/net/dap_chain_net_ch.c b/modules/net/dap_chain_net_ch.c index 35903022e6..33e9ebd115 100644 --- a/modules/net/dap_chain_net_ch.c +++ b/modules/net/dap_chain_net_ch.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, DAP_SIGN_HASH_TYPE_DEFAULT); if (l_sign) { sign_s = dap_sign_get_size(l_sign); flags = flags | D_SIGN;//data signed diff --git a/modules/node-cli/dap_chain_node_cli_cmd.c b/modules/node-cli/dap_chain_node_cli_cmd.c index 037c382c1d..a70606456a 100644 --- a/modules/node-cli/dap_chain_node_cli_cmd.c +++ b/modules/node-cli/dap_chain_node_cli_cmd.c @@ -3859,7 +3859,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); + sizeof(dap_chain_datum_anchor_t) + a_datum_anchor->header.data_size, DAP_SIGN_HASH_TYPE_DEFAULT); if (l_sign) { size_t l_sign_size = dap_sign_get_size(l_sign); @@ -5266,7 +5266,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, DAP_SIGN_HASH_TYPE_DEFAULT); if (*a_signed == NULL) { DAP_DELETE(l_buffer); return -9; diff --git a/modules/node-cli/dap_chain_node_cli_cmd_token.c b/modules/node-cli/dap_chain_node_cli_cmd_token.c index 0ea06e1d4b..d839b90ce1 100644 --- a/modules/node-cli/dap_chain_node_cli_cmd_token.c +++ b/modules/node-cli/dap_chain_node_cli_cmd_token.c @@ -82,7 +82,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); + sizeof(*l_datum_token) + l_tsd_size, DAP_SIGN_HASH_TYPE_DEFAULT); if (l_sign) { size_t l_sign_size = dap_sign_get_size(l_sign); dap_chain_datum_token_t *l_datum_token_new diff --git a/modules/node-cli/dap_chain_node_cli_cmd_tx.c b/modules/node-cli/dap_chain_node_cli_cmd_tx.c index ada6781479..486a2182e8 100644 --- a/modules/node-cli/dap_chain_node_cli_cmd_tx.c +++ b/modules/node-cli/dap_chain_node_cli_cmd_tx.c @@ -1730,8 +1730,16 @@ int s_json_rpc_tx_parse_json(dap_chain_net_t *a_net, dap_chain_t *a_chain, json_ log_it(L_ERROR, "Json TX: bad node_addr in OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE"); break; } + // Maybe should get pkey and tronsform to dap_pkey_t + dap_pkey_t *l_pkey = NULL; + const char *l_pkey_full_str = s_json_get_text(l_json_item_obj, "pkey_full"); + if(l_pkey_full_str) { + l_pkey = dap_pkey_get_from_str(l_pkey_full_str); + debug_if(!l_pkey, L_ERROR, "Json TX: bad pkey in OUT_COND_SUBTYPE_SRV_STAKE_POS_DELEGATE"); + } + 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, l_pkey); l_item = (const uint8_t*) l_out_cond_item; // Save value for using in In item if(l_item) { 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 9fe9c7ee21..f4f1b2fd1e 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 @@ -167,6 +167,20 @@ DAP_STATIC_INLINE char *s_get_approved_group(dap_chain_net_t *a_net) return a_net ? dap_strdup_printf("%s.orders.stake.approved", a_net->pub.gdb_groups_prefix) : NULL; } +static dap_pkey_t *s_get_pkey_by_hash_callback(const uint8_t *a_hash) +{ + dap_list_t *l_srv_stake_list = dap_chain_srv_get_internal((dap_chain_net_id_t) { .uint64 = 0 }, (dap_chain_srv_uid_t) { .uint64 = DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_ID }); + dap_chain_net_srv_stake_item_t *l_stake = NULL; + for ( ; l_srv_stake_list && !l_stake; l_srv_stake_list = l_srv_stake_list->next) { + struct srv_stake *l_srv_stake = l_srv_stake_list->data; + HASH_FIND(hh, l_srv_stake->itemlist, a_hash, sizeof(dap_hash_fast_t), l_stake); + } + if (l_stake) { + return l_stake->pkey; + } + return NULL; +} + /** * @brief dap_stream_ch_vpn_init Init actions for VPN stream channel * @return 0 if everything is okay, lesser then zero if errors @@ -189,7 +203,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" @@ -219,6 +233,8 @@ int dap_chain_net_srv_stake_pos_delegate_init() "\texample datoshi amount syntax (only integer) 1 20 0.4321e+4\n" ); + 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); dap_chain_static_srv_callbacks_t l_callbacks = { .start = s_pos_delegate_start, .delete = s_pos_delegate_delete, .purge = s_pos_delegate_purge, @@ -258,7 +274,7 @@ static void s_pos_delegate_delete(void *a_service_internal) 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); } struct cache_item *l_cache_item = NULL, *l_cache_tmp = NULL; HASH_ITER(hh, l_srv_stake->cache, l_cache_item, l_cache_tmp) { @@ -466,7 +482,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); struct srv_stake *l_srv_stake = s_srv_stake_by_net_id(a_net->pub.id); @@ -489,14 +505,31 @@ 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)) { HASH_ADD(ht, l_srv_stake->tx_itemlist, tx_hash, sizeof(dap_hash_fast_t), l_stake); 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_pkey_t *l_pkey = NULL; 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_stake->pkey) { + if (l_cond && 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; + l_stake->pkey = DAP_DUP_SIZE(l_pkey, dap_pkey_get_size(l_pkey)); + } + } + if (!l_stake->pkey) { + l_pkey = dap_ledger_find_pkey_by_hash(a_net->pub.ledger, &a_signing_addr->data.hash_fast); + l_stake->pkey = DAP_DUP_SIZE(l_pkey, dap_pkey_get_size(l_pkey)); + } + } + 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); @@ -559,6 +592,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); + struct srv_stake *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) { struct srv_stake *l_srv_stake = s_srv_stake_by_net_id(a_net_id); @@ -769,10 +824,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]; @@ -834,7 +888,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_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; @@ -1024,7 +1079,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 @@ -1122,13 +1177,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; @@ -1192,6 +1264,56 @@ 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, DAP_SIGN_HASH_TYPE_DEFAULT); + + 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) { @@ -1406,7 +1528,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, DAP_SIGN_HASH_TYPE_DEFAULT); if (l_sign) { size_t l_sign_size = dap_sign_get_size(l_sign); @@ -2032,13 +2154,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) { @@ -2123,11 +2256,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; bool l_add_hash_to_gdb = false; dap_cli_server_cmd_find_option_val(a_argv, a_arg_index, a_argc, "-net", &l_net_str); if (!l_net_str) { @@ -2157,14 +2293,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; @@ -2198,16 +2340,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"); + 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; @@ -2270,7 +2430,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); @@ -2354,6 +2514,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)) { @@ -2374,6 +2535,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) { @@ -2404,8 +2570,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"); @@ -2431,6 +2598,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; + } + + struct srv_stake *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, @@ -2844,6 +3066,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)); @@ -3021,7 +3246,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; @@ -3068,6 +3293,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), "check", NULL)) { l_cmd_num = CMD_CHECK; } + 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; + } 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; } @@ -3085,6 +3316,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: { @@ -3211,6 +3445,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; + } + struct srv_stake *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)) { @@ -3262,7 +3560,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 8f8b2b5fcd..cbdeeb0669 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 { // TODO move it to private section 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; @@ -49,9 +50,10 @@ int dap_chain_net_srv_stake_pos_delegate_init(); void dap_chain_net_srv_stake_pos_delegate_deinit(); 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 887f06e0c8..7b7349c25e 100644 --- a/modules/type/blocks/dap_chain_block.c +++ b/modules/type/blocks/dap_chain_block.c @@ -283,7 +283,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), DAP_SIGN_ADD_PKEY_HASHING_FLAG(DAP_SIGN_HASH_TYPE_DEFAULT)); 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 4810a2a993..b98acbf16d 100644 --- a/modules/type/blocks/dap_chain_cs_blocks.c +++ b/modules/type/blocks/dap_chain_cs_blocks.c @@ -426,7 +426,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, DAP_SIGN_HASH_TYPE_DEFAULT); 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..c8f7d8784c 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, DAP_SIGN_HASH_TYPE_DEFAULT); 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, DAP_SIGN_HASH_TYPE_DEFAULT); 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), DAP_SIGN_HASH_TYPE_DEFAULT); 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 8717e40b56..238d391715 100644 --- a/modules/wallet/dap_chain_wallet.c +++ b/modules/wallet/dap_chain_wallet.c @@ -1291,6 +1291,14 @@ int dap_chain_wallet_get_pkey_hash(dap_chain_wallet_t *a_wallet, dap_hash_fast_t dap_enc_key_t *l_key = dap_chain_wallet_get_key(a_wallet, 0); dap_return_val_if_fail_err(l_key, -2, "Can't get wallet key!"); 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 be5c52f72b..73c18b418c 100644 --- a/modules/wallet/include/dap_chain_wallet.h +++ b/modules/wallet/include/dap_chain_wallet.h @@ -98,5 +98,6 @@ 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); 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); -dap_list_t* dap_chain_wallet_get_local_addr(); \ No newline at end of file +dap_list_t* dap_chain_wallet_get_local_addr(); -- GitLab