Merge pull request #45 from wowario/upstream

Upstream merge
pull/60/head
jw 6 years ago committed by GitHub
commit aa29f98f08
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1496,6 +1496,8 @@ public:
*/
virtual std::map<uint64_t, std::tuple<uint64_t, uint64_t, uint64_t>> get_output_histogram(const std::vector<uint64_t> &amounts, bool unlocked, uint64_t recent_cutoff, uint64_t min_count) const = 0;
virtual bool get_output_distribution(uint64_t amount, uint64_t from_height, uint64_t to_height, std::vector<uint64_t> &distribution, uint64_t &base) const = 0;
/**
* @brief is BlockchainDB in read-only mode?
*

@ -3180,6 +3180,47 @@ std::map<uint64_t, std::tuple<uint64_t, uint64_t, uint64_t>> BlockchainLMDB::get
return histogram;
}
bool BlockchainLMDB::get_output_distribution(uint64_t amount, uint64_t from_height, uint64_t to_height, std::vector<uint64_t> &distribution, uint64_t &base) const
{
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
TXN_PREFIX_RDONLY();
RCURSOR(output_amounts);
distribution.clear();
const uint64_t db_height = height();
if (from_height >= db_height)
return false;
distribution.resize(db_height - from_height, 0);
bool fret = true;
MDB_val_set(k, amount);
MDB_val v;
MDB_cursor_op op = MDB_SET;
while (1)
{
int ret = mdb_cursor_get(m_cur_output_amounts, &k, &v, op);
op = MDB_NEXT_DUP;
if (ret == MDB_NOTFOUND)
break;
if (ret)
throw0(DB_ERROR("Failed to enumerate outputs"));
const outkey *ok = (const outkey *)v.mv_data;
const uint64_t height = ok->data.height;
if (height >= from_height)
distribution[height - from_height]++;
else
base++;
if (to_height > 0 && height > to_height)
break;
}
TXN_POSTFIX_RDONLY();
return true;
}
void BlockchainLMDB::check_hard_fork_info()
{
}

@ -293,6 +293,8 @@ public:
*/
std::map<uint64_t, std::tuple<uint64_t, uint64_t, uint64_t>> get_output_histogram(const std::vector<uint64_t> &amounts, bool unlocked, uint64_t recent_cutoff, uint64_t min_count) const;
bool get_output_distribution(uint64_t amount, uint64_t from_height, uint64_t to_height, std::vector<uint64_t> &distribution, uint64_t &base) const;
private:
void do_resize(uint64_t size_increase=0);

@ -1963,7 +1963,7 @@ void Blockchain::get_output_key_mask_unlocked(const uint64_t& amount, const uint
unlocked = is_tx_spendtime_unlocked(m_db->get_tx_unlock_time(toi.first));
}
//------------------------------------------------------------------
bool Blockchain::get_output_distribution(uint64_t amount, uint64_t from_height, uint64_t &start_height, std::vector<uint64_t> &distribution, uint64_t &base) const
bool Blockchain::get_output_distribution(uint64_t amount, uint64_t from_height, uint64_t to_height, uint64_t &start_height, std::vector<uint64_t> &distribution, uint64_t &base) const
{
// rct outputs don't exist before v3
if (amount == 0)
@ -1984,22 +1984,7 @@ bool Blockchain::get_output_distribution(uint64_t amount, uint64_t from_height,
if (from_height > start_height)
start_height = from_height;
distribution.clear();
uint64_t db_height = m_db->height();
if (start_height >= db_height)
return false;
distribution.resize(db_height - start_height, 0);
bool r = for_all_outputs(amount, [&](uint64_t height) {
CHECK_AND_ASSERT_MES(height >= real_start_height && height <= db_height, false, "Height not in expected range");
if (height >= start_height)
distribution[height - start_height]++;
else
base++;
return true;
});
if (!r)
return false;
return true;
return m_db->get_output_distribution(amount, start_height, to_height, distribution, base);
}
//------------------------------------------------------------------
// This function takes a list of block hashes from another node
@ -3944,7 +3929,7 @@ MWARNING("first_index: " << first_index << " - " << last_index);
// add to the known hashes array
if (!valid)
{
MWARNING("invalid hash for blocks " << n * HASH_OF_HASHES_STEP << " - " << (n * HASH_OF_HASHES_STEP + HASH_OF_HASHES_STEP - 1));
MDEBUG("invalid hash for blocks " << n * HASH_OF_HASHES_STEP << " - " << (n * HASH_OF_HASHES_STEP + HASH_OF_HASHES_STEP - 1));
break;
}

@ -527,12 +527,13 @@ namespace cryptonote
* @brief gets per block distribution of outputs of a given amount
*
* @param amount the amount to get a ditribution for
* @param return-by-reference from_height the height before which we do not care about the data
* @param from_height the height before which we do not care about the data
* @param to_height the height after which we do not care about the data
* @param return-by-reference start_height the height of the first rct output
* @param return-by-reference distribution the start offset of the first rct output in this block (same as previous if none)
* @param return-by-reference base how many outputs of that amount are before the stated distribution
*/
bool get_output_distribution(uint64_t amount, uint64_t from_height, uint64_t &start_height, std::vector<uint64_t> &distribution, uint64_t &base) const;
bool get_output_distribution(uint64_t amount, uint64_t from_height, uint64_t to_height, uint64_t &start_height, std::vector<uint64_t> &distribution, uint64_t &base) const;
/**
* @brief gets the global indices for outputs from a given transaction

@ -1074,9 +1074,9 @@ namespace cryptonote
return m_blockchain_storage.get_random_rct_outs(req, res);
}
//-----------------------------------------------------------------------------------------------
bool core::get_output_distribution(uint64_t amount, uint64_t from_height, uint64_t &start_height, std::vector<uint64_t> &distribution, uint64_t &base) const
bool core::get_output_distribution(uint64_t amount, uint64_t from_height, uint64_t to_height, uint64_t &start_height, std::vector<uint64_t> &distribution, uint64_t &base) const
{
return m_blockchain_storage.get_output_distribution(amount, from_height, start_height, distribution, base);
return m_blockchain_storage.get_output_distribution(amount, from_height, to_height, start_height, distribution, base);
}
//-----------------------------------------------------------------------------------------------
bool core::get_tx_outputs_gindexs(const crypto::hash& tx_id, std::vector<uint64_t>& indexs) const

@ -576,7 +576,7 @@ namespace cryptonote
*
* @brief get per block distribution of outputs of a given amount
*/
bool get_output_distribution(uint64_t amount, uint64_t from_height, uint64_t &start_height, std::vector<uint64_t> &distribution, uint64_t &base) const;
bool get_output_distribution(uint64_t amount, uint64_t from_height, uint64_t to_height, uint64_t &start_height, std::vector<uint64_t> &distribution, uint64_t &base) const;
/**
* @copydoc miner::pause

@ -1632,10 +1632,10 @@ skip:
}
uint64_t n_use_blocks = m_core.prevalidate_block_hashes(arg.start_height, arg.m_block_ids);
if (n_use_blocks == 0)
if (n_use_blocks + HASH_OF_HASHES_STEP <= arg.m_block_ids.size())
{
LOG_ERROR_CCONTEXT("Peer yielded no usable blocks, dropping connection");
drop_connection(context, false, false);
LOG_ERROR_CCONTEXT("Most blocks are invalid, dropping connection");
drop_connection(context, true, false);
return 1;
}

@ -241,6 +241,7 @@ namespace nodetool
bool check_connection_and_handshake_with_peer(const epee::net_utils::network_address& na, uint64_t last_seen_stamp);
bool gray_peerlist_housekeeping();
bool check_incoming_connections();
void kill() { ///< will be called e.g. from deinit()
_info("Killing the net_node");
@ -304,6 +305,7 @@ namespace nodetool
epee::math_helper::once_a_time_seconds<1> m_connections_maker_interval;
epee::math_helper::once_a_time_seconds<60*30, false> m_peerlist_store_interval;
epee::math_helper::once_a_time_seconds<60> m_gray_peerlist_housekeeping_interval;
epee::math_helper::once_a_time_seconds<900, false> m_incoming_connections_interval;
std::string m_bind_ip;
std::string m_port;

@ -1279,6 +1279,20 @@ namespace nodetool
m_connections_maker_interval.do_call(boost::bind(&node_server<t_payload_net_handler>::connections_maker, this));
m_gray_peerlist_housekeeping_interval.do_call(boost::bind(&node_server<t_payload_net_handler>::gray_peerlist_housekeeping, this));
m_peerlist_store_interval.do_call(boost::bind(&node_server<t_payload_net_handler>::store_config, this));
m_incoming_connections_interval.do_call(boost::bind(&node_server<t_payload_net_handler>::check_incoming_connections, this));
return true;
}
//-----------------------------------------------------------------------------------
template<class t_payload_net_handler>
bool node_server<t_payload_net_handler>::check_incoming_connections()
{
if (m_offline || m_hide_my_port)
return true;
if (get_incoming_connections_count() == 0)
{
const el::Level level = el::Level::Warning;
MCLOG_RED(level, "global", "No incoming connections - check firewalls/routers allow port " << get_this_peer_port());
}
return true;
}
//-----------------------------------------------------------------------------------

@ -47,6 +47,7 @@ using namespace epee;
#include "rpc/rpc_args.h"
#include "core_rpc_server_error_codes.h"
#include "p2p/net_node.h"
#include "get_output_distribution_cache.h"
#include "version.h"
#undef MONERO_DEFAULT_LOG_CATEGORY
@ -2110,9 +2111,30 @@ namespace cryptonote
continue;
}
// this is a slow operation, so we have precomputed caches of common cases
bool found = false;
for (const auto &slot: get_output_distribution_cache)
{
if (slot.amount == amount && slot.from_height == req.from_height && slot.to_height == req.to_height)
{
res.distributions.push_back({amount, slot.start_height, slot.distribution, slot.base});
found = true;
if (req.cumulative)
{
auto &distribution = res.distributions.back().distribution;
distribution[0] += slot.base;
for (size_t n = 1; n < distribution.size(); ++n)
distribution[n] += distribution[n-1];
}
break;
}
}
if (found)
continue;
std::vector<uint64_t> distribution;
uint64_t start_height, base;
if (!m_core.get_output_distribution(amount, req.from_height, start_height, distribution, base))
if (!m_core.get_output_distribution(amount, req.from_height, req.to_height, start_height, distribution, base))
{
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
error_resp.message = "Failed to get rct distribution";

@ -0,0 +1,23 @@
static const struct
{
uint64_t amount;
uint64_t from_height;
uint64_t to_height;
uint64_t start_height;
uint64_t base;
std::vector<uint64_t> distribution;
}
get_output_distribution_cache[] =
{
{
0,
{
},
},
{
0,
{
}
}
};

@ -113,6 +113,7 @@ public:
virtual bool for_all_outputs(uint64_t amount, const std::function<bool(uint64_t height)> &f) const { return true; }
virtual bool is_read_only() const { return false; }
virtual std::map<uint64_t, std::tuple<uint64_t, uint64_t, uint64_t>> get_output_histogram(const std::vector<uint64_t> &amounts, bool unlocked, uint64_t recent_cutoff, uint64_t min_count) const { return std::map<uint64_t, std::tuple<uint64_t, uint64_t, uint64_t>>(); }
virtual bool get_output_distribution(uint64_t amount, uint64_t from_height, uint64_t to_height, std::vector<uint64_t> &distribution, uint64_t &base) const { return false; }
virtual void add_txpool_tx(const transaction &tx, const txpool_tx_meta_t& details) {}
virtual void update_txpool_tx(const crypto::hash &txid, const txpool_tx_meta_t& details) {}

Loading…
Cancel
Save