forked from lthn/blockchain
merge from develop
This commit is contained in:
commit
d03f47a9c7
30 changed files with 417 additions and 276 deletions
|
|
@ -2552,7 +2552,7 @@ bool blockchain_storage::add_out_to_get_random_outs(COMMAND_RPC_GET_RANDOM_OUTPU
|
|||
CHECK_AND_ASSERT_MES(tx_ptr->tx.vout.size() > out_ptr->out_no, false, "internal error: in global outs index, transaction out index="
|
||||
<< out_ptr->out_no << " is greater than transaction outputs = " << tx_ptr->tx.vout.size() << ", for tx id = " << out_ptr->tx_id);
|
||||
|
||||
CHECK_AND_ASSERT_MES(amount != 0 || height_upper_limit != 0, false, "height_upper_limit must be nonzero for hidden amounts (amount = 0)");
|
||||
//CHECK_AND_ASSERT_MES(amount != 0 || height_upper_limit != 0, false, "height_upper_limit must be nonzero for hidden amounts (amount = 0)");
|
||||
|
||||
if (height_upper_limit != 0 && tx_ptr->m_keeper_block_height > height_upper_limit)
|
||||
return false;
|
||||
|
|
@ -2610,6 +2610,14 @@ bool blockchain_storage::add_out_to_get_random_outs(COMMAND_RPC_GET_RANDOM_OUTPU
|
|||
oen.amount_commitment = toz.amount_commitment;
|
||||
oen.concealing_point = toz.concealing_point;
|
||||
oen.blinded_asset_id = toz.blinded_asset_id; // TODO @#@# bad design, too much manual coping, consider redesign -- sowle
|
||||
if (is_coinbase(tx_ptr->tx))
|
||||
{
|
||||
oen.flags |= RANDOM_OUTPUTS_FOR_AMOUNTS_FLAGS_COINBASE;
|
||||
if (is_pos_coinbase(tx_ptr->tx))
|
||||
{
|
||||
oen.flags |= RANDOM_OUTPUTS_FOR_AMOUNTS_FLAGS_POS_COINBASE;
|
||||
}
|
||||
}
|
||||
}
|
||||
VARIANT_SWITCH_END();
|
||||
|
||||
|
|
@ -2698,9 +2706,9 @@ bool blockchain_storage::get_random_outs_for_amounts(const COMMAND_RPC_GET_RANDO
|
|||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool blockchain_storage::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 blockchain_storage::get_target_outs_for_amount_prezarcanum(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request& req, const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::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
|
||||
{
|
||||
size_t decoys_count = details.offsets.size();
|
||||
size_t decoys_count = details.global_offsets.size();
|
||||
uint64_t amount = details.amount;
|
||||
|
||||
uint64_t outs_container_size = m_db_outputs.get_item_size(details.amount);
|
||||
|
|
@ -2727,7 +2735,7 @@ bool blockchain_storage::get_target_outs_for_amount_prezarcanum(const COMMAND_RP
|
|||
if (up_index_limit >= decoys_count)
|
||||
{
|
||||
std::set<size_t> used;
|
||||
used.insert(details.own_global_index);
|
||||
//used.insert(details.own_global_index);
|
||||
for (uint64_t j = 0; j != decoys_count || used.size() >= up_index_limit;)
|
||||
{
|
||||
size_t g_index_initial = crypto::rand<size_t>() % up_index_limit;
|
||||
|
|
@ -2770,117 +2778,27 @@ bool blockchain_storage::get_target_outs_for_amount_prezarcanum(const COMMAND_RP
|
|||
}
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
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
|
||||
bool blockchain_storage::get_target_outs_for_postzarcanum(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request& req, const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::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;
|
||||
used.insert(details.own_global_index);
|
||||
for (auto offset : details.offsets)
|
||||
for (auto global_index : details.global_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;
|
||||
|
||||
//TODO: Consider including PoW coinbase to transactions(does it needed?)
|
||||
|
||||
// convert offset to estimated height
|
||||
uint64_t estimated_h = this->get_current_blockchain_size() - 1 - offset;
|
||||
//make sure it's after zc hardfork
|
||||
if (estimated_h < m_core_runtime_config.hard_forks.m_height_the_hardfork_n_active_after[ZANO_HARDFORK_04_ZARCANUM])
|
||||
{
|
||||
LOG_ERROR("Wrong estimated offset(" << offset << "), it hits zone before zarcanum hardfork");
|
||||
return false;
|
||||
}
|
||||
|
||||
#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);
|
||||
CHECK_AND_ASSERT_THROW_MES(tx_ptr, "internal error: tx_id " << tx_id << " around estimated_h = " << estimated_h << " not found in db");
|
||||
//go through tx outputs
|
||||
for (size_t i = 0; i != tx_ptr->tx.vout.size(); i++)
|
||||
{
|
||||
if (tx_ptr->tx.vout[i].type() != typeid(tx_out_zarcanum))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const tx_out_zarcanum& z_out = boost::get<tx_out_zarcanum>(tx_ptr->tx.vout[i]);
|
||||
|
||||
// NOTE: second part of condition (mix_attr >= CURRENCY_TO_KEY_OUT_FORCED_MIX_LOWER_BOUND && ..) might be not accurate
|
||||
// since the wallet might want to request more inputs then it planning to do mixins. For now let's keep it this way and fix
|
||||
// it if we see the problems about it.
|
||||
if (z_out.mix_attr == CURRENCY_TO_KEY_OUT_FORCED_NO_MIX || (z_out.mix_attr >= CURRENCY_TO_KEY_OUT_FORCED_MIX_LOWER_BOUND && z_out.mix_attr < details.offsets.size()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// skip spent outptus
|
||||
if (tx_ptr->m_spent_flags[i])
|
||||
{
|
||||
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
|
||||
selected_global_indexes.push_back(tx_ptr->m_global_output_indexes[i]);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
while (selected_global_indexes.size() < TARGET_RANDOM_OUTS_SELECTIOM_POOL_MIN)
|
||||
{
|
||||
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));
|
||||
}
|
||||
else
|
||||
{
|
||||
//looking for regular output of regular transactions
|
||||
for (auto tx_id : block_ptr->bl.tx_hashes)
|
||||
{
|
||||
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);
|
||||
bool res = add_out_to_get_random_outs(result_outs, details.amount, global_index, this->get_core_runtime_config().hf4_minimum_mixins, false);
|
||||
if (!res)
|
||||
{
|
||||
COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::out_entry& oen = *result_outs.outs.insert(result_outs.outs.end(), COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::out_entry{});
|
||||
oen.flags = RANDOM_OUTPUTS_FOR_AMOUNTS_FLAGS_NOT_ALLOWED;
|
||||
}
|
||||
}
|
||||
CHECK_AND_ASSERT_THROW_MES(details.global_offsets.size() == result_outs.outs.size(), "details.global_offsets.size() == result_outs.outs.size() check failed");
|
||||
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
|
||||
bool blockchain_storage::get_random_outs_for_amounts3(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::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;
|
||||
uint64_t count_zarcanum_blocks = 0;
|
||||
if(is_hardfork_active(ZANO_HARDFORK_04_ZARCANUM))
|
||||
count_zarcanum_blocks = this->get_current_blockchain_size() - m_core_runtime_config.hard_forks.m_height_the_hardfork_n_active_after[ZANO_HARDFORK_04_ZARCANUM];
|
||||
|
||||
|
||||
for (size_t i = 0; i != req.amounts.size(); i++)
|
||||
|
|
@ -2891,7 +2809,7 @@ bool blockchain_storage::get_random_outs_for_amounts2(const COMMAND_RPC_GET_RAND
|
|||
result_outs.amount = amount;
|
||||
|
||||
bool r = false;
|
||||
if (amount == 0 && count_zarcanum_blocks > 20000)
|
||||
if (amount == 0)
|
||||
{
|
||||
//zarcanum era inputs
|
||||
r = get_target_outs_for_postzarcanum(req, req.amounts[i], result_outs, amounts_to_up_index_limit_cache);
|
||||
|
|
@ -3595,7 +3513,7 @@ bool blockchain_storage::get_est_height_from_date(uint64_t date, uint64_t& res_h
|
|||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool blockchain_storage::find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, std::list<std::pair<block, std::list<transaction> > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count, uint64_t minimum_height, bool need_global_indexes)const
|
||||
bool blockchain_storage::find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, std::list<std::pair<block, std::list<transaction> > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count, uint64_t minimum_height)const
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_read_lock);
|
||||
blocks_direct_container blocks_direct;
|
||||
|
|
@ -3614,7 +3532,7 @@ bool blockchain_storage::find_blockchain_supplement(const std::list<crypto::hash
|
|||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool blockchain_storage::find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, blocks_direct_container& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count, uint64_t minimum_height, bool request_coinbase_info)const
|
||||
bool blockchain_storage::find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, blocks_direct_container& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count, uint64_t minimum_height)const
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_read_lock);
|
||||
if (!find_blockchain_supplement(qblock_ids, start_height))
|
||||
|
|
@ -3631,8 +3549,7 @@ bool blockchain_storage::find_blockchain_supplement(const std::list<crypto::hash
|
|||
std::list<crypto::hash> mis;
|
||||
get_transactions_direct(m_db_blocks[i]->bl.tx_hashes, blocks.back().second, mis);
|
||||
CHECK_AND_ASSERT_MES(!mis.size(), false, "internal error, block " << get_block_hash(m_db_blocks[i]->bl) << " [" << i << "] contains missing transactions: " << mis);
|
||||
if(request_coinbase_info)
|
||||
blocks.back().third = m_db_transactions.find(get_transaction_hash(m_db_blocks[i]->bl.miner_tx));
|
||||
blocks.back().third = m_db_transactions.find(get_transaction_hash(m_db_blocks[i]->bl.miner_tx));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -280,13 +280,13 @@ namespace currency
|
|||
bool get_short_chain_history(std::list<crypto::hash>& ids)const;
|
||||
bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp)const;
|
||||
bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, uint64_t& starter_offset)const;
|
||||
bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, std::list<std::pair<block, std::list<transaction> > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count, uint64_t minimum_height = 0, bool need_global_indexes = false)const;
|
||||
bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, blocks_direct_container& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count, uint64_t minimum_height = 0, bool request_coinbase_info = false)const;
|
||||
bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, std::list<std::pair<block, std::list<transaction> > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count, uint64_t minimum_height = 0)const;
|
||||
bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, blocks_direct_container& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count, uint64_t minimum_height = 0)const;
|
||||
//bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, std::list<std::pair<block, std::list<transaction> > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count)const;
|
||||
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_random_outs_for_amounts3(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::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;
|
||||
|
|
@ -643,8 +643,8 @@ namespace currency
|
|||
bool push_transaction_to_global_outs_index(const transaction& tx, const crypto::hash& tx_id, std::vector<uint64_t>& global_indexes);
|
||||
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_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_amount_prezarcanum(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request& req, const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::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_AMOUNTS3::request& req, const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::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;
|
||||
|
|
|
|||
|
|
@ -249,8 +249,9 @@
|
|||
#define BC_OFFERS_CURRENT_OFFERS_SERVICE_ARCHIVE_VER CURRENCY_FORMATION_VERSION + BLOCKCHAIN_STORAGE_MAJOR_COMPATIBILITY_VERSION + 9
|
||||
#define BC_OFFERS_CURRENCY_MARKET_FILENAME "market.bin"
|
||||
|
||||
#define WALLET_FILE_SERIALIZATION_VERSION 163
|
||||
#define WALLET_FILE_LAST_SUPPORTED_VERSION 163
|
||||
|
||||
#define WALLET_FILE_SERIALIZATION_VERSION 165
|
||||
#define WALLET_FILE_LAST_SUPPORTED_VERSION 165
|
||||
|
||||
#define CURRENT_MEMPOOL_ARCHIVE_VER (CURRENCY_FORMATION_VERSION+31)
|
||||
|
||||
|
|
|
|||
|
|
@ -289,7 +289,7 @@ namespace currency
|
|||
}
|
||||
|
||||
blockchain_storage::blocks_direct_container bs;
|
||||
if(!m_core.get_blockchain_storage().find_blockchain_supplement(req.block_ids, bs, res.current_height, res.start_height, COMMAND_RPC_GET_BLOCKS_FAST_MAX_COUNT, req.minimum_height, req.need_global_indexes))
|
||||
if(!m_core.get_blockchain_storage().find_blockchain_supplement(req.block_ids, bs, res.current_height, res.start_height, COMMAND_RPC_GET_BLOCKS_FAST_MAX_COUNT, req.minimum_height))
|
||||
{
|
||||
res.status = API_RETURN_CODE_FAIL;
|
||||
return false;
|
||||
|
|
@ -326,7 +326,7 @@ namespace currency
|
|||
}
|
||||
|
||||
blockchain_storage::blocks_direct_container bs;
|
||||
if (!m_core.get_blockchain_storage().find_blockchain_supplement(req.block_ids, bs, res.current_height, res.start_height, COMMAND_RPC_GET_BLOCKS_FAST_MAX_COUNT, req.minimum_height, req.need_global_indexes))
|
||||
if (!m_core.get_blockchain_storage().find_blockchain_supplement(req.block_ids, bs, res.current_height, res.start_height, COMMAND_RPC_GET_BLOCKS_FAST_MAX_COUNT, req.minimum_height))
|
||||
{
|
||||
res.status = API_RETURN_CODE_FAIL;
|
||||
return false;
|
||||
|
|
@ -336,21 +336,15 @@ namespace currency
|
|||
{
|
||||
res.blocks.resize(res.blocks.size()+1);
|
||||
res.blocks.back().block = block_to_blob(b.first->bl);
|
||||
if (req.need_global_indexes)
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(b.third.get(), false, "Internal error on handling COMMAND_RPC_GET_BLOCKS_FAST: b.third is empty, ie coinbase info is not prepared");
|
||||
res.blocks.back().coinbase_global_outs = b.third->m_global_output_indexes;
|
||||
res.blocks.back().tx_global_outs.resize(b.second.size());
|
||||
}
|
||||
CHECK_AND_ASSERT_MES(b.third.get(), false, "Internal error on handling COMMAND_RPC_GET_BLOCKS_FAST: b.third is empty, ie coinbase info is not prepared");
|
||||
res.blocks.back().coinbase_global_outs = b.third->m_global_output_indexes;
|
||||
res.blocks.back().tx_global_outs.resize(b.second.size());
|
||||
size_t i = 0;
|
||||
|
||||
BOOST_FOREACH(auto& t, b.second)
|
||||
{
|
||||
res.blocks.back().txs.push_back(tx_to_blob(t->tx));
|
||||
if (req.need_global_indexes)
|
||||
{
|
||||
res.blocks.back().tx_global_outs[i].v = t->m_global_output_indexes;
|
||||
}
|
||||
res.blocks.back().tx_global_outs[i].v = t->m_global_output_indexes;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
|
@ -424,11 +418,11 @@ 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)
|
||||
bool core_rpc_server::on_get_random_outs3(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::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))
|
||||
if (!m_core.get_blockchain_storage().get_random_outs_for_amounts3(req, res))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ namespace currency
|
|||
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_LEGACY::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_LEGACY::response& res, connection_context& cntx);
|
||||
bool on_get_random_outs1(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_random_outs3(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::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);
|
||||
|
|
@ -112,7 +112,7 @@ namespace currency
|
|||
MAP_URI_AUTO_BIN2("/get_o_indexes.bin", on_get_indexes, COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES)
|
||||
MAP_URI_AUTO_BIN2("/getrandom_outs.bin", on_get_random_outs, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS_LEGACY)
|
||||
MAP_URI_AUTO_BIN2("/getrandom_outs1.bin", on_get_random_outs1, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS)
|
||||
MAP_URI_AUTO_BIN2("/getrandom_outs2.bin", on_get_random_outs2, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2)
|
||||
MAP_URI_AUTO_BIN2("/getrandom_outs3.bin", on_get_random_outs3, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3)
|
||||
MAP_URI_AUTO_BIN2("/set_maintainers_info.bin", on_set_maintainers_info, COMMAND_RPC_SET_MAINTAINERS_INFO)
|
||||
MAP_URI_AUTO_BIN2("/get_tx_pool.bin", on_get_tx_pool, COMMAND_RPC_GET_TX_POOL)
|
||||
MAP_URI_AUTO_BIN2("/check_keyimages.bin", on_check_keyimages, COMMAND_RPC_CHECK_KEYIMAGES)
|
||||
|
|
@ -146,7 +146,7 @@ namespace currency
|
|||
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_LEGACY)
|
||||
MAP_JON_RPC ("getrandom_outs1", on_get_random_outs1, 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 ("getrandom_outs3", on_get_random_outs3, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3)
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -162,12 +162,10 @@ namespace currency
|
|||
|
||||
struct request
|
||||
{
|
||||
bool need_global_indexes;
|
||||
uint64_t minimum_height;
|
||||
std::list<crypto::hash> block_ids; //*first 10 blocks id goes sequential, next goes in pow(2,n) offset, like 2, 4, 8, 16, 32, 64 and so on, and the last one is always genesis block */
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(need_global_indexes)
|
||||
KV_SERIALIZE(minimum_height)
|
||||
KV_SERIALIZE_CONTAINER_POD_AS_BLOB(block_ids)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
|
|
@ -383,6 +381,11 @@ namespace currency
|
|||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
|
||||
#define RANDOM_OUTPUTS_FOR_AMOUNTS_FLAGS_COINBASE 0x0000000000000001LL
|
||||
#define RANDOM_OUTPUTS_FOR_AMOUNTS_FLAGS_NOT_ALLOWED 0x0000000000000002LL
|
||||
#define RANDOM_OUTPUTS_FOR_AMOUNTS_FLAGS_POS_COINBASE 0x0000000000000004LL
|
||||
|
||||
#pragma pack (push, 1)
|
||||
struct out_entry
|
||||
{
|
||||
|
|
@ -398,12 +401,13 @@ namespace currency
|
|||
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
|
||||
uint64_t flags;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
struct outs_for_amount
|
||||
{
|
||||
uint64_t amount;
|
||||
uint64_t amount = 0;
|
||||
std::list<out_entry> outs;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
|
|
@ -423,18 +427,16 @@ namespace currency
|
|||
};
|
||||
};
|
||||
//-----------------------------------------------
|
||||
struct COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2
|
||||
struct COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3
|
||||
{
|
||||
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::vector<uint64_t> offsets; //[i] = height, estimated location where to pickup output of transaction
|
||||
uint64_t own_global_index; //index to exclude from selection
|
||||
std::vector<uint64_t> global_offsets; //[i] = global_index to pick up
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(amount)
|
||||
KV_SERIALIZE(offsets)
|
||||
KV_SERIALIZE(own_global_index)
|
||||
KV_SERIALIZE(global_offsets)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,6 @@
|
|||
#define PROJECT_REVISION "0"
|
||||
#define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION
|
||||
|
||||
#define PROJECT_VERSION_BUILD_NO 282
|
||||
#define PROJECT_VERSION_BUILD_NO 286
|
||||
#define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO)
|
||||
#define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]"
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ namespace tools
|
|||
currency::COMMAND_RPC_GET_BLOCKS_FAST::request req;
|
||||
req.block_ids = rqt.block_ids;
|
||||
req.minimum_height = rqt.minimum_height;
|
||||
req.need_global_indexes = rqt.need_global_indexes;
|
||||
currency::COMMAND_RPC_GET_BLOCKS_FAST::response res = AUTO_VAL_INIT(res);
|
||||
bool r = call_COMMAND_RPC_GET_BLOCKS_FAST(req, res);
|
||||
rsp.status = res.status;
|
||||
|
|
@ -98,9 +97,9 @@ namespace tools
|
|||
return invoke_http_bin_remote_command2_update_is_disconnect("/getrandom_outs1.bin", req, res);
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool default_http_core_proxy::call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2(const currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request& req, currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::response& res)
|
||||
bool default_http_core_proxy::call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3(const currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request& req, currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::response& res)
|
||||
{
|
||||
return invoke_http_bin_remote_command2_update_is_disconnect("/getrandom_outs2.bin", req, res);
|
||||
return invoke_http_bin_remote_command2_update_is_disconnect("/getrandom_outs3.bin", req, res);
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool default_http_core_proxy::call_COMMAND_RPC_SEND_RAW_TX(const currency::COMMAND_RPC_SEND_RAW_TX::request& req, currency::COMMAND_RPC_SEND_RAW_TX::response& res)
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ namespace tools
|
|||
bool call_COMMAND_RPC_GET_TX_POOL(const currency::COMMAND_RPC_GET_TX_POOL::request& rqt, currency::COMMAND_RPC_GET_TX_POOL::response& rsp) override;
|
||||
bool call_COMMAND_RPC_GET_ALIASES_BY_ADDRESS(const currency::COMMAND_RPC_GET_ALIASES_BY_ADDRESS::request& rqt, currency::COMMAND_RPC_GET_ALIASES_BY_ADDRESS::response& rsp) override;
|
||||
bool call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS(const currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& rqt, currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& rsp) override;
|
||||
bool call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2(const currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request& rqt, currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::response& rsp) override;
|
||||
bool call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3(const currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request& rqt, currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::response& rsp) override;
|
||||
bool call_COMMAND_RPC_SEND_RAW_TX(const currency::COMMAND_RPC_SEND_RAW_TX::request& rqt, currency::COMMAND_RPC_SEND_RAW_TX::response& rsp) override;
|
||||
bool call_COMMAND_RPC_FORCE_RELAY_RAW_TXS(const currency::COMMAND_RPC_FORCE_RELAY_RAW_TXS::request& rqt, currency::COMMAND_RPC_FORCE_RELAY_RAW_TXS::response& rsp) override;
|
||||
bool call_COMMAND_RPC_GET_ALL_ALIASES(currency::COMMAND_RPC_GET_ALL_ALIASES::response& rsp) override;
|
||||
|
|
|
|||
|
|
@ -58,9 +58,9 @@ namespace tools
|
|||
return m_rpc.on_get_random_outs1(req, res, m_cntxt_stub);
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2(const currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request& req, currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::response& res) override
|
||||
bool call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3(const currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request& req, currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::response& res) override
|
||||
{
|
||||
return m_rpc.on_get_random_outs2(req, res, m_cntxt_stub);
|
||||
return m_rpc.on_get_random_outs3(req, res, m_cntxt_stub);
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool call_COMMAND_RPC_SEND_RAW_TX(const currency::COMMAND_RPC_SEND_RAW_TX::request& req, currency::COMMAND_RPC_SEND_RAW_TX::response& res) override
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ namespace tools
|
|||
virtual bool call_COMMAND_RPC_GET_TX_POOL(const currency::COMMAND_RPC_GET_TX_POOL::request& rqt, currency::COMMAND_RPC_GET_TX_POOL::response& rsp){ return false; }
|
||||
virtual bool call_COMMAND_RPC_GET_ALIASES_BY_ADDRESS(const currency::COMMAND_RPC_GET_ALIASES_BY_ADDRESS::request& rqt, currency::COMMAND_RPC_GET_ALIASES_BY_ADDRESS::response& rsp){ return false; }
|
||||
virtual bool call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS(const currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& rqt, currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& rsp){ return false; }
|
||||
virtual bool call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2(const currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request& rqt, currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::response& rsp) { return false; }
|
||||
virtual bool call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3(const currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request& rqt, currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::response& rsp) { return false; }
|
||||
virtual bool call_COMMAND_RPC_SEND_RAW_TX(const currency::COMMAND_RPC_SEND_RAW_TX::request& rqt, currency::COMMAND_RPC_SEND_RAW_TX::response& rsp){ return false; }
|
||||
virtual bool call_COMMAND_RPC_FORCE_RELAY_RAW_TXS(const currency::COMMAND_RPC_FORCE_RELAY_RAW_TXS::request& rqt, currency::COMMAND_RPC_FORCE_RELAY_RAW_TXS::response& rsp){ return false; }
|
||||
virtual bool call_COMMAND_RPC_GET_ALL_ALIASES(currency::COMMAND_RPC_GET_ALL_ALIASES::response& rsp){ return false; }
|
||||
|
|
|
|||
|
|
@ -24,9 +24,10 @@ uint64_t scaler::scale(uint64_t h)
|
|||
|
||||
void decoy_selection_generator::init(uint64_t max_h)
|
||||
{
|
||||
|
||||
load_distribution(g_default_distribution, max_h);
|
||||
m_is_initialized = true;
|
||||
|
||||
m_max = max_h; // distribution INCLUDE m_max, count = m_max + 1
|
||||
}
|
||||
bool decoy_selection_generator::load_distribution_from_file(const char* path)
|
||||
{
|
||||
|
|
@ -66,6 +67,60 @@ std::vector<uint64_t> decoy_selection_generator::generate_distribution(uint64_t
|
|||
return res;
|
||||
}
|
||||
|
||||
|
||||
std::vector<uint64_t> decoy_selection_generator::generate_unique_reversed_distribution(uint64_t count)
|
||||
{
|
||||
std::set<uint64_t> set_to_extend;
|
||||
generate_unique_reversed_distribution(count, set_to_extend);
|
||||
return std::vector<uint64_t>(set_to_extend.begin(), set_to_extend.end());
|
||||
}
|
||||
|
||||
std::vector<uint64_t> decoy_selection_generator::generate_unique_reversed_distribution(uint64_t count, uint64_t preincluded_item)
|
||||
{
|
||||
std::set<uint64_t> set_to_extend;
|
||||
set_to_extend.insert(preincluded_item);
|
||||
generate_unique_reversed_distribution(count, set_to_extend);
|
||||
return std::vector<uint64_t>(set_to_extend.begin(), set_to_extend.end());
|
||||
}
|
||||
|
||||
#define DECOY_SELECTION_GENERATOR_MAX_ITERATIONS 1000000
|
||||
|
||||
void decoy_selection_generator::generate_unique_reversed_distribution(uint64_t count, std::set<uint64_t>& set_to_extend)
|
||||
{
|
||||
if (count + set_to_extend.size() > m_max)
|
||||
{
|
||||
throw std::runtime_error("generate_distribution_set with unexpected count");
|
||||
}
|
||||
|
||||
size_t attempt_count = 0;
|
||||
while (set_to_extend.size() != count)
|
||||
{
|
||||
attempt_count++;
|
||||
if (attempt_count > DECOY_SELECTION_GENERATOR_MAX_ITERATIONS)
|
||||
{
|
||||
throw std::runtime_error("generate_distribution_set: attempt_count hit DECOY_SELECTION_GENERATOR_MAX_ITERATIONS");
|
||||
}
|
||||
|
||||
uint64_t r = 0;
|
||||
crypto::generate_random_bytes(sizeof(r), &r);
|
||||
double r_ = map_uint_to_double(r);
|
||||
auto it = m_distribution_mapping.upper_bound(r_);
|
||||
if (it == m_distribution_mapping.end())
|
||||
{
|
||||
throw(std::runtime_error(std::string("_r not found in m_distribution_mapping: ") + std::to_string(r_)));
|
||||
}
|
||||
uint64_t h = it->second;
|
||||
if (it != m_distribution_mapping.begin())
|
||||
{
|
||||
uint64_t h_0 = (--it)->second;
|
||||
crypto::generate_random_bytes(sizeof(r), &r);
|
||||
h = h_0 + r % (h - h_0) + 1;
|
||||
}
|
||||
//scale from nominal to max_h
|
||||
set_to_extend.insert(m_max - h);
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t get_distance(const std::vector<decoy_selection_generator::distribution_entry> entries, size_t i)
|
||||
{
|
||||
if (i == 0)
|
||||
|
|
@ -79,7 +134,8 @@ bool decoy_selection_generator::load_distribution(const std::vector<decoy_select
|
|||
//do prescale of distribution
|
||||
std::vector<decoy_selection_generator::distribution_entry> derived_distribution;
|
||||
scaler scl;
|
||||
scl.config_scale(original_distribution.back().h, max_h);
|
||||
uint64_t adjustment_value = original_distribution[0].h;
|
||||
scl.config_scale(original_distribution.back().h - adjustment_value, max_h);
|
||||
|
||||
uint64_t last_scaled_h = 0;
|
||||
std::list<double> last_scaled_array;
|
||||
|
|
@ -87,7 +143,7 @@ bool decoy_selection_generator::load_distribution(const std::vector<decoy_select
|
|||
|
||||
for (size_t i = 0; i <= original_distribution.size(); i++)
|
||||
{
|
||||
if (i == original_distribution.size() || (scl.scale(original_distribution[i].h) != last_scaled_h && last_scaled_array.size()))
|
||||
if (i == original_distribution.size() || (scl.scale(original_distribution[i].h - adjustment_value) != last_scaled_h && last_scaled_array.size()))
|
||||
{
|
||||
//put avg to data_scaled
|
||||
double summ = 0;
|
||||
|
|
@ -96,7 +152,7 @@ bool decoy_selection_generator::load_distribution(const std::vector<decoy_select
|
|||
summ += item;
|
||||
}
|
||||
double avg = summ / last_scaled_array.size();
|
||||
uint64_t prev_h = scl.scale(original_distribution[i - 1].h);
|
||||
uint64_t prev_h = scl.scale(original_distribution[i - 1].h - adjustment_value);
|
||||
derived_distribution.push_back(decoy_selection_generator::distribution_entry{ prev_h, avg});
|
||||
last_scaled_array.clear();
|
||||
}
|
||||
|
|
@ -105,7 +161,7 @@ bool decoy_selection_generator::load_distribution(const std::vector<decoy_select
|
|||
break;
|
||||
}
|
||||
last_scaled_array.push_back(original_distribution[i].v);
|
||||
last_scaled_h = scl.scale(original_distribution[i].h);
|
||||
last_scaled_h = scl.scale(original_distribution[i].h - adjustment_value);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -44,10 +44,14 @@ public:
|
|||
void init(uint64_t max_h);
|
||||
bool load_distribution_from_file(const char* path);
|
||||
std::vector<uint64_t> generate_distribution(uint64_t count);
|
||||
std::vector<uint64_t> generate_unique_reversed_distribution(uint64_t count, uint64_t preincluded_item);
|
||||
std::vector<uint64_t> generate_unique_reversed_distribution(uint64_t count);
|
||||
void generate_unique_reversed_distribution(uint64_t count, std::set<uint64_t>& set_to_extend);
|
||||
bool is_initialized() { return m_is_initialized; }
|
||||
|
||||
private:
|
||||
bool load_distribution(const std::vector<decoy_selection_generator::distribution_entry>& entries, uint64_t max_h);
|
||||
bool m_is_initialized = false;
|
||||
uint64_t m_max = 0;
|
||||
std::map<double, uint64_t> m_distribution_mapping;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -62,6 +62,10 @@ using namespace currency;
|
|||
|
||||
#define WALLET_TX_MAX_ALLOWED_FEE (COIN * 100)
|
||||
|
||||
#define WALLET_FETCH_RANDOM_OUTS_SIZE 200
|
||||
|
||||
|
||||
|
||||
#undef LOG_DEFAULT_CHANNEL
|
||||
#define LOG_DEFAULT_CHANNEL "wallet"
|
||||
ENABLE_CHANNEL_BY_DEFAULT("wallet")
|
||||
|
|
@ -77,9 +81,10 @@ namespace tools
|
|||
, m_log_prefix("???")
|
||||
, m_watch_only(false)
|
||||
, m_required_decoys_count(CURRENCY_DEFAULT_DECOY_SET_SIZE)
|
||||
, m_max_allowed_output_amount_for_defragmentation_tx(CURRENCY_BLOCK_REWARD)
|
||||
, m_min_utxo_count_for_defragmentation_tx(WALLET_MIN_UTXO_COUNT_FOR_DEFRAGMENTATION_TX)
|
||||
, m_max_utxo_count_for_defragmentation_tx(WALLET_MAX_UTXO_COUNT_FOR_DEFRAGMENTATION_TX)
|
||||
, m_decoys_count_for_defragmentation_tx(WALLET_DEFAULT_DECOYS_COUNT_FOR_DEFRAGMENTATION_TX)
|
||||
, m_decoys_count_for_defragmentation_tx(SIZE_MAX)
|
||||
, m_use_deffered_global_outputs(false)
|
||||
#ifdef DISABLE_TOR
|
||||
, m_disable_tor_relay(true)
|
||||
|
|
@ -504,8 +509,18 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t
|
|||
//PoW block don't have change, so all outs supposed to be marked as "mined"
|
||||
ptc.is_derived_from_coinbase = !ptc.is_pos_coinbase;
|
||||
ptc.height = height;
|
||||
|
||||
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(pglobal_indexes, "pglobal_indexes not set");
|
||||
if (this->is_in_hardfork_zone(ZANO_HARDFORK_04_ZARCANUM))
|
||||
{
|
||||
if (pglobal_indexes->size())
|
||||
{
|
||||
//store global index that is under coinage, so we can used in decoy selection algo
|
||||
if (ptc.height < m_last_known_daemon_height && m_last_known_daemon_height - ptc.height > WALLET_DEFAULT_TX_SPENDABLE_AGE)
|
||||
{
|
||||
m_last_zc_global_index = pglobal_indexes->back();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(auto& in : tx.vin)
|
||||
{
|
||||
|
|
@ -1897,8 +1912,6 @@ void wallet2::pull_blocks(size_t& blocks_added, std::atomic<bool>& stop)
|
|||
currency::COMMAND_RPC_GET_BLOCKS_DIRECT::response res = AUTO_VAL_INIT(res);
|
||||
|
||||
req.minimum_height = get_wallet_minimum_height();
|
||||
if (is_auditable())
|
||||
req.need_global_indexes = true;
|
||||
if (req.minimum_height > m_height_of_start_sync)
|
||||
m_height_of_start_sync = req.minimum_height;
|
||||
|
||||
|
|
@ -1951,12 +1964,14 @@ void wallet2::handle_pulled_blocks(size_t& blocks_added, std::atomic<bool>& stop
|
|||
currency::COMMAND_RPC_GET_BLOCKS_DIRECT::response& res)
|
||||
{
|
||||
size_t current_index = res.start_height;
|
||||
m_last_known_daemon_height = res.current_height;
|
||||
bool been_matched_block = false;
|
||||
if (res.start_height == 0 && get_blockchain_current_size() == 1 && !res.blocks.empty())
|
||||
{
|
||||
const currency::block& genesis = res.blocks.front().block_ptr->bl;
|
||||
THROW_IF_TRUE_WALLET_EX(get_block_height(genesis) != 0, error::wallet_internal_error, "first block expected to be genesis");
|
||||
process_genesis_if_needed(genesis);
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(res.blocks.front().coinbase_ptr, "Unexpected empty coinbase");
|
||||
process_genesis_if_needed(genesis, &(res.blocks.front().coinbase_ptr->m_global_output_indexes));
|
||||
res.blocks.pop_front();
|
||||
++current_index;
|
||||
been_matched_block = true;
|
||||
|
|
@ -2479,20 +2494,37 @@ void wallet2::scan_tx_pool(bool& has_related_alias_in_unconfirmed)
|
|||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::on_idle()
|
||||
{
|
||||
scan_unconfirmed_outdate_tx();
|
||||
scan_not_compliant_unconfirmed_txs();
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::scan_unconfirmed_outdate_tx()
|
||||
bool wallet2::scan_not_compliant_unconfirmed_txs()
|
||||
{
|
||||
uint64_t tx_expiration_ts_median = get_tx_expiration_median();
|
||||
uint64_t time_limit = m_core_runtime_config.get_core_time() - CURRENCY_MEMPOOL_TX_LIVETIME;
|
||||
for (auto it = m_unconfirmed_txs.begin(); it != m_unconfirmed_txs.end(); )
|
||||
{
|
||||
bool tx_outdated = it->second.timestamp < time_limit;
|
||||
if (tx_outdated || is_tx_expired(it->second.tx, tx_expiration_ts_median))
|
||||
bool remove_this_tx = false;
|
||||
std::stringstream reason_ss;
|
||||
if (it->second.timestamp < time_limit)
|
||||
{
|
||||
WLT_LOG_BLUE("removing unconfirmed tx " << it->second.tx_hash << ", reason: " << (tx_outdated ? "outdated" : "expired") << ", tx_expiration_ts_median=" << tx_expiration_ts_median, LOG_LEVEL_0);
|
||||
remove_this_tx = true;
|
||||
reason_ss << "outdated, ";
|
||||
}
|
||||
if (is_tx_expired(it->second.tx, tx_expiration_ts_median))
|
||||
{
|
||||
remove_this_tx = true;
|
||||
reason_ss << "expired, ";
|
||||
}
|
||||
if (is_in_hardfork_zone(ZANO_HARDFORK_04_ZARCANUM) && it->second.tx.version < TRANSACTION_VERSION_POST_HF4)
|
||||
{
|
||||
remove_this_tx = true;
|
||||
reason_ss << "not compliant with HF4, ";
|
||||
}
|
||||
|
||||
if (remove_this_tx)
|
||||
{
|
||||
WLT_LOG_BLUE("removing unconfirmed tx " << it->second.tx_hash << ", reason: " << reason_ss.str() << "tx_expiration_ts_median=" << tx_expiration_ts_median, LOG_LEVEL_0);
|
||||
//lookup all used transfer and update flags
|
||||
for (auto i : it->second.selected_indicies)
|
||||
{
|
||||
|
|
@ -2504,15 +2536,18 @@ bool wallet2::scan_unconfirmed_outdate_tx()
|
|||
if (!m_transfers[i].m_spent_height)
|
||||
{
|
||||
uint32_t flags_before = m_transfers[i].m_flags;
|
||||
m_transfers[i].m_flags &= ~(WALLET_TRANSFER_DETAIL_FLAG_SPENT);
|
||||
m_transfers[i].m_flags &= ~(WALLET_TRANSFER_DETAIL_FLAG_SPENT); // TODO: consider removing other blocking flags (e.g. for escrow tx) -- sowle
|
||||
WLT_LOG_BLUE("mark transfer #" << i << " as unspent, flags: " << flags_before << " -> " << m_transfers[i].m_flags << ", reason: removing unconfirmed tx " << it->second.tx_hash, LOG_LEVEL_0);
|
||||
}
|
||||
}
|
||||
//fire some event
|
||||
m_wcallback->on_transfer_canceled(it->second);
|
||||
m_unconfirmed_txs.erase(it++);
|
||||
}else
|
||||
}
|
||||
else
|
||||
{
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
//scan marked as spent but don't have height (unconfirmed, and actually not unconfirmed)
|
||||
|
|
@ -2522,16 +2557,11 @@ bool wallet2::scan_unconfirmed_outdate_tx()
|
|||
if (!it->second.has_outgoing_entries())
|
||||
continue;
|
||||
|
||||
for (auto& in : it->second.tx.vin)
|
||||
for (auto& in_v : it->second.tx.vin)
|
||||
{
|
||||
if (in.type() == typeid(txin_to_key))
|
||||
{
|
||||
ki_in_unconfirmed.insert(boost::get<txin_to_key>(in).k_image);
|
||||
}
|
||||
else if (in.type() == typeid(txin_zc_input))
|
||||
{
|
||||
ki_in_unconfirmed.insert(boost::get<txin_zc_input>(in).k_image);
|
||||
}
|
||||
crypto::key_image ki{};
|
||||
if (get_key_image_from_txin_v(in_v, ki))
|
||||
ki_in_unconfirmed.insert(ki);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4760,6 +4790,7 @@ void wallet2::get_unconfirmed_transfers(std::vector<wallet_public::wallet_transf
|
|||
continue;
|
||||
}
|
||||
trs.push_back(u.second);
|
||||
load_wallet_transfer_info_flags(trs.back());
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
|
|
@ -5973,10 +6004,11 @@ bool wallet2::prepare_tx_sources_for_defragmentation_tx(std::vector<currency::tx
|
|||
for (size_t i = 0, size = m_transfers.size(); i < size && selected_indicies.size() < m_max_utxo_count_for_defragmentation_tx; ++i)
|
||||
{
|
||||
const auto& td = m_transfers[i];
|
||||
if (!td.is_native_coin() || td.m_amount > CURRENCY_BLOCK_REWARD)
|
||||
if (!td.is_native_coin() || td.m_amount > m_max_allowed_output_amount_for_defragmentation_tx)
|
||||
continue;
|
||||
|
||||
if (is_transfer_ready_to_go(td, m_decoys_count_for_defragmentation_tx))
|
||||
uint64_t fake_outs_count_for_td = m_decoys_count_for_defragmentation_tx == SIZE_MAX ? (td.is_zc() ? m_core_runtime_config.hf4_minimum_mixins : CURRENCY_DEFAULT_DECOY_SET_SIZE) : m_decoys_count_for_defragmentation_tx;
|
||||
if (is_transfer_ready_to_go(td, fake_outs_count_for_td))
|
||||
{
|
||||
found_money += td.m_amount;
|
||||
selected_indicies.push_back(i);
|
||||
|
|
@ -5985,7 +6017,7 @@ bool wallet2::prepare_tx_sources_for_defragmentation_tx(std::vector<currency::tx
|
|||
}
|
||||
}
|
||||
|
||||
if (selected_indicies.size() < m_min_utxo_count_for_defragmentation_tx)
|
||||
if (selected_indicies.size() < m_min_utxo_count_for_defragmentation_tx || found_money <= TX_MINIMUM_FEE)
|
||||
{
|
||||
// too few outputs were found, hence don't create a defragmentation tx
|
||||
selected_indicies.clear();
|
||||
|
|
@ -5995,7 +6027,7 @@ bool wallet2::prepare_tx_sources_for_defragmentation_tx(std::vector<currency::tx
|
|||
|
||||
WLT_LOG(ss.str(), LOG_LEVEL_2);
|
||||
|
||||
return prepare_tx_sources(m_decoys_count_for_defragmentation_tx, sources, selected_indicies);
|
||||
return prepare_tx_sources(m_decoys_count_for_defragmentation_tx == SIZE_MAX ? CURRENCY_DEFAULT_DECOY_SET_SIZE : m_decoys_count_for_defragmentation_tx, sources, selected_indicies);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::prepare_tx_sources(assets_selection_context& needed_money_map, size_t fake_outputs_count, uint64_t dust_threshold, std::vector<currency::tx_source_entry>& sources, std::vector<uint64_t>& selected_indicies)
|
||||
|
|
@ -6008,17 +6040,18 @@ bool wallet2::prepare_tx_sources(assets_selection_context& needed_money_map, siz
|
|||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::prefetch_global_indicies_if_needed(const std::vector<uint64_t>& selected_indicies)
|
||||
{
|
||||
std::list<std::reference_wrapper<const currency::transaction>> txs;
|
||||
std::list<uint64_t> indices_that_requested_global_indicies;
|
||||
//std::list<std::reference_wrapper<const currency::transaction>> txs;
|
||||
//std::list<uint64_t> indices_that_requested_global_indicies;
|
||||
for (uint64_t i : selected_indicies)
|
||||
{
|
||||
if (m_transfers[i].m_global_output_index == WALLET_GLOBAL_OUTPUT_INDEX_UNDEFINED)
|
||||
{
|
||||
indices_that_requested_global_indicies.push_back(i);
|
||||
txs.push_back(m_transfers[i].m_ptx_wallet_info->m_tx);
|
||||
}
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(m_transfers[i].m_global_output_index != WALLET_GLOBAL_OUTPUT_INDEX_UNDEFINED,
|
||||
"m_transfers[" << i << "].m_global_output_index is WALLET_GLOBAL_OUTPUT_INDEX_UNDEFINED");
|
||||
//indices_that_requested_global_indicies.push_back(i);
|
||||
//txs.push_back(m_transfers[i].m_ptx_wallet_info->m_tx);
|
||||
//}
|
||||
}
|
||||
|
||||
/*
|
||||
std::vector<std::vector<uint64_t> > outputs_for_all_txs;
|
||||
fetch_tx_global_indixes(txs, outputs_for_all_txs);
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(txs.size() == outputs_for_all_txs.size(), "missmatch sizes txs.size() == outputs_for_all_txs.size()");
|
||||
|
|
@ -6029,7 +6062,7 @@ void wallet2::prefetch_global_indicies_if_needed(const std::vector<uint64_t>& se
|
|||
transfer_details& td = m_transfers[*it_indices];
|
||||
td.m_global_output_index = (*it_ooutputs)[td.m_internal_output_index];
|
||||
it_ooutputs++; it_indices++;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::prepare_tx_sources(size_t fake_outputs_count_, std::vector<currency::tx_source_entry>& sources, const std::vector<uint64_t>& selected_indicies)
|
||||
|
|
@ -6049,26 +6082,26 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count_, std::vector<currenc
|
|||
if (current_size - 1 >= zarcanum_start_from)
|
||||
{
|
||||
//in Zarcanum era
|
||||
const uint64_t test_scale_size = current_size - 1 - zarcanum_start_from;
|
||||
zarcanum_decoy_set_generator.init(test_scale_size - 1);
|
||||
//const uint64_t test_scale_size = current_size - 1 - zarcanum_start_from;
|
||||
zarcanum_decoy_set_generator.init(m_last_zc_global_index);
|
||||
}
|
||||
|
||||
bool need_to_request = fake_outputs_count != 0;
|
||||
COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::request req = AUTO_VAL_INIT(req);
|
||||
COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::request req = AUTO_VAL_INIT(req);
|
||||
req.height_upper_limit = m_last_pow_block_h; // request decoys to be either older than, or the same age as stake output's height
|
||||
req.use_forced_mix_outs = false; // TODO: add this feature to UI later
|
||||
//req.decoys_count = fake_outputs_count + 1; // one more to be able to skip a decoy in case it hits the real output
|
||||
for (uint64_t i: selected_indicies)
|
||||
{
|
||||
req.amounts.push_back(COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::offsets_distribution());
|
||||
COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS2::offsets_distribution& rdisttib = req.amounts.back();
|
||||
req.amounts.push_back(COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::offsets_distribution());
|
||||
COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3::offsets_distribution& rdisttib = req.amounts.back();
|
||||
|
||||
auto it = m_transfers.begin() + i;
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(it->m_ptx_wallet_info->m_tx.vout.size() > it->m_internal_output_index,
|
||||
"m_internal_output_index = " << it->m_internal_output_index <<
|
||||
" is greater or equal to outputs count = " << it->m_ptx_wallet_info->m_tx.vout.size());
|
||||
|
||||
rdisttib.own_global_index = it->m_global_output_index;
|
||||
//rdisttib.own_global_index = it->m_global_output_index;
|
||||
//check if we have Zarcanum era output of pre-Zarcanum
|
||||
if (it->is_zc())
|
||||
{
|
||||
|
|
@ -6077,15 +6110,14 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count_, std::vector<currenc
|
|||
//Zarcanum era
|
||||
rdisttib.amount = 0;
|
||||
//generate distribution in Zarcanum hardfork
|
||||
THROW_IF_FALSE_WALLET_INT_ERR_EX(zarcanum_decoy_set_generator.is_initialized(), "zarcanum_decoy_set_generator are not initialized");
|
||||
rdisttib.offsets = zarcanum_decoy_set_generator.generate_distribution(m_core_runtime_config.hf4_minimum_mixins);
|
||||
build_distribution_for_input(zarcanum_decoy_set_generator, rdisttib.global_offsets, it->m_global_output_index);
|
||||
need_to_request = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//for prezarcanum era use flat distribution
|
||||
rdisttib.amount = it->m_amount;
|
||||
rdisttib.offsets.resize(fake_outputs_count, 0);
|
||||
rdisttib.global_offsets.resize(fake_outputs_count + 1, 0);
|
||||
}
|
||||
}
|
||||
if (need_to_request)
|
||||
|
|
@ -6094,8 +6126,8 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count_, std::vector<currenc
|
|||
while (true)
|
||||
{
|
||||
daemon_resp = COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response();
|
||||
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");
|
||||
bool r = m_core_proxy->call_COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS3(req, daemon_resp);
|
||||
THROW_IF_FALSE_WALLET_EX(r, error::no_connection_to_daemon, "getrandom_outs3.bin");
|
||||
if (daemon_resp.status == API_RETURN_CODE_FAIL)
|
||||
{
|
||||
if (attempt_count < 10)
|
||||
|
|
@ -6118,10 +6150,9 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count_, std::vector<currenc
|
|||
|
||||
std::vector<COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount> scanty_outs;
|
||||
THROW_IF_FALSE_WALLET_EX(daemon_resp.outs.size() == req.amounts.size(), error::not_enough_outs_to_mix, scanty_outs, fake_outputs_count);
|
||||
//for (COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& amount_outs : daemon_resp.outs)
|
||||
for(size_t i = 0; i != daemon_resp.outs.size(); i++)
|
||||
{
|
||||
if (daemon_resp.outs[i].outs.size() != req.amounts[i].offsets.size())
|
||||
if (req.amounts[i].amount != 0 && daemon_resp.outs[i].outs.size() != req.amounts[i].global_offsets.size())
|
||||
{
|
||||
scanty_outs.push_back(daemon_resp.outs[i]);
|
||||
}
|
||||
|
|
@ -6131,6 +6162,7 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count_, std::vector<currenc
|
|||
}
|
||||
|
||||
//lets prefetch m_global_output_index for selected_indicies
|
||||
//this days doesn't prefetch, only validated that prefetch is not needed
|
||||
prefetch_global_indicies_if_needed(selected_indicies);
|
||||
|
||||
//prepare inputs
|
||||
|
|
@ -6154,6 +6186,16 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count_, std::vector<currenc
|
|||
//paste mixin transaction
|
||||
if (daemon_resp.outs.size())
|
||||
{
|
||||
if (td.is_zc())
|
||||
{
|
||||
//get rid of unneeded
|
||||
select_decoys(daemon_resp.outs[i], td.m_global_output_index);
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO: make sure we have exact count needed
|
||||
}
|
||||
|
||||
daemon_resp.outs[i].outs.sort([](const out_entry& a, const out_entry& b){return a.global_amount_index < b.global_amount_index; });
|
||||
for(out_entry& daemon_oe : daemon_resp.outs[i].outs)
|
||||
{
|
||||
|
|
@ -6164,7 +6206,7 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count_, std::vector<currenc
|
|||
oe.concealing_point = daemon_oe.concealing_point;
|
||||
oe.out_reference = daemon_oe.global_amount_index;
|
||||
oe.stealth_address = daemon_oe.stealth_address;
|
||||
oe.blinded_asset_id = daemon_oe.blinded_asset_id; // TODO @#@# BAD DESING, consider refactoring -- sowle
|
||||
oe.blinded_asset_id = daemon_oe.blinded_asset_id; // TODO @#@# BAD DESIGN, consider refactoring -- sowle
|
||||
src.outputs.push_back(oe);
|
||||
if (src.outputs.size() >= fake_outputs_count)
|
||||
break;
|
||||
|
|
@ -6226,6 +6268,72 @@ bool wallet2::prepare_tx_sources(size_t fake_outputs_count_, std::vector<currenc
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------
|
||||
template<typename t_obj_container>
|
||||
typename t_obj_container::value_type extract_random_from_container(t_obj_container& container)
|
||||
{
|
||||
auto it = container.begin();
|
||||
std::advance(it, (crypto::rand<size_t>() % container.size()));
|
||||
typename t_obj_container::value_type obj = *it;
|
||||
container.erase(it);
|
||||
return obj;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------
|
||||
void wallet2::select_decoys(currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& amount_entry, uint64_t own_g_index)
|
||||
{
|
||||
THROW_IF_FALSE_WALLET_INT_ERR_EX(amount_entry.amount == 0, "Amount is not 0 in zc decoys entry");
|
||||
typedef currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::out_entry out_entry;
|
||||
|
||||
//TODO: This strategy would be a subject for continuous refactoring
|
||||
|
||||
//first take all real transactions if ther are some
|
||||
std::list<out_entry> local_outs;
|
||||
std::list<out_entry> coinbases;
|
||||
|
||||
while (amount_entry.outs.size() && local_outs.size() != m_core_runtime_config.hf4_minimum_mixins)
|
||||
{
|
||||
out_entry entry = extract_random_from_container(amount_entry.outs);
|
||||
|
||||
//skip auditable
|
||||
if ((entry.flags & (RANDOM_OUTPUTS_FOR_AMOUNTS_FLAGS_NOT_ALLOWED)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (entry.flags & (RANDOM_OUTPUTS_FOR_AMOUNTS_FLAGS_COINBASE))
|
||||
{
|
||||
coinbases.push_back(entry);
|
||||
continue;
|
||||
}
|
||||
//
|
||||
if (entry.global_amount_index == own_g_index)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
local_outs.push_back(entry);
|
||||
}
|
||||
|
||||
//extend with coin base outs if needed
|
||||
while (coinbases.size() && local_outs.size() != m_core_runtime_config.hf4_minimum_mixins)
|
||||
{
|
||||
out_entry entry = extract_random_from_container(coinbases);
|
||||
local_outs.push_back(entry);
|
||||
}
|
||||
|
||||
THROW_IF_FALSE_WALLET_INT_ERR_EX(local_outs.size() == m_core_runtime_config.hf4_minimum_mixins, "Amount is not 0 in zc decoys entry");
|
||||
amount_entry.outs = local_outs;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------
|
||||
void wallet2::build_distribution_for_input(decoy_selection_generator& zarcanum_decoy_set_generator, std::vector<uint64_t>& offsets, uint64_t own_index)
|
||||
{
|
||||
THROW_IF_FALSE_WALLET_INT_ERR_EX(zarcanum_decoy_set_generator.is_initialized(), "zarcanum_decoy_set_generator are not initialized");
|
||||
if (m_core_runtime_config.hf4_minimum_mixins)
|
||||
{
|
||||
offsets = zarcanum_decoy_set_generator.generate_unique_reversed_distribution(m_last_zc_global_index - 1 > WALLET_FETCH_RANDOM_OUTS_SIZE ? WALLET_FETCH_RANDOM_OUTS_SIZE: m_last_zc_global_index - 1, own_index);
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------
|
||||
bool wallet2::prepare_tx_sources(crypto::hash multisig_id, std::vector<currency::tx_source_entry>& sources, uint64_t& found_money)
|
||||
{
|
||||
|
|
@ -6757,7 +6865,7 @@ bool wallet2::prepare_free_transfers_cache(uint64_t fake_outputs_count)
|
|||
if (td.m_zc_info_ptr)
|
||||
{
|
||||
//zarcanum out, redefine fake_outputs_count
|
||||
fake_outputs_count_local = this->is_auditable() ? 0 : CURRENCY_HF4_MANDATORY_DECOY_SET_SIZE;
|
||||
fake_outputs_count_local = this->is_auditable() ? 0 : m_core_runtime_config.hf4_minimum_mixins;
|
||||
}
|
||||
if (is_transfer_able_to_go(td, fake_outputs_count_local))
|
||||
{
|
||||
|
|
@ -6862,7 +6970,7 @@ bool wallet2::is_connected_to_net()
|
|||
return (res.synchronized_connections_count) ? true : false;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::process_genesis_if_needed(const currency::block& genesis)
|
||||
void wallet2::process_genesis_if_needed(const currency::block& genesis, const std::vector<uint64_t>* pglobal_indexes)
|
||||
{
|
||||
if (!m_transfers.empty() || !m_key_images.empty())
|
||||
return;
|
||||
|
|
@ -6880,7 +6988,7 @@ void wallet2::process_genesis_if_needed(const currency::block& genesis)
|
|||
m_last_bc_timestamp = genesis.timestamp;
|
||||
|
||||
WLT_LOG_L2("Processing genesis block: " << genesis_hash);
|
||||
process_new_transaction(genesis.miner_tx, 0, genesis, nullptr);
|
||||
process_new_transaction(genesis.miner_tx, 0, genesis, pglobal_indexes);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::set_genesis(const crypto::hash& genesis_hash)
|
||||
|
|
@ -7023,7 +7131,7 @@ void wallet2::prepare_tx_destinations(uint64_t needed_money,
|
|||
const crypto::public_key& asset_id,
|
||||
std::vector<currency::tx_destination_entry>& final_destinations)
|
||||
{
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(found_money >= needed_money, "needed_money==" << needed_money << " < found_money==" << found_money);
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(found_money >= needed_money, "found_money = " << print_money_brief(found_money) << " is less than needed_money = " << print_money_brief(needed_money) << ", assed_id: " << asset_id);
|
||||
|
||||
if (is_in_hardfork_zone(ZANO_HARDFORK_04_ZARCANUM))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
#include "currency_core/pos_mining.h"
|
||||
#include "view_iface.h"
|
||||
#include "wallet2_base.h"
|
||||
#include "decoy_selection.h"
|
||||
|
||||
#define WALLET_DEFAULT_TX_SPENDABLE_AGE CURRENCY_HF4_MANDATORY_MIN_COINAGE
|
||||
#define WALLET_POS_MINT_CHECK_HEIGHT_INTERVAL 1
|
||||
|
|
@ -147,6 +148,9 @@ namespace tools
|
|||
std::unordered_map<crypto::public_key, crypto::key_image> m_pending_key_images; // (out_pk -> ki) pairs of change outputs to be added in watch-only wallet without spend sec key
|
||||
uint64_t m_last_pow_block_h = 0;
|
||||
std::list<std::pair<uint64_t, wallet_event_t>> m_rollback_events;
|
||||
uint64_t m_last_zc_global_index = 0;
|
||||
|
||||
|
||||
|
||||
//variables that not being serialized
|
||||
std::atomic<uint64_t> m_last_bc_timestamp = 0;
|
||||
|
|
@ -154,9 +158,7 @@ namespace tools
|
|||
std::atomic<uint64_t> m_last_sync_percent = 0;
|
||||
mutable uint64_t m_current_wallet_file_size = 0;
|
||||
bool m_use_assets_whitelisting = true;
|
||||
|
||||
// variables that should be part of state data object but should not be stored during serialization
|
||||
mutable std::atomic<bool> m_whitelist_updated = false;
|
||||
|
||||
|
||||
//===============================================================
|
||||
template <class t_archive>
|
||||
|
|
@ -220,7 +222,8 @@ namespace tools
|
|||
a & m_rollback_events;
|
||||
a & m_whitelisted_assets;
|
||||
a & m_use_assets_whitelisting;
|
||||
}
|
||||
a & m_last_zc_global_index;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -397,6 +400,7 @@ namespace tools
|
|||
void transfer_asset_ownership(const crypto::public_key asset_id, const crypto::public_key& new_owner, currency::transaction& result_tx);
|
||||
|
||||
bool daemon_get_asset_info(const crypto::public_key& asset_id, currency::asset_descriptor_base& adb);
|
||||
const std::unordered_map<crypto::public_key, wallet_own_asset_context>& get_own_assets() const { return m_own_asset_descriptors; }
|
||||
bool set_core_proxy(const std::shared_ptr<i_core_proxy>& proxy);
|
||||
void set_pos_utxo_count_limits_for_defragmentation_tx(uint64_t min_outs, uint64_t max_outs); // don't create UTXO defrag. tx if there are less than 'min_outs' outs; don't put more than 'max_outs' outs
|
||||
void set_pos_decoys_count_for_defragmentation_tx(size_t decoys_count);
|
||||
|
|
@ -537,7 +541,6 @@ namespace tools
|
|||
void get_transfers(transfer_container& incoming_transfers) const;
|
||||
std::string get_transfers_str(bool include_spent = true, bool include_unspent = true, bool show_only_unknown = false, const std::string& filter_asset_ticker = std::string{}) const;
|
||||
std::string get_balance_str() const;
|
||||
std::string get_balance_str_raw() const;
|
||||
|
||||
// Returns all payments by given id in unspecified order
|
||||
void get_payments(const std::string& payment_id, std::list<payment_details>& payments, uint64_t min_height = 0) const;
|
||||
|
|
@ -658,14 +661,9 @@ namespace tools
|
|||
|
||||
bool add_custom_asset_id(const crypto::public_key& asset_id, currency::asset_descriptor_base& asset_descriptor);
|
||||
bool delete_custom_asset_id(const crypto::public_key& asset_id);
|
||||
const std::unordered_map<crypto::public_key, currency::asset_descriptor_base>& get_local_whitelist() const;
|
||||
const std::unordered_map<crypto::public_key, currency::asset_descriptor_base>& get_global_whitelist() const;
|
||||
const std::unordered_map<crypto::public_key, tools::wallet_own_asset_context>& get_own_assets() const;
|
||||
|
||||
bool load_whitelisted_tokens_if_not_loaded() const;
|
||||
bool load_whitelisted_tokens() const;
|
||||
|
||||
|
||||
void set_connectivity_options(unsigned int timeout);
|
||||
|
||||
/*
|
||||
|
|
@ -699,9 +697,6 @@ namespace tools
|
|||
bool encrypt_buffer(const std::string& buff, std::string& res_buff);
|
||||
bool decrypt_buffer(const std::string& buff, std::string& res_buff);
|
||||
bool is_in_hardfork_zone(uint64_t hardfork_index) const;
|
||||
|
||||
//performance inefficient call, suitable only for rare ocasions or super lazy developers
|
||||
bool proxy_to_daemon(const std::string& uri, const std::string& body, int& response_code, std::string& response_body);
|
||||
|
||||
construct_tx_param get_default_construct_tx_param();
|
||||
|
||||
|
|
@ -761,10 +756,10 @@ private:
|
|||
std::vector<std::string> get_aliases_for_address(const std::string& addr);
|
||||
bool is_connected_to_net();
|
||||
bool is_transfer_okay_for_pos(const transfer_details& tr, bool is_zarcanum_hf, uint64_t& stake_unlock_time) const;
|
||||
bool scan_unconfirmed_outdate_tx();
|
||||
bool scan_not_compliant_unconfirmed_txs();
|
||||
const currency::transaction& get_transaction_by_id(const crypto::hash& tx_hash);
|
||||
void rise_on_transfer2(const wallet_public::wallet_transfer_info& wti);
|
||||
void process_genesis_if_needed(const currency::block& genesis);
|
||||
void process_genesis_if_needed(const currency::block& genesis, const std::vector<uint64_t>* pglobal_indexes);
|
||||
bool build_escrow_proposal(bc_services::contract_private_details& ecrow_details, uint64_t fee, uint64_t unlock_time, currency::tx_service_attachment& att, std::vector<uint64_t>& selected_indicies);
|
||||
bool prepare_tx_sources(assets_selection_context& needed_money_map, size_t fake_outputs_count, uint64_t dust_threshold, std::vector<currency::tx_source_entry>& sources, std::vector<uint64_t>& selected_indicies);
|
||||
bool prepare_tx_sources(size_t fake_outputs_count, std::vector<currency::tx_source_entry>& sources, const std::vector<uint64_t>& selected_indicies);
|
||||
|
|
@ -852,6 +847,7 @@ private:
|
|||
uint64_t get_directly_spent_transfer_index_by_input_in_tracking_wallet(uint64_t amount, const std::vector<currency::txout_ref_v> & key_offsets);
|
||||
uint64_t get_directly_spent_transfer_index_by_input_in_tracking_wallet(const currency::txin_to_key& intk);
|
||||
uint64_t get_directly_spent_transfer_index_by_input_in_tracking_wallet(const currency::txin_zc_input& inzc);
|
||||
uint8_t out_get_mixin_attr(const currency::tx_out_v& out_t);
|
||||
const crypto::public_key& out_get_pub_key(const currency::tx_out_v& out_t, std::list<currency::htlc_info>& htlc_info_list);
|
||||
bool expand_selection_with_zc_input(assets_selection_context& needed_money_map, uint64_t fake_outputs_count, std::vector<uint64_t>& selected_indexes);
|
||||
|
||||
|
|
@ -859,6 +855,8 @@ private:
|
|||
void remove_transfer_from_amount_gindex_map(uint64_t tid);
|
||||
uint64_t get_alias_cost(const std::string& alias);
|
||||
detail::split_strategy_id_t get_current_split_strategy();
|
||||
void build_distribution_for_input(decoy_selection_generator& zarcanum_decoy_set_generator, std::vector<uint64_t>& offsets, uint64_t own_index);
|
||||
void select_decoys(currency::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount & amount_entry, uint64_t own_g_index);
|
||||
|
||||
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);
|
||||
|
|
@ -886,6 +884,7 @@ private:
|
|||
|
||||
|
||||
bool m_do_rise_transfer;
|
||||
uint64_t m_max_allowed_output_amount_for_defragmentation_tx;
|
||||
uint64_t m_min_utxo_count_for_defragmentation_tx;
|
||||
uint64_t m_max_utxo_count_for_defragmentation_tx;
|
||||
size_t m_decoys_count_for_defragmentation_tx;
|
||||
|
|
@ -894,6 +893,7 @@ private:
|
|||
uint64_t m_upper_transaction_size_limit; //TODO: auto-calc this value or request from daemon, now use some fixed value
|
||||
|
||||
std::atomic<bool> m_stop;
|
||||
mutable std::atomic<bool> m_whitelist_updated = false;
|
||||
std::shared_ptr<i_core_proxy> m_core_proxy;
|
||||
std::shared_ptr<i_wallet2_callback> m_wcallback;
|
||||
|
||||
|
|
@ -911,6 +911,8 @@ private:
|
|||
std::string m_votes_config_path;
|
||||
tools::wallet_public::wallet_vote_config m_votes_config;
|
||||
|
||||
uint64_t m_last_known_daemon_height = 0;
|
||||
|
||||
//this needed to access wallets state in coretests, for creating abnormal blocks and tranmsactions
|
||||
friend class test_generator;
|
||||
}; // class wallet2
|
||||
|
|
|
|||
|
|
@ -138,17 +138,17 @@ namespace wallet_public
|
|||
|
||||
struct wallet_transfer_info
|
||||
{
|
||||
uint64_t timestamp;
|
||||
crypto::hash tx_hash;
|
||||
uint64_t height; //if height == 0 then tx is unconfirmed
|
||||
uint64_t unlock_time;
|
||||
uint32_t tx_blob_size;
|
||||
uint64_t timestamp = 0;
|
||||
crypto::hash tx_hash = currency::null_hash;
|
||||
uint64_t height = 0; //if height == 0 then tx is unconfirmed
|
||||
uint64_t unlock_time = 0;
|
||||
uint32_t tx_blob_size = 0;
|
||||
std::string payment_id;
|
||||
std::string comment;
|
||||
bool is_service;
|
||||
bool is_mixing;
|
||||
bool is_mining;
|
||||
uint64_t tx_type;
|
||||
bool is_service = false;
|
||||
bool is_mixing = false;
|
||||
bool is_mining = false;
|
||||
uint64_t tx_type = 0;
|
||||
employed_tx_entries employed_entries;
|
||||
std::vector<currency::tx_service_attachment> service_entries;
|
||||
std::vector<std::string> remote_addresses; //optional
|
||||
|
|
@ -157,11 +157,11 @@ namespace wallet_public
|
|||
std::vector<wallet_sub_transfer_info> subtransfers;
|
||||
|
||||
//not included in streaming serialization
|
||||
uint64_t fee;
|
||||
bool show_sender;
|
||||
uint64_t fee = 0;
|
||||
bool show_sender = false;
|
||||
std::vector<escrow_contract_details> contract;
|
||||
uint16_t extra_flags;
|
||||
uint64_t transfer_internal_index;
|
||||
uint16_t extra_flags = 0;
|
||||
uint64_t transfer_internal_index = 0;
|
||||
|
||||
//not included in kv serialization map
|
||||
currency::transaction tx;
|
||||
|
|
|
|||
|
|
@ -38,25 +38,25 @@ POP_VS_WARNINGS
|
|||
catch (const tools::error::daemon_busy& e) \
|
||||
{ \
|
||||
er.code = WALLET_RPC_ERROR_CODE_DAEMON_IS_BUSY; \
|
||||
er.message = e.what(); \
|
||||
er.message = std::string("WALLET_RPC_ERROR_CODE_DAEMON_IS_BUSY") + e.what(); \
|
||||
return false; \
|
||||
} \
|
||||
catch (const tools::error::not_enough_money& e) \
|
||||
{ \
|
||||
er.code = WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR; \
|
||||
er.message = e.error_code(); \
|
||||
er.code = WALLET_RPC_ERROR_CODE_NOT_ENOUGH_MONEY; \
|
||||
er.message = std::string("WALLET_RPC_ERROR_CODE_NOT_ENOUGH_MONEY") + e.error_code(); \
|
||||
return false; \
|
||||
} \
|
||||
catch (const tools::error::wallet_error& e) \
|
||||
{ \
|
||||
er.code = WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR; \
|
||||
er.message = e.error_code(); \
|
||||
er.message = std::string("WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR") + e.error_code(); \
|
||||
return false; \
|
||||
} \
|
||||
catch (const std::exception& e) \
|
||||
{ \
|
||||
er.code = WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR; \
|
||||
er.message = e.what(); \
|
||||
er.message = std::string("WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR") + e.what(); \
|
||||
return false; \
|
||||
} \
|
||||
catch (...) \
|
||||
|
|
|
|||
|
|
@ -13,3 +13,4 @@
|
|||
#define WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR -4
|
||||
#define WALLET_RPC_ERROR_CODE_WRONG_PAYMENT_ID -5
|
||||
#define WALLET_RPC_ERROR_CODE_WRONG_ARGUMENT -6
|
||||
#define WALLET_RPC_ERROR_CODE_NOT_ENOUGH_MONEY -7
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
#define TX_POOL_SCAN_INTERVAL 1
|
||||
#endif
|
||||
|
||||
#define HTTP_PROXY_TIMEOUT 2000
|
||||
#define HTTP_PROXY_TIMEOUT 4000
|
||||
#define HTTP_PROXY_ATTEMPTS_COUNT 1
|
||||
|
||||
const command_line::arg_descriptor<bool> arg_alloc_win_console ( "alloc-win-console", "Allocates debug console with GUI", false );
|
||||
|
|
|
|||
|
|
@ -553,12 +553,16 @@ bool test_generator::build_wallets(const blockchain_vector& blockchain,
|
|||
//skip genesis
|
||||
currency::block_direct_data_entry bdde = AUTO_VAL_INIT(bdde);
|
||||
std::shared_ptr<block_extended_info> bptr(new block_extended_info());
|
||||
bptr->bl = b->b;
|
||||
bptr->bl = b->b;
|
||||
bdde.block_ptr = bptr;
|
||||
std::shared_ptr<transaction_chain_entry> coinbase_tx_ptr(new transaction_chain_entry());
|
||||
coinbase_tx_ptr->m_global_output_indexes = get_tx_gindex_from_map(currency::get_transaction_hash(b->b.miner_tx), txs_outs);
|
||||
bdde.coinbase_ptr = coinbase_tx_ptr;
|
||||
for (auto& tx : b->m_transactions)
|
||||
{
|
||||
std::shared_ptr<transaction_chain_entry> tx_ptr(new transaction_chain_entry());
|
||||
tx_ptr->tx = tx;
|
||||
tx_ptr->m_global_output_indexes = get_tx_gindex_from_map(currency::get_transaction_hash(tx), txs_outs);
|
||||
bdde.txs_ptr.push_back(tx_ptr);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -752,6 +752,17 @@ bool shuffle_source_entries(std::vector<currency::tx_source_entry>& sources);
|
|||
// one output will be created for each destination entry and one additional output to add up to old coinbase total amount
|
||||
bool replace_coinbase_in_genesis_block(const std::vector<currency::tx_destination_entry>& destinations, test_generator& generator, std::vector<test_event_entry>& events, currency::block& genesis_block);
|
||||
|
||||
template<typename t_map>
|
||||
const std::vector<uint64_t>& get_tx_gindex_from_map(const crypto::hash& tx_id, const t_map& id_to_vector)
|
||||
{
|
||||
auto it_global_indexes = id_to_vector.find(tx_id);
|
||||
if (it_global_indexes == id_to_vector.end())
|
||||
{
|
||||
throw std::runtime_error("TX ID NOT FOUND");
|
||||
}
|
||||
return it_global_indexes->second;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
template<class t_test_class>
|
||||
auto do_check_tx_verification_context(const currency::tx_verification_context& tvc, bool tx_added, size_t event_index, const currency::transaction& tx, t_test_class& validator, int)
|
||||
|
|
@ -994,6 +1005,7 @@ namespace crypto {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
inline uint64_t get_sources_total_amount(const std::vector<currency::tx_source_entry>& s)
|
||||
{
|
||||
uint64_t result = 0;
|
||||
|
|
|
|||
|
|
@ -99,20 +99,30 @@ bool wallet_test_core_proxy::call_COMMAND_RPC_GET_BLOCKS_FAST(const currency::CO
|
|||
{
|
||||
auto b = m_blocks[i];
|
||||
currency::block_complete_entry bce = AUTO_VAL_INIT(bce);
|
||||
for (auto tx : b->m_transactions)
|
||||
bce.tx_global_outs.resize(b->m_transactions.size());
|
||||
bce.coinbase_global_outs = get_tx_gindex(currency::get_transaction_hash(b->b.miner_tx));
|
||||
for (size_t j = 0; j != b->m_transactions.size(); j++)
|
||||
{
|
||||
const auto& tx = b->m_transactions[j];
|
||||
bce.txs.push_back(tx_to_blob(tx));
|
||||
bce.tx_global_outs[j].v = get_tx_gindex(currency::get_transaction_hash(tx));
|
||||
}
|
||||
bce.block = block_to_blob(b->b);
|
||||
rsp.blocks.push_back(bce);
|
||||
}
|
||||
rsp.current_height = m_blocks.size();
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::vector<uint64_t>& wallet_test_core_proxy::get_tx_gindex(const crypto::hash& tx_id)
|
||||
{
|
||||
return get_tx_gindex_from_map(tx_id, m_txs_outs);
|
||||
}
|
||||
bool wallet_test_core_proxy::call_COMMAND_RPC_GET_BLOCKS_DIRECT(const currency::COMMAND_RPC_GET_BLOCKS_DIRECT::request& rqt, currency::COMMAND_RPC_GET_BLOCKS_DIRECT::response& rsp)
|
||||
{
|
||||
currency::COMMAND_RPC_GET_BLOCKS_FAST::request req = AUTO_VAL_INIT(req);
|
||||
req.block_ids = rqt.block_ids;
|
||||
req.minimum_height = rqt.minimum_height;
|
||||
req.need_global_indexes = rqt.need_global_indexes;
|
||||
currency::COMMAND_RPC_GET_BLOCKS_FAST::response res = AUTO_VAL_INIT(res);
|
||||
bool r = this->call_COMMAND_RPC_GET_BLOCKS_FAST(req, res);
|
||||
rsp.status = res.status;
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ struct wallet_test_core_proxy : public tools::i_core_proxy
|
|||
virtual bool call_COMMAND_RPC_GET_CURRENT_CORE_TX_EXPIRATION_MEDIAN(const currency::COMMAND_RPC_GET_CURRENT_CORE_TX_EXPIRATION_MEDIAN::request& req, currency::COMMAND_RPC_GET_CURRENT_CORE_TX_EXPIRATION_MEDIAN::response& res) override;
|
||||
virtual bool get_transfer_address(const std::string& adr_str, currency::account_public_address& addr, std::string& payment_id) override;
|
||||
|
||||
const std::vector<uint64_t>& get_tx_gindex(const crypto::hash& tx_id);
|
||||
|
||||
|
||||
test_generator::tx_global_indexes m_txs_outs;
|
||||
test_generator::blockchain_vector m_blocks;
|
||||
test_generator::outputs_index m_oi;
|
||||
|
|
|
|||
|
|
@ -34,11 +34,15 @@ POP_VS_WARNINGS
|
|||
|
||||
void test_plain_wallet()
|
||||
{
|
||||
|
||||
std::string res = plain_wallet::init("195.201.107.230", "33336", "C:\\Users\\roky\\home\\", 0);
|
||||
//std::string res = plain_wallet::init("195.201.107.230", "33336", "E:\\tmp\\", 0);
|
||||
std::string res = plain_wallet::init("127.0.0.1", "12111", "C:\\Users\\roky\\home\\", 0);
|
||||
|
||||
uint64_t instance_id = 0;
|
||||
res = plain_wallet::open("SEGA_2", "Test2");
|
||||
res = plain_wallet::open("test_restored.zan", "111");
|
||||
//res = plain_wallet::restore("heart level clear fate sorrow childhood sent fate ceiling party third steel came ask mix neither message already almost vast date glide tumble color okay space",
|
||||
// "test_restored.zan", "111", "");
|
||||
|
||||
|
||||
while(true)
|
||||
{
|
||||
epee::misc_utils::sleep_no_w(2000);
|
||||
|
|
@ -50,16 +54,18 @@ void test_plain_wallet()
|
|||
}
|
||||
|
||||
|
||||
std::string invoke_body = "{\"method\":\"get_recent_txs_and_info\",\"params\":{\"offset\":0,\"count\":30,\"update_provision_info\":true}}";
|
||||
|
||||
res = plain_wallet::sync_call("invoke", instance_id, invoke_body);
|
||||
std::string invoke_body = "{\"method\":\"store\",\"params\":{}}";
|
||||
//std::string res1 = plain_wallet::sync_call("invoke", instance_id, invoke_body);
|
||||
|
||||
invoke_body = "{\"method\":\"assets_whitelist_get\",\"params\":{}}";
|
||||
invoke_body = "{\"method\":\"get_recent_txs_and_info\",\"params\":{\"offset\":0,\"count\":30,\"update_provision_info\":true}}";
|
||||
std::string res2 = plain_wallet::sync_call("invoke", instance_id, invoke_body);
|
||||
|
||||
res = plain_wallet::sync_call("invoke", instance_id, invoke_body);
|
||||
invoke_body = "{\"method\":\"getbalance\",\"params\":{}}";
|
||||
std::string res3 = plain_wallet::sync_call("invoke", instance_id, invoke_body);
|
||||
|
||||
|
||||
res = plain_wallet::close_wallet(instance_id);
|
||||
invoke_body = "{\r\n \"method\": \"transfer\",\r\n \"params\": {\r\n \"destinations\": [\r\n {\r\n \"amount\": \"1000000000000\",\r\n \"address\": \"ZxD9oVwGwW6ULix9Pqttnr7JDpaoLvDVA1KJ9eA9KRxPMRZT5X7WwtU94XH1Z6q6XTMxNbHmbV2xfZ429XxV6fST2DxEg4BQV\",\r\n \"asset_id\": \"cc4e69455e63f4a581257382191de6856c2156630b3fba0db4bdd73ffcfb36b6\"\r\n }\r\n ],\r\n \"fee\": 10000000000,\r\n \"mixin\": 10,\r\n \"payment_id\": \"\",\r\n \"comment\": \"\",\r\n \"push_payer\": false,\r\n \"hide_receiver\": true\r\n }\r\n}";
|
||||
std::string res4 = plain_wallet::sync_call("invoke", instance_id, invoke_body);
|
||||
|
||||
LOG_PRINT_L0(res);
|
||||
|
||||
|
|
|
|||
|
|
@ -18,10 +18,10 @@ public:
|
|||
m_bob.generate();
|
||||
|
||||
uint64_t block_reward_without_fee = 0;
|
||||
|
||||
uint64_t block_reward = 0;
|
||||
if(!construct_miner_tx(0, 0, 0, 2, 0, m_bob.get_keys().account_address, m_bob.get_keys().account_address, m_tx, block_reward_without_fee, block_reward, TRANSACTION_VERSION_PRE_HF4, blobdata(), CURRENCY_MINER_TX_MAX_OUTS))
|
||||
return false;
|
||||
|
||||
m_tx_pub_key = get_tx_pub_key_from_extra(m_tx);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,32 +10,39 @@ TEST(decoy_selection_test, decoy_selection_test)
|
|||
{
|
||||
const uint64_t test_scale_size = 20000;
|
||||
decoy_selection_generator dsg;
|
||||
dsg.init(test_scale_size - 1);
|
||||
dsg.init(100);
|
||||
std::map<uint64_t, uint64_t> hits;
|
||||
|
||||
|
||||
|
||||
//std::vector<uint64_t> decoys = dsg.generate_distribution(15);
|
||||
|
||||
std::cout << "";
|
||||
|
||||
//std::vector<uint64_t> hits(test_scale_size, 0);
|
||||
|
||||
|
||||
// while (true)
|
||||
// {
|
||||
// std::vector<uint64_t> decoys = dsg.generate_distribution(15);
|
||||
// for (auto d : decoys)
|
||||
// {
|
||||
// hits[d]++;
|
||||
// }
|
||||
//
|
||||
// if (hits[10] > 500)
|
||||
// break;
|
||||
//
|
||||
// }
|
||||
// std::stringstream ss;
|
||||
// for (auto it = hits.begin(); it != hits.end(); it++)
|
||||
// {
|
||||
// //if (hits[i] != 0)
|
||||
// {
|
||||
// ss << it->first << ", " << it->second << ENDL;
|
||||
// }
|
||||
// }
|
||||
// epee::file_io_utils::save_string_to_file("distribution.csv", ss.str());
|
||||
while (true)
|
||||
{
|
||||
std::vector<uint64_t> decoys = dsg.generate_distribution(15);
|
||||
for (auto d : decoys)
|
||||
{
|
||||
hits[d]++;
|
||||
}
|
||||
|
||||
if (hits[10] > 500)
|
||||
break;
|
||||
|
||||
}
|
||||
std::stringstream ss;
|
||||
for (auto it = hits.begin(); it != hits.end(); it++)
|
||||
{
|
||||
if (it->second != 0)
|
||||
{
|
||||
ss << it->first << ", " << it->second << std::endl;
|
||||
}
|
||||
}
|
||||
epee::file_io_utils::save_string_to_file("distribution.csv", ss.str());
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
7
utils/configure_win64_msvs2022_gui.cmd
Normal file
7
utils/configure_win64_msvs2022_gui.cmd
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
call configure_local_paths_msvs2022.cmd
|
||||
|
||||
cd ..
|
||||
@mkdir build_msvc2022_64
|
||||
cd build_msvc2022_64
|
||||
|
||||
cmake -D TESTNET=FALSE -D USE_PCH=TRUE -D BUILD_TESTS=TRUE -D OPENSSL_ROOT_DIR="%OPENSSL_ROOT_DIR%" -D CMAKE_PREFIX_PATH="%QT_PREFIX_PATH%"\msvc2019_64 -D BUILD_GUI=TRUE -D STATIC=FALSE -DBOOST_ROOT="%BOOST_ROOT%" -DBOOST_LIBRARYDIR="%BOOST_ROOT%\lib64-msvc-14.3" -G "Visual Studio 17 2022" -A x64 -T host=x64 ".."
|
||||
7
utils/configure_win64_msvs2022_gui_testnet.cmd
Normal file
7
utils/configure_win64_msvs2022_gui_testnet.cmd
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
call configure_local_paths_msvs2022.cmd
|
||||
|
||||
cd ..
|
||||
@mkdir build_msvc2022_64_tn
|
||||
cd build_msvc2022_64_tn
|
||||
|
||||
cmake -D TESTNET=TRUE -D USE_PCH=TRUE -D BUILD_TESTS=TRUE -D OPENSSL_ROOT_DIR="%OPENSSL_ROOT_DIR%" -D CMAKE_PREFIX_PATH="%QT_PREFIX_PATH%"\msvc2019_64 -D BUILD_GUI=TRUE -D STATIC=FALSE -DBOOST_ROOT="%BOOST_ROOT%" -DBOOST_LIBRARYDIR="%BOOST_ROOT%\lib64-msvc-14.3" -G "Visual Studio 17 2022" -A x64 -T host=x64 ".."
|
||||
1
utils/test_api_files/get_alias_by_address.json
Normal file
1
utils/test_api_files/get_alias_by_address.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"method": "get_alias_details","params": {"alias": "zoidb"}}
|
||||
|
|
@ -1 +1 @@
|
|||
{"method": "get_alias_details","params": {"alias": "zoidb"}}
|
||||
{"method": "get_alias_details","params": "ZxCjF84feY7GQZ1fdy9r3ZJABwaFjmb2Dd25H5qANWZ2VufpmyNu7ZnShMBDpiw8VW2k1EjPZswgFZnx3v1EYgJ32Rjn64mq9"}
|
||||
Loading…
Add table
Reference in a new issue