aboutsummaryrefslogtreecommitdiff
path: root/src/cryptonote_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/cryptonote_core')
-rw-r--r--src/cryptonote_core/blockchain.cpp65
-rw-r--r--src/cryptonote_core/blockchain.h4
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp21
-rw-r--r--src/cryptonote_core/cryptonote_tx_utils.h7
4 files changed, 88 insertions, 9 deletions
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index f5bd9bbb5..73c60760b 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -178,6 +178,7 @@ Blockchain::Blockchain(tx_memory_pool& tx_pool) :
m_enforce_dns_checkpoints(false), m_max_prepare_blocks_threads(4), m_db_sync_on_blocks(true), m_db_sync_threshold(1), m_db_sync_mode(db_async), m_db_default_sync(false), m_fast_sync(true), m_show_time_stats(false), m_sync_counter(0), m_bytes_to_sync(0), m_cancel(false),
m_long_term_block_weights_window(CRYPTONOTE_LONG_TERM_BLOCK_WEIGHT_WINDOW_SIZE),
m_long_term_effective_median_block_weight(0),
+ m_long_term_block_weights_cache_tip_hash(crypto::null_hash),
m_difficulty_for_next_block_top_hash(crypto::null_hash),
m_difficulty_for_next_block(1),
m_btc_valid(false)
@@ -645,6 +646,8 @@ block Blockchain::pop_block_from_blockchain()
block popped_block;
std::vector<transaction> popped_txs;
+ CHECK_AND_ASSERT_THROW_MES(m_db->height() > 1, "Cannot pop the genesis block");
+
try
{
m_db->pop_block(popped_block, popped_txs);
@@ -1279,7 +1282,50 @@ void Blockchain::get_long_term_block_weights(std::vector<uint64_t>& weights, uin
LOG_PRINT_L3("Blockchain::" << __func__);
CRITICAL_REGION_LOCAL(m_blockchain_lock);
+ PERF_TIMER(get_long_term_block_weights);
+
+ if (count == 0)
+ return;
+
+ bool cached = false;
+ uint64_t blockchain_height = m_db->height();
+ uint64_t tip_height = start_height + count - 1;
+ crypto::hash tip_hash = crypto::null_hash;
+ if (tip_height < blockchain_height && count == m_long_term_block_weights_cache.size())
+ {
+ tip_hash = m_db->get_block_hash_from_height(tip_height);
+ cached = tip_hash == m_long_term_block_weights_cache_tip_hash;
+ }
+
+ if (cached)
+ {
+ MTRACE("requesting " << count << " from " << start_height << ", cached");
+ weights = m_long_term_block_weights_cache;
+ return;
+ }
+
+ // in the vast majority of uncached cases, most is still cached,
+ // as we just move the window one block up:
+ if (tip_height > 0 && count == m_long_term_block_weights_cache.size() && tip_height < blockchain_height)
+ {
+ crypto::hash old_tip_hash = m_db->get_block_hash_from_height(tip_height - 1);
+ if (old_tip_hash == m_long_term_block_weights_cache_tip_hash)
+ {
+ weights = m_long_term_block_weights_cache;
+ for (size_t i = 1; i < weights.size(); ++i)
+ weights[i - 1] = weights[i];
+ MTRACE("requesting " << count << " from " << start_height << ", incremental");
+ weights.back() = m_db->get_block_long_term_weight(tip_height);
+ m_long_term_block_weights_cache = weights;
+ m_long_term_block_weights_cache_tip_hash = tip_hash;
+ return;
+ }
+ }
+
+ MTRACE("requesting " << count << " from " << start_height << ", uncached");
weights = m_db->get_long_term_block_weights(start_height, count);
+ m_long_term_block_weights_cache = weights;
+ m_long_term_block_weights_cache_tip_hash = tip_hash;
}
//------------------------------------------------------------------
uint64_t Blockchain::get_current_cumulative_block_weight_limit() const
@@ -1997,7 +2043,7 @@ bool Blockchain::find_blockchain_supplement(const std::list<crypto::hash>& qbloc
return true;
}
//------------------------------------------------------------------
-uint64_t Blockchain::block_difficulty(uint64_t i) const
+difficulty_type Blockchain::block_difficulty(uint64_t i) const
{
LOG_PRINT_L3("Blockchain::" << __func__);
// WARNING: this function does not take m_blockchain_lock, and thus should only call read only
@@ -2196,7 +2242,11 @@ bool Blockchain::find_blockchain_supplement(const std::list<crypto::hash>& qbloc
bool result = find_blockchain_supplement(qblock_ids, resp.m_block_ids, resp.start_height, resp.total_height);
if (result)
- resp.cumulative_difficulty = m_db->get_block_cumulative_difficulty(resp.total_height - 1);
+ {
+ cryptonote::difficulty_type wide_cumulative_difficulty = m_db->get_block_cumulative_difficulty(resp.total_height - 1);
+ resp.cumulative_difficulty = (wide_cumulative_difficulty << 64 >> 64).convert_to<uint64_t>();
+ resp.cumulative_difficulty_top64 = (wide_cumulative_difficulty >> 64).convert_to<uint64_t>();
+ }
return result;
}
@@ -3126,6 +3176,7 @@ bool Blockchain::check_fee(size_t tx_weight, uint64_t fee) const
if (version >= HF_VERSION_DYNAMIC_FEE)
{
median = m_current_block_cumul_weight_limit / 2;
+ const uint64_t blockchain_height = m_db->height();
already_generated_coins = blockchain_height ? m_db->get_block_already_generated_coins(blockchain_height - 1) : 0;
if (!get_block_reward(median, 1, already_generated_coins, base_reward, version))
return false;
@@ -4282,8 +4333,9 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector<block_complete
for (unsigned int j = 0; j < batches; j++, ++blockidx)
{
block &block = blocks[blockidx];
+ crypto::hash block_hash;
- if (!parse_and_validate_block_from_blob(it->block, block))
+ if (!parse_and_validate_block_from_blob(it->block, block, block_hash))
return false;
// check first block and skip all blocks if its not chained properly
@@ -4296,7 +4348,7 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector<block_complete
return true;
}
}
- if (have_block(get_block_hash(block)))
+ if (have_block(block_hash))
blocks_exist = true;
std::advance(it, 1);
@@ -4306,11 +4358,12 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector<block_complete
for (unsigned i = 0; i < extra && !blocks_exist; i++, blockidx++)
{
block &block = blocks[blockidx];
+ crypto::hash block_hash;
- if (!parse_and_validate_block_from_blob(it->block, block))
+ if (!parse_and_validate_block_from_blob(it->block, block, block_hash))
return false;
- if (have_block(get_block_hash(block)))
+ if (have_block(block_hash))
blocks_exist = true;
std::advance(it, 1);
diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h
index 3b8169764..2cd4dc31b 100644
--- a/src/cryptonote_core/blockchain.h
+++ b/src/cryptonote_core/blockchain.h
@@ -653,7 +653,7 @@ namespace cryptonote
*
* @return the difficulty
*/
- uint64_t block_difficulty(uint64_t i) const;
+ difficulty_type block_difficulty(uint64_t i) const;
/**
* @brief gets blocks based on a list of block hashes
@@ -1060,6 +1060,8 @@ namespace cryptonote
uint64_t m_timestamps_and_difficulties_height;
uint64_t m_long_term_block_weights_window;
uint64_t m_long_term_effective_median_block_weight;
+ mutable crypto::hash m_long_term_block_weights_cache_tip_hash;
+ mutable std::vector<uint64_t> m_long_term_block_weights_cache;
epee::critical_section m_difficulty_lock;
crypto::hash m_difficulty_for_next_block_top_hash;
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp
index 387203cc0..8ab7d174c 100644
--- a/src/cryptonote_core/cryptonote_core.cpp
+++ b/src/cryptonote_core/cryptonote_core.cpp
@@ -1432,7 +1432,8 @@ namespace cryptonote
block lb;
if (!b)
{
- if(!parse_and_validate_block_from_blob(block_blob, lb))
+ crypto::hash block_hash;
+ if(!parse_and_validate_block_from_blob(block_blob, lb, block_hash))
{
LOG_PRINT_L1("Failed to parse and validate new block");
bvc.m_verifivation_failed = true;
@@ -1784,12 +1785,28 @@ namespace cryptonote
return f;
}
//-----------------------------------------------------------------------------------------------
- static double probability(unsigned int blocks, unsigned int expected)
+ static double probability1(unsigned int blocks, unsigned int expected)
{
// https://www.umass.edu/wsp/resources/poisson/#computing
return pow(expected, blocks) / (factorial(blocks) * exp(expected));
}
//-----------------------------------------------------------------------------------------------
+ static double probability(unsigned int blocks, unsigned int expected)
+ {
+ double p = 0.0;
+ if (blocks <= expected)
+ {
+ for (unsigned int b = 0; b <= blocks; ++b)
+ p += probability1(b, expected);
+ }
+ else if (blocks > expected)
+ {
+ for (unsigned int b = blocks; b <= expected * 3 /* close enough */; ++b)
+ p += probability1(b, expected);
+ }
+ return p;
+ }
+ //-----------------------------------------------------------------------------------------------
bool core::check_block_rate()
{
if (m_offline || m_target_blockchain_height > get_current_blockchain_height())
diff --git a/src/cryptonote_core/cryptonote_tx_utils.h b/src/cryptonote_core/cryptonote_tx_utils.h
index cb1561c2d..d38aa7474 100644
--- a/src/cryptonote_core/cryptonote_tx_utils.h
+++ b/src/cryptonote_core/cryptonote_tx_utils.h
@@ -104,6 +104,13 @@ namespace cryptonote
std::vector<rct::key> &amount_keys,
crypto::public_key &out_eph_public_key) ;
+ bool generate_output_ephemeral_keys(const size_t tx_version, const cryptonote::account_keys &sender_account_keys, const crypto::public_key &txkey_pub, const crypto::secret_key &tx_key,
+ const cryptonote::tx_destination_entry &dst_entr, const boost::optional<cryptonote::account_public_address> &change_addr, const size_t output_index,
+ const bool &need_additional_txkeys, const std::vector<crypto::secret_key> &additional_tx_keys,
+ std::vector<crypto::public_key> &additional_tx_public_keys,
+ std::vector<rct::key> &amount_keys,
+ crypto::public_key &out_eph_public_key) ;
+
bool generate_genesis_block(
block& bl
, std::string const & genesis_tx