1
0
Fork 0
forked from lthn/blockchain

get_random_outs_for_amounts2 in work

This commit is contained in:
cryptozoidberg 2023-12-08 20:41:47 +01:00
parent 2d44c967ef
commit 5b4a3e3a38
No known key found for this signature in database
GPG key ID: 22DEB97A54C6FDEC
5 changed files with 159 additions and 0 deletions

View file

@ -2660,6 +2660,81 @@ bool blockchain_storage::get_random_outs_for_amounts(const COMMAND_RPC_GET_RANDO
return true;
}
//------------------------------------------------------------------
bool blockchain_storage::get_random_outs_for_amounts2(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::response& res)const
{
CRITICAL_REGION_LOCAL(m_read_lock);
LOG_PRINT_L3("[get_random_outs_for_amounts] amounts: " << req.amounts.size());
std::map<uint64_t, uint64_t> amounts_to_up_index_limit_cache;
for (size_t i = 0; i != req.amounts.size(); i++)
{
uint64_t amount = req.amounts[i].amount;
const std::list<uint64_t>& offsets = req.amounts[i].offsets;
COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs = *res.outs.insert(res.outs.end(), COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount());
result_outs.amount = amount;
uint64_t zc_hard_fork_after_h = m_core_runtime_config.hard_forks[ZANO_HARDFORK_04_ZARCANUM];
for (auto it = offsets.begin(); it != offsets.end(); it++)
{
uint64_t target_height =
}
uint64_t outs_container_size = m_db_outputs.get_item_size(amount);
if (!outs_container_size)
{
LOG_ERROR("COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS: not outs for amount " << amount << ", wallet should use some real outs when it lookup for some mix, so, at least one out for this amount should exist");
continue;//actually this is strange situation, wallet should use some real outs when it lookup for some mix, so, at least one out for this amount should exist
}
//it is not good idea to use top fresh outs, because it increases possibility of transaction canceling on split
//lets find upper bound of not fresh outs
size_t up_index_limit = 0;
auto it_limit = amounts_to_up_index_limit_cache.find(amount);
if (it_limit == amounts_to_up_index_limit_cache.end())
{
up_index_limit = find_end_of_allowed_index(amount);
amounts_to_up_index_limit_cache[up_index_limit];
}
else
{
up_index_limit = it_limit->second;
}
CHECK_AND_ASSERT_MES(up_index_limit <= outs_container_size, false, "internal error: find_end_of_allowed_index returned wrong index=" << up_index_limit << ", with amount_outs.size = " << outs_container_size);
if (up_index_limit >= req.decoys_count)
{
std::set<size_t> used;
size_t try_count = 0;
for (uint64_t j = 0; j != req.decoys_count && try_count < up_index_limit;)
{
size_t g_index = crypto::rand<size_t>() % up_index_limit;
if (used.count(g_index))
continue;
bool added = add_out_to_get_random_outs(result_outs, amount, g_index, req.decoys_count, req.use_forced_mix_outs, req.height_upper_limit);
used.insert(g_index);
if (added)
++j;
++try_count;
}
if (result_outs.outs.size() < req.decoys_count)
{
LOG_PRINT_YELLOW("Not enough inputs for amount " << print_money_brief(amount) << ", needed " << req.decoys_count << ", added " << result_outs.outs.size() << " good outs from " << up_index_limit << " unlocked of " << outs_container_size << " total", LOG_LEVEL_0);
}
}
else
{
size_t added = 0;
for (size_t i = 0; i != up_index_limit; i++)
added += add_out_to_get_random_outs(result_outs, amount, i, req.decoys_count, req.use_forced_mix_outs, req.height_upper_limit) ? 1 : 0;
LOG_PRINT_YELLOW("Not enough inputs for amount " << print_money_brief(amount) << ", needed " << req.decoys_count << ", added " << added << " good outs from " << up_index_limit << " unlocked of " << outs_container_size << " total - respond with all good outs", LOG_LEVEL_0);
}
}
return true;
}
//------------------------------------------------------------------
boost::multiprecision::uint128_t blockchain_storage::total_coins() const
{
CRITICAL_REGION_LOCAL(m_read_lock);

View file

@ -281,6 +281,7 @@ namespace currency
bool handle_get_objects(NOTIFY_REQUEST_GET_OBJECTS::request& arg, NOTIFY_RESPONSE_GET_OBJECTS::request& rsp)const;
bool handle_get_objects(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res)const;
bool get_random_outs_for_amounts(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res)const;
bool get_random_outs_for_amounts2(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::response& res)const;
bool get_backward_blocks_sizes(size_t from_height, std::vector<size_t>& sz, size_t count)const;
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;

View file

@ -384,6 +384,17 @@ namespace currency
return true;
}
bool core_rpc_server::on_get_random_outs2(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::response& res, connection_context& cntx)
{
CHECK_CORE_READY();
res.status = API_RETURN_CODE_FAIL;
if (!m_core.get_blockchain_storage().get_random_outs_for_amounts2(req, res))
{
return true;
}
res.status = API_RETURN_CODE_OK;
}
//------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::on_get_indexes(const COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::request& req, COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES::response& res, connection_context& cntx)
{

View file

@ -49,6 +49,7 @@ namespace currency
bool on_start_mining(const COMMAND_RPC_START_MINING::request& req, COMMAND_RPC_START_MINING::response& res, connection_context& cntx);
bool on_stop_mining(const COMMAND_RPC_STOP_MINING::request& req, COMMAND_RPC_STOP_MINING::response& res, connection_context& cntx);
bool on_get_random_outs(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res, connection_context& cntx);
bool on_get_random_outs2(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::response& res, connection_context& cntx);
bool on_get_info(const COMMAND_RPC_GET_INFO::request& req, COMMAND_RPC_GET_INFO::response& res, connection_context& cntx);
bool on_set_maintainers_info(const COMMAND_RPC_SET_MAINTAINERS_INFO::request& req, COMMAND_RPC_SET_MAINTAINERS_INFO::response& res, connection_context& cntx);
bool on_get_tx_pool(const COMMAND_RPC_GET_TX_POOL::request& req, COMMAND_RPC_GET_TX_POOL::response& res, connection_context& cntx);
@ -141,6 +142,7 @@ namespace currency
MAP_JON_RPC ("get_all_pool_tx_list", on_get_all_pool_tx_list, COMMAND_RPC_GET_ALL_POOL_TX_LIST)
MAP_JON_RPC ("get_pool_info", on_get_pool_info, COMMAND_RPC_GET_POOL_INFO)
MAP_JON_RPC ("getrandom_outs", on_get_random_outs, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS)
MAP_JON_RPC ("getrandom_outs2", on_get_random_outs2, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2)
MAP_JON_RPC ("get_votes", on_get_votes, COMMAND_RPC_GET_VOTES)
//assets api
MAP_JON_RPC ("get_asset_info", on_get_asset_info, COMMAND_RPC_GET_ASSET_INFO)

View file

@ -422,6 +422,76 @@ namespace currency
};
};
//-----------------------------------------------
struct COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2
{
struct offsets_distribution
{
uint64_t amount; //if amount is 0 then lookup in post-zarcanum zone only, if not 0 then pre-zarcanum only
std::list<uint64_t> offsets; //[i] = height, estimated location where to pickup output of transaction
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(amount)
KV_SERIALIZE(offsets)
END_KV_SERIALIZE_MAP()
};
struct request
{
std::list<offsets_distribution> amounts;
uint64_t height_upper_limit; // if nonzero, all the decoy outputs must be either older than, or the same age as this height
bool use_forced_mix_outs;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(amounts)
KV_SERIALIZE(decoys_count)
KV_SERIALIZE(height_upper_limit)
KV_SERIALIZE(use_forced_mix_outs)
END_KV_SERIALIZE_MAP()
};
#pragma pack (push, 1)
struct out_entry
{
out_entry() = default;
out_entry(uint64_t global_amount_index, const crypto::public_key& stealth_address)
: global_amount_index(global_amount_index), stealth_address(stealth_address), concealing_point{}, amount_commitment{}, blinded_asset_id{}
{}
out_entry(uint64_t global_amount_index, const crypto::public_key& stealth_address, const crypto::public_key& amount_commitment, const crypto::public_key& concealing_point, const crypto::public_key& blinded_asset_id)
: global_amount_index(global_amount_index), stealth_address(stealth_address), concealing_point(concealing_point), amount_commitment(amount_commitment), blinded_asset_id(blinded_asset_id)
{}
uint64_t global_amount_index;
crypto::public_key stealth_address;
crypto::public_key concealing_point; // premultiplied by 1/8
crypto::public_key amount_commitment; // premultiplied by 1/8
crypto::public_key blinded_asset_id; // premultiplied by 1/8
};
#pragma pack(pop)
struct outs_for_amount
{
uint64_t amount;
std::list<out_entry> outs;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(amount)
KV_SERIALIZE_CONTAINER_POD_AS_BLOB(outs)
END_KV_SERIALIZE_MAP()
};
struct response
{
std::vector<outs_for_amount> outs;
std::string status;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(outs)
KV_SERIALIZE(status)
END_KV_SERIALIZE_MAP()
};
};
//-----------------------------------------------
struct COMMAND_RPC_SET_MAINTAINERS_INFO
{