1
0
Fork 0
forked from lthn/blockchain

improved alias detection in transaction history + added RPC API for alias registration

This commit is contained in:
cryptozoidberg 2022-06-16 17:02:00 +02:00
parent 6317a48bb9
commit 0e5bcbef47
No known key found for this signature in database
GPG key ID: 22DEB97A54C6FDEC
14 changed files with 170 additions and 30 deletions

View file

@ -62,6 +62,8 @@ namespace epee
t_pod_type transform_str_to_t_pod(const std::string& a)
{
t_pod_type res = AUTO_VAL_INIT(res);
if (a.empty())
return res;
if (!epee::string_tools::hex_to_pod(a, res))
throw std::runtime_error(std::string("Unable to transform \"") + a + "\" to pod type " + typeid(t_pod_type).name());
return res;

View file

@ -3506,6 +3506,17 @@ std::string blockchain_storage::get_alias_by_address(const account_public_addres
return "";
}
//------------------------------------------------------------------
std::set<std::string> blockchain_storage::get_aliases_by_address(const account_public_address& addr)const
{
auto alias_ptr = m_db_addr_to_alias.find(addr);
if (alias_ptr && alias_ptr->size())
{
return *(alias_ptr);
}
return std::set<std::string>();
}
//------------------------------------------------------------------
bool blockchain_storage::pop_alias_info(const extra_alias_entry& ai)
{
CRITICAL_REGION_LOCAL(m_read_lock);
@ -3695,15 +3706,6 @@ uint64_t blockchain_storage::validate_alias_reward(const transaction& tx, const
//validate the price had been paid
uint64_t found_alias_reward = get_amount_for_zero_pubkeys(tx);
//@#@
//work around for net 68's generation
#if CURRENCY_FORMATION_VERSION == 68
if (alias == "bhrfrrrtret" && get_transaction_hash(tx) == epee::string_tools::parse_tpod_from_hex_string<crypto::hash>("760b85546678d2235a1843e18d8a016a2e4d9b8273cc4d7c09bebff1f6fa7eaf") )
return true;
if (alias == "test-420" && get_transaction_hash(tx) == epee::string_tools::parse_tpod_from_hex_string<crypto::hash>("10f8a2539b2551bd0919bf7e3b1dfbae7553eca63e58cd2264ae60f90030edf8"))
return true;
#endif
CHECK_AND_ASSERT_MES(found_alias_reward >= fee_for_alias, false, "registration of alias '"
<< alias << "' goes with a reward of " << print_money(found_alias_reward) << " which is less than expected: " << print_money(fee_for_alias)
<<"(fee median: " << get_tx_fee_median() << ")"

View file

@ -279,6 +279,7 @@ namespace currency
bool get_tx_outputs_gindexs(const crypto::hash& tx_id, std::vector<uint64_t>& indexs)const;
bool get_alias_info(const std::string& alias, extra_alias_entry_base& info)const;
std::string get_alias_by_address(const account_public_address& addr)const;
std::set<std::string> get_aliases_by_address(const account_public_address& addr)const;
template<typename cb_t>
bool enumerate_aliases(cb_t cb) const;
template<typename cb_t>

View file

@ -1291,7 +1291,7 @@ namespace currency
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::on_alias_by_address(const COMMAND_RPC_GET_ALIASES_BY_ADDRESS::request& req, COMMAND_RPC_GET_ALIASES_BY_ADDRESS::response& res, epee::json_rpc::error& error_resp, connection_context& cntx)
bool core_rpc_server::on_aliases_by_address(const COMMAND_RPC_GET_ALIASES_BY_ADDRESS::request& req, COMMAND_RPC_GET_ALIASES_BY_ADDRESS::response& res, epee::json_rpc::error& error_resp, connection_context& cntx)
{
account_public_address addr = AUTO_VAL_INIT(addr);
if (!get_account_address_from_str(addr, req))
@ -1303,22 +1303,28 @@ namespace currency
COMMAND_RPC_GET_ALIAS_DETAILS::request req2 = AUTO_VAL_INIT(req2);
COMMAND_RPC_GET_ALIAS_DETAILS::response res2 = AUTO_VAL_INIT(res2);
req2.alias = m_core.get_blockchain_storage().get_alias_by_address(addr);
if (!req2.alias.size())
std::set<std::string> aliases = m_core.get_blockchain_storage().get_aliases_by_address(addr);
if (!aliases.size())
{
res.status = API_RETURN_CODE_NOT_FOUND;
return true;
}
for (auto it = aliases.begin(); it != aliases.end(); it++)
{
req2.alias = *it;
bool r = this->on_get_alias_details(req2, res2, error_resp, cntx);
if (!r || res2.status != API_RETURN_CODE_OK)
{
res.status = API_RETURN_CODE_FAIL;
return true;
}
res.alias_info_list.push_back(alias_rpc_details());
res.alias_info_list.back().details = res2.alias_details;
res.alias_info_list.back().alias = req2.alias;
res.alias_info.details = res2.alias_details;
res.alias_info.alias = req2.alias;
}
res.status = API_RETURN_CODE_OK;
return true;
}

View file

@ -71,7 +71,7 @@ namespace currency
bool on_get_alias_details(const COMMAND_RPC_GET_ALIAS_DETAILS::request& req, COMMAND_RPC_GET_ALIAS_DETAILS::response& res, epee::json_rpc::error& error_resp, connection_context& cntx);
bool on_get_all_aliases(const COMMAND_RPC_GET_ALL_ALIASES::request& req, COMMAND_RPC_GET_ALL_ALIASES::response& res, epee::json_rpc::error& error_resp, connection_context& cntx);
bool on_get_aliases(const COMMAND_RPC_GET_ALIASES::request& req, COMMAND_RPC_GET_ALIASES::response& res, epee::json_rpc::error& error_resp, connection_context& cntx);
bool on_alias_by_address(const COMMAND_RPC_GET_ALIASES_BY_ADDRESS::request& req, COMMAND_RPC_GET_ALIASES_BY_ADDRESS::response& res, epee::json_rpc::error& error_resp, connection_context& cntx);
bool on_aliases_by_address(const COMMAND_RPC_GET_ALIASES_BY_ADDRESS::request& req, COMMAND_RPC_GET_ALIASES_BY_ADDRESS::response& res, epee::json_rpc::error& error_resp, connection_context& cntx);
bool on_get_alias_reward(const COMMAND_RPC_GET_ALIAS_REWARD::request& req, COMMAND_RPC_GET_ALIAS_REWARD::response& res, epee::json_rpc::error& error_resp, connection_context& cntx);
bool on_get_addendums(const COMMAND_RPC_GET_ADDENDUMS::request& req, COMMAND_RPC_GET_ADDENDUMS::response& res, epee::json_rpc::error& error_resp, connection_context& cntx);
bool on_reset_transaction_pool(const COMMAND_RPC_RESET_TX_POOL::request& req, COMMAND_RPC_RESET_TX_POOL::response& res, connection_context& cntx);
@ -134,7 +134,7 @@ namespace currency
MAP_JON_RPC_WE("getblockheaderbyhash", on_get_block_header_by_hash, COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH)
MAP_JON_RPC_WE("getblockheaderbyheight", on_get_block_header_by_height, COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT)
MAP_JON_RPC_WE("get_alias_details", on_get_alias_details, COMMAND_RPC_GET_ALIAS_DETAILS)
MAP_JON_RPC_WE("get_alias_by_address", on_alias_by_address, COMMAND_RPC_GET_ALIASES_BY_ADDRESS)
MAP_JON_RPC_WE("get_alias_by_address", on_aliases_by_address, COMMAND_RPC_GET_ALIASES_BY_ADDRESS)
MAP_JON_RPC_WE("get_alias_reward", on_get_alias_reward, COMMAND_RPC_GET_ALIAS_REWARD)
MAP_JON_RPC ("get_est_height_from_date", on_get_est_height_from_date, COMMAND_RPC_GET_EST_HEIGHT_FROM_DATE)
//block explorer api

View file

@ -1069,11 +1069,11 @@ namespace currency
struct response
{
//std::string alias;
alias_rpc_details alias_info;
std::vector<alias_rpc_details> alias_info_list;
std::string status;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(alias_info)
KV_SERIALIZE(alias_info_list)
KV_SERIALIZE(status)
END_KV_SERIALIZE_MAP()
};

View file

@ -50,7 +50,7 @@ namespace tools
//------------------------------------------------------------------------------------------------------------------------------
bool call_COMMAND_RPC_GET_ALIASES_BY_ADDRESS(const currency::COMMAND_RPC_GET_ALIASES_BY_ADDRESS::request& req, currency::COMMAND_RPC_GET_ALIASES_BY_ADDRESS::response& res) override
{
return m_rpc.on_alias_by_address(req, res, m_err_stub, m_cntxt_stub);
return m_rpc.on_aliases_by_address(req, res, m_err_stub, m_cntxt_stub);
}
//------------------------------------------------------------------------------------------------------------------------------
bool call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS(const currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res) override

View file

@ -3308,6 +3308,11 @@ void wallet2::get_recent_transfers_history(std::vector<wallet_public::wallet_tra
last_item_index = offset + local_offset;
trs.back().transfer_internal_index = last_item_index;
if (wti.remote_addresses.size() == 1)
{
wti.recipients_aliases = get_aliases_for_address(wti.remote_addresses[0]);
}
if (trs.size() >= count)
{
return false;
@ -3872,13 +3877,56 @@ void wallet2::push_alias_info_to_extra_according_to_hf_status(const currency::ex
}
}
//----------------------------------------------------------------------------------------------------
void wallet2::request_alias_registration(const currency::extra_alias_entry& ai, currency::transaction& res_tx, uint64_t fee, uint64_t reward)
uint64_t wallet2::get_alias_cost(const std::string& alias)
{
currency::COMMAND_RPC_GET_ALIAS_REWARD::request req = AUTO_VAL_INIT(req);
currency::COMMAND_RPC_GET_ALIAS_REWARD::response rsp = AUTO_VAL_INIT(rsp);
req.alias = alias;
if (!m_core_proxy->call_COMMAND_RPC_GET_ALIAS_REWARD(req, rsp))
{
throw std::runtime_error(std::string("Failed to get alias cost"));
}
return rsp.reward + rsp.reward / 10; //add 10% of price to be sure;
}
//----------------------------------------------------------------------------------------------------
void wallet2::request_alias_registration(currency::extra_alias_entry& ai, currency::transaction& res_tx, uint64_t fee, uint64_t reward, const crypto::secret_key& authority_key)
{
if (!validate_alias_name(ai.m_alias))
{
throw std::runtime_error(std::string("wrong alias characters: ") + ai.m_alias);
}
if (ai.m_alias.size() < ALIAS_MINIMUM_PUBLIC_SHORT_NAME_ALLOWED)
{
if (authority_key == currency::null_skey)
{
throw std::runtime_error(std::string("Short aliases is not allowed without authority key: ") + ALIAS_SHORT_NAMES_VALIDATION_PUB_KEY);
}
crypto::public_key authority_pub = AUTO_VAL_INIT(authority_pub);
bool r = crypto::secret_key_to_public_key(authority_key, authority_pub);
CHECK_AND_ASSERT_THROW_MES(r, "Failed to generate pub key from secrete authority key");
if (string_tools::pod_to_hex(authority_pub) != ALIAS_SHORT_NAMES_VALIDATION_PUB_KEY)
{
throw std::runtime_error(std::string("Short aliases is not allowed to register by this authority key"));
}
r = currency::sign_extra_alias_entry(ai, authority_pub, authority_key);
CHECK_AND_ASSERT_THROW_MES(r, "Failed to sign alias update");
WLT_LOG_L2("Generated update alias info: " << ENDL
<< "alias: " << ai.m_alias << ENDL
<< "signature: " << currency::print_t_array(ai.m_sign) << ENDL
<< "signed(owner) pub key: " << m_account.get_keys().account_address.spend_public_key << ENDL
<< "to address: " << get_account_address_as_str(ai.m_address) << ENDL
<< "sign_buff_hash: " << currency::get_sign_buff_hash_for_alias_update(ai)
);
}
if (!reward)
{
reward = get_alias_cost(ai.m_alias);
}
std::vector<currency::tx_destination_entry> destinations;
std::vector<currency::extra_v> extra;
std::vector<currency::attachment_v> attachments;
@ -5147,16 +5195,29 @@ void wallet2::add_sent_unconfirmed_tx(const currency::transaction& tx,
}
//----------------------------------------------------------------------------------------------------
std::string wallet2::get_alias_for_address(const std::string& addr)
{
std::vector<std::string> aliases = get_aliases_for_address(addr);
if (aliases.size())
return aliases.front();
return "";
}
//----------------------------------------------------------------------------------------------------
std::vector<std::string> wallet2::get_aliases_for_address(const std::string& addr)
{
PROFILE_FUNC("wallet2::get_alias_for_address");
currency::COMMAND_RPC_GET_ALIASES_BY_ADDRESS::request req = addr;
currency::COMMAND_RPC_GET_ALIASES_BY_ADDRESS::response res = AUTO_VAL_INIT(res);
std::vector<std::string> aliases;
if (!m_core_proxy->call_COMMAND_RPC_GET_ALIASES_BY_ADDRESS(req, res))
{
WLT_LOG_L0("Failed to COMMAND_RPC_GET_ALIASES_BY_ADDRESS");
return "";
return aliases;
}
return res.alias_info.alias;
for (auto& e : res.alias_info_list)
{
aliases.push_back(e.alias);
}
return aliases;
}
//----------------------------------------------------------------------------------------------------
void wallet2::transfer(const std::vector<currency::tx_destination_entry>& dsts, size_t fake_outputs_count,

View file

@ -541,7 +541,7 @@ namespace tools
void push_offer(const bc_services::offer_details_ex& od, currency::transaction& res_tx);
void cancel_offer_by_id(const crypto::hash& tx_id, uint64_t of_ind, uint64_t fee, currency::transaction& tx);
void update_offer_by_id(const crypto::hash& tx_id, uint64_t of_ind, const bc_services::offer_details_ex& od, currency::transaction& res_tx);
void request_alias_registration(const currency::extra_alias_entry& ai, currency::transaction& res_tx, uint64_t fee, uint64_t reward);
void request_alias_registration(currency::extra_alias_entry& ai, currency::transaction& res_tx, uint64_t fee, uint64_t reward, const crypto::secret_key& authority_key = currency::null_skey);
void request_alias_update(currency::extra_alias_entry& ai, currency::transaction& res_tx, uint64_t fee, uint64_t reward);
bool check_available_sources(std::list<uint64_t>& amounts);
@ -868,7 +868,7 @@ namespace tools
void set_use_deffered_global_outputs(bool use);
construct_tx_param get_default_construct_tx_param_inital();
void set_disable_tor_relay(bool disable);
uint64_t get_default_fee() {return TX_DEFAULT_FEE;}
void export_transaction_history(std::ostream& ss, const std::string& format, bool include_pos_transactions = true);
/*
@ -933,6 +933,7 @@ private:
void handle_pulled_blocks(size_t& blocks_added, std::atomic<bool>& stop,
currency::COMMAND_RPC_GET_BLOCKS_DIRECT::response& blocks);
std::string get_alias_for_address(const std::string& addr);
std::vector<std::string> get_aliases_for_address(const std::string& addr);
static bool build_kernel(const currency::pos_entry& pe, const currency::stake_modifier_type& stake_modifier, const uint64_t timestamp, currency::stake_kernel& kernel);
bool is_connected_to_net();
bool is_transfer_okay_for_pos(const transfer_details& tr, uint64_t& stake_unlock_time);
@ -1019,6 +1020,7 @@ private:
void push_alias_info_to_extra_according_to_hf_status(const currency::extra_alias_entry& ai, std::vector<currency::extra_v>& extra);
void remove_transfer_from_amount_gindex_map(uint64_t tid);
uint64_t get_alias_cost(const std::string& alias);
static void wti_to_csv_entry(std::ostream& ss, const wallet_public::wallet_transfer_info& wti, size_t index);
static void wti_to_txt_line(std::ostream& ss, const wallet_public::wallet_transfer_info& wti, size_t index);

View file

@ -377,7 +377,28 @@ namespace wallet_public
};
};
struct COMMAND_RPC_REGISTER_ALIAS
{
struct request
{
currency::alias_rpc_details al;
crypto::secret_key authority_key;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(al)
KV_SERIALIZE_POD_AS_HEX_STRING(authority_key)
END_KV_SERIALIZE_MAP()
};
struct response
{
crypto::hash tx_id;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE_POD_AS_HEX_STRING(tx_id)
END_KV_SERIALIZE_MAP()
};
};
struct transfer_destination

View file

@ -747,6 +747,31 @@ namespace tools
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
bool wallet_rpc_server::on_register_alias(const wallet_public::COMMAND_RPC_REGISTER_ALIAS::request& req, wallet_public::COMMAND_RPC_REGISTER_ALIAS::response& res, epee::json_rpc::error& er, connection_context& cntx)
{
WALLET_RPC_BEGIN_TRY_ENTRY();
currency::extra_alias_entry ai = AUTO_VAL_INIT(ai);
if (!alias_rpc_details_to_alias_info(req.al, ai))
{
er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS;
er.message = "WALLET_RPC_ERROR_CODE_WRONG_ADDRESS";
return false;
}
if (!currency::validate_alias_name(ai.m_alias))
{
er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS;
er.message = "WALLET_RPC_ERROR_CODE_WRONG_ADDRESS - Wrong alias name";
return false;
}
currency::transaction tx = AUTO_VAL_INIT(tx);
m_wallet.request_alias_registration(ai, tx, m_wallet.get_default_fee(), 0, req.authority_key);
res.tx_id = get_transaction_hash(tx);
return true;
WALLET_RPC_CATCH_TRY_ENTRY();
}
//------------------------------------------------------------------------------------------------------------------------------
bool wallet_rpc_server::on_contracts_send_proposal(const wallet_public::COMMAND_CONTRACTS_SEND_PROPOSAL::request& req, wallet_public::COMMAND_CONTRACTS_SEND_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx)
{
WALLET_RPC_BEGIN_TRY_ENTRY();

View file

@ -54,6 +54,7 @@ namespace tools
MAP_JON_RPC_WE("get_restore_info", on_getwallet_restore_info, wallet_public::COMMAND_RPC_GET_WALLET_RESTORE_INFO)
MAP_JON_RPC_WE("get_seed_phrase_info", on_get_seed_phrase_info, wallet_public::COMMAND_RPC_GET_SEED_PHRASE_INFO)
MAP_JON_RPC_WE("get_mining_history", on_get_mining_history, wallet_public::COMMAND_RPC_GET_MINING_HISTORY)
MAP_JON_RPC_WE("register_alias", on_register_alias, wallet_public::COMMAND_RPC_REGISTER_ALIAS)
//contracts API
MAP_JON_RPC_WE("contracts_send_proposal", on_contracts_send_proposal, wallet_public::COMMAND_CONTRACTS_SEND_PROPOSAL)
MAP_JON_RPC_WE("contracts_accept_proposal", on_contracts_accept_proposal, wallet_public::COMMAND_CONTRACTS_ACCEPT_PROPOSAL)
@ -93,6 +94,8 @@ namespace tools
bool on_submit_transfer(const wallet_public::COMMAND_SUBMIT_TRANSFER::request& req, wallet_public::COMMAND_SUBMIT_TRANSFER::response& res, epee::json_rpc::error& er, connection_context& cntx);
bool on_search_for_transactions(const wallet_public::COMMAND_RPC_SEARCH_FOR_TRANSACTIONS::request& req, wallet_public::COMMAND_RPC_SEARCH_FOR_TRANSACTIONS::response& res, epee::json_rpc::error& er, connection_context& cntx);
bool on_get_mining_history(const wallet_public::COMMAND_RPC_GET_MINING_HISTORY::request& req, wallet_public::COMMAND_RPC_GET_MINING_HISTORY::response& res, epee::json_rpc::error& er, connection_context& cntx);
bool on_register_alias(const wallet_public::COMMAND_RPC_REGISTER_ALIAS::request& req, wallet_public::COMMAND_RPC_REGISTER_ALIAS::response& res, epee::json_rpc::error& er, connection_context& cntx);
bool on_contracts_send_proposal(const wallet_public::COMMAND_CONTRACTS_SEND_PROPOSAL::request& req, wallet_public::COMMAND_CONTRACTS_SEND_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx);
bool on_contracts_accept_proposal(const wallet_public::COMMAND_CONTRACTS_ACCEPT_PROPOSAL::request& req, wallet_public::COMMAND_CONTRACTS_ACCEPT_PROPOSAL::response& res, epee::json_rpc::error& er, connection_context& cntx);

View file

@ -1254,7 +1254,10 @@ std::string wallets_manager::get_alias_info_by_address(const std::string& addr,
if (res.status != API_RETURN_CODE_OK)
return res.status;
res_details = res.alias_info;
if (res.alias_info_list.empty())
return API_RETURN_CODE_NOT_FOUND;
res_details = res.alias_info_list.front();
return res.status;
}

View file

@ -0,0 +1,14 @@
{
"jsonrpc": "2.0",
"id": 0,
"method": "register_alias",
"params": {
"al": {
"alias": "zinazinazina",
"address": "ZxDFNTq2Qf3FPvHakortVe3HxQBXwWNkWZydqfksgv9NRh1Z5b4tE91geYbmPn4JEoNxTMbj8Wj6R4v3fhV6K4Qh36hLacW1w",
"tracking_key": "",
"comment": ""
},
"authority_key": ""
}
}