forked from lthn/blockchain
fixed crash in decoy_selection api
This commit is contained in:
parent
01f00a67e6
commit
997dcb8312
3 changed files with 51 additions and 14 deletions
|
|
@ -2726,11 +2726,12 @@ bool blockchain_storage::get_target_outs_for_amount_prezarcanum(const COMMAND_RP
|
|||
}
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
|
||||
bool blockchain_storage::get_target_outs_for_amount_postzarcanum(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request& req, const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::offsets_distribution& details, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, std::map<uint64_t, uint64_t>& amounts_to_up_index_limit_cache) const
|
||||
bool blockchain_storage::get_target_outs_for_postzarcanum(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request& req, const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::offsets_distribution& details, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, std::map<uint64_t, uint64_t>& amounts_to_up_index_limit_cache) const
|
||||
{
|
||||
std::set<uint64_t> used;
|
||||
for (auto offset : details.offsets)
|
||||
{
|
||||
|
||||
//perfectly we would need to find transaction's output on the given height, with the given probability
|
||||
//of being coinbase(coinbase outputs should be included less in decoy selection algorithm)
|
||||
bool is_coinbase = (crypto::rand<uint64_t>() % 101) > req.coinbase_percents ? false : true;
|
||||
|
|
@ -2749,8 +2750,6 @@ bool blockchain_storage::get_target_outs_for_amount_postzarcanum(const COMMAND_R
|
|||
#define TARGET_RANDOM_OUTS_SELECTIOM_POOL_MIN 10
|
||||
//try to find output around given H
|
||||
std::vector<uint64_t> selected_global_indexes;
|
||||
|
||||
|
||||
auto process_tx = [&](const crypto::hash& tx_id) {
|
||||
|
||||
auto tx_ptr = m_db_transactions.find(tx_id);
|
||||
|
|
@ -2778,6 +2777,11 @@ bool blockchain_storage::get_target_outs_for_amount_postzarcanum(const COMMAND_R
|
|||
continue;
|
||||
}
|
||||
|
||||
if (used.find(tx_ptr->m_global_output_indexes[i]) != used.end())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// add output
|
||||
// note: code that will process selected_global_indes will be revisiting transactions entries to obtain all
|
||||
// needed data, that should work relatively effective because of on-top-of-db cache keep daya unserialized
|
||||
|
|
@ -2788,7 +2792,7 @@ bool blockchain_storage::get_target_outs_for_amount_postzarcanum(const COMMAND_R
|
|||
|
||||
while (selected_global_indexes.size() < TARGET_RANDOM_OUTS_SELECTIOM_POOL_MIN)
|
||||
{
|
||||
auto block_ptr = m_db_blocks.get(estimated_h--);
|
||||
auto block_ptr = m_db_blocks.get(estimated_h);
|
||||
if (is_coinbase && is_pos_block(block_ptr->bl) )
|
||||
{
|
||||
process_tx(get_transaction_hash(block_ptr->bl.miner_tx));
|
||||
|
|
@ -2801,12 +2805,25 @@ bool blockchain_storage::get_target_outs_for_amount_postzarcanum(const COMMAND_R
|
|||
process_tx(tx_id);
|
||||
}
|
||||
}
|
||||
if(estimated_h)
|
||||
estimated_h--;
|
||||
else
|
||||
{
|
||||
//likely unusual situation when blocks enumerated all way back to genesis
|
||||
//let's check if we have at least something
|
||||
if (!selected_global_indexes.size())
|
||||
{
|
||||
//need to regenerate offsets
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//pick up a random output from selected_global_indes
|
||||
uint64_t global_index = selected_global_indexes[crypto::rand<uint64_t>() % selected_global_indexes.size()];
|
||||
bool res = add_out_to_get_random_outs(result_outs, details.amount, global_index, details.offsets.size(), req.use_forced_mix_outs, req.height_upper_limit);
|
||||
CHECK_AND_ASSERT_THROW_MES(res, "Failed to add_out_to_get_random_outs([" << global_index << "]) at postzarcanum era");
|
||||
used.insert(global_index);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -2824,16 +2841,19 @@ bool blockchain_storage::get_random_outs_for_amounts2(const COMMAND_RPC_GET_RAND
|
|||
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;
|
||||
|
||||
bool r = false;
|
||||
if (amount == 0)
|
||||
{
|
||||
//zarcanum era inputs
|
||||
get_target_outs_for_amount_postzarcanum(req, req.amounts[i], result_outs, amounts_to_up_index_limit_cache);
|
||||
r = get_target_outs_for_postzarcanum(req, req.amounts[i], result_outs, amounts_to_up_index_limit_cache);
|
||||
}
|
||||
else
|
||||
{
|
||||
//zarcanum era inputs
|
||||
get_target_outs_for_amount_prezarcanum(req, req.amounts[i], result_outs, amounts_to_up_index_limit_cache);
|
||||
r = get_target_outs_for_amount_prezarcanum(req, req.amounts[i], result_outs, amounts_to_up_index_limit_cache);
|
||||
}
|
||||
if (!r)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -639,7 +639,7 @@ namespace currency
|
|||
bool pop_transaction_from_global_index(const transaction& tx, const crypto::hash& tx_id);
|
||||
bool add_out_to_get_random_outs(COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, uint64_t amount, size_t i, uint64_t mix_count, bool use_only_forced_to_mix = false, uint64_t height_upper_limit = 0) const;
|
||||
bool get_target_outs_for_amount_prezarcanum(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request& req, const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::offsets_distribution& details, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, std::map<uint64_t, uint64_t>& amounts_to_up_index_limit_cache) const;
|
||||
bool get_target_outs_for_amount_postzarcanum(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request& req, const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::offsets_distribution& details, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, std::map<uint64_t, uint64_t>& amounts_to_up_index_limit_cache) const;
|
||||
bool get_target_outs_for_postzarcanum(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request& req, const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::offsets_distribution& details, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, std::map<uint64_t, uint64_t>& amounts_to_up_index_limit_cache) const;
|
||||
bool add_block_as_invalid(const block& bl, const crypto::hash& h);
|
||||
bool add_block_as_invalid(const block_extended_info& bei, const crypto::hash& h);
|
||||
size_t find_end_of_allowed_index(uint64_t amount)const;
|
||||
|
|
|
|||
|
|
@ -5922,12 +5922,29 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count, std::vector<currency
|
|||
}
|
||||
}
|
||||
|
||||
bool r = m_core_proxy->call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2(req, daemon_resp);
|
||||
THROW_IF_FALSE_WALLET_EX(r, error::no_connection_to_daemon, "getrandom_outs2.bin");
|
||||
THROW_IF_FALSE_WALLET_EX(daemon_resp.status != API_RETURN_CODE_BUSY, error::daemon_busy, "getrandom_outs.bin");
|
||||
THROW_IF_FALSE_WALLET_EX(daemon_resp.status == API_RETURN_CODE_OK, error::get_random_outs_error, daemon_resp.status);
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(daemon_resp.outs.size() == selected_indicies.size(),
|
||||
"daemon returned wrong response for getrandom_outs.bin, wrong amounts count = " << daemon_resp.outs.size() << ", expected: " << selected_indicies.size());
|
||||
size_t attempt_count = 0;
|
||||
while (true)
|
||||
{
|
||||
bool r = m_core_proxy->call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2(req, daemon_resp);
|
||||
THROW_IF_FALSE_WALLET_EX(r, error::no_connection_to_daemon, "getrandom_outs2.bin");
|
||||
if(daemon_resp.status == API_RETURN_CODE_FAIL)
|
||||
{
|
||||
if (attempt_count < 10)
|
||||
{
|
||||
attempt_count++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(daemon_resp.outs.size() == selected_indicies.size(),
|
||||
"unable to exacute getrandom_outs.bin after 10 attempts with code API_RETURN_CODE_FAIL, there must be problems with mixins");
|
||||
}
|
||||
}
|
||||
THROW_IF_FALSE_WALLET_EX(daemon_resp.status != API_RETURN_CODE_BUSY, error::daemon_busy, "getrandom_outs.bin");
|
||||
THROW_IF_FALSE_WALLET_EX(daemon_resp.status == API_RETURN_CODE_OK, error::get_random_outs_error, daemon_resp.status);
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(daemon_resp.outs.size() == selected_indicies.size(),
|
||||
"daemon returned wrong response for getrandom_outs.bin, wrong amounts count = " << daemon_resp.outs.size() << ", expected: " << selected_indicies.size());
|
||||
}
|
||||
|
||||
std::vector<COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount> scanty_outs;
|
||||
for(COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& amount_outs : daemon_resp.outs)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue