forked from lthn/blockchain
get_random_outs_for_amounts2 in work
This commit is contained in:
parent
2d44c967ef
commit
5b4a3e3a38
5 changed files with 159 additions and 0 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue