aboutsummaryrefslogtreecommitdiff
path: root/src/cryptonote_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/cryptonote_core')
-rw-r--r--src/cryptonote_core/blockchain.cpp261
-rw-r--r--src/cryptonote_core/blockchain.h48
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp15
-rw-r--r--src/cryptonote_core/cryptonote_core.h1
-rw-r--r--src/cryptonote_core/cryptonote_tx_utils.cpp2
-rw-r--r--src/cryptonote_core/tx_sanity_check.cpp2
6 files changed, 176 insertions, 153 deletions
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index ac2c07913..dab1a0a96 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -715,7 +715,6 @@ block Blockchain::pop_block_from_blockchain()
m_blocks_longhash_table.clear();
m_scan_table.clear();
m_blocks_txs_check.clear();
- m_check_txin_table.clear();
CHECK_AND_ASSERT_THROW_MES(update_next_cumulative_weight_limit(), "Error updating next cumulative weight limit");
uint64_t top_block_height;
@@ -731,9 +730,9 @@ bool Blockchain::reset_and_set_genesis_block(const block& b)
LOG_PRINT_L3("Blockchain::" << __func__);
CRITICAL_REGION_LOCAL(m_blockchain_lock);
m_timestamps_and_difficulties_height = 0;
- m_alternative_chains.clear();
invalidate_block_template_cache();
m_db->reset();
+ m_db->drop_alt_blocks();
m_hardfork->init();
db_wtxn_guard wtxn_guard(m_db);
@@ -858,10 +857,15 @@ bool Blockchain::get_block_by_hash(const crypto::hash &h, block &blk, bool *orph
// try to find block in alternative chain
catch (const BLOCK_DNE& e)
{
- blocks_ext_by_hash::const_iterator it_alt = m_alternative_chains.find(h);
- if (m_alternative_chains.end() != it_alt)
+ alt_block_data_t data;
+ cryptonote::blobdata blob;
+ if (m_db->get_alt_block(h, &data, &blob))
{
- blk = it_alt->second.bl;
+ if (!cryptonote::parse_and_validate_block_from_blob(blob, blk))
+ {
+ MERROR("Found block " << h << " in alt chain, but failed to parse it");
+ throw std::runtime_error("Found block in alt chain, but failed to parse it");
+ }
if (orphan)
*orphan = true;
return true;
@@ -1019,7 +1023,7 @@ bool Blockchain::rollback_blockchain_switching(std::list<block>& original_chain,
//------------------------------------------------------------------
// This function attempts to switch to an alternate chain, returning
// boolean based on success therein.
-bool Blockchain::switch_to_alternative_blockchain(std::list<blocks_ext_by_hash::const_iterator>& alt_chain, bool discard_disconnected_chain)
+bool Blockchain::switch_to_alternative_blockchain(std::list<block_extended_info>& alt_chain, bool discard_disconnected_chain)
{
LOG_PRINT_L3("Blockchain::" << __func__);
CRITICAL_REGION_LOCAL(m_blockchain_lock);
@@ -1030,7 +1034,7 @@ bool Blockchain::switch_to_alternative_blockchain(std::list<blocks_ext_by_hash::
CHECK_AND_ASSERT_MES(alt_chain.size(), false, "switch_to_alternative_blockchain: empty chain passed");
// verify that main chain has front of alt chain's parent block
- if (!m_db->block_exists(alt_chain.front()->second.bl.prev_id))
+ if (!m_db->block_exists(alt_chain.front().bl.prev_id))
{
LOG_ERROR("Attempting to move to an alternate chain, but it doesn't appear to connect to the main chain!");
return false;
@@ -1039,7 +1043,7 @@ bool Blockchain::switch_to_alternative_blockchain(std::list<blocks_ext_by_hash::
// pop blocks from the blockchain until the top block is the parent
// of the front block of the alt chain.
std::list<block> disconnected_chain;
- while (m_db->top_block_hash() != alt_chain.front()->second.bl.prev_id)
+ while (m_db->top_block_hash() != alt_chain.front().bl.prev_id)
{
block b = pop_block_from_blockchain();
disconnected_chain.push_front(b);
@@ -1050,11 +1054,11 @@ bool Blockchain::switch_to_alternative_blockchain(std::list<blocks_ext_by_hash::
//connecting new alternative chain
for(auto alt_ch_iter = alt_chain.begin(); alt_ch_iter != alt_chain.end(); alt_ch_iter++)
{
- auto ch_ent = *alt_ch_iter;
+ const auto &bei = *alt_ch_iter;
block_verification_context bvc = boost::value_initialized<block_verification_context>();
// add block to main chain
- bool r = handle_block_to_main_chain(ch_ent->second.bl, bvc);
+ bool r = handle_block_to_main_chain(bei.bl, bvc);
// if adding block to main chain failed, rollback to previous state and
// return false
@@ -1070,14 +1074,18 @@ bool Blockchain::switch_to_alternative_blockchain(std::list<blocks_ext_by_hash::
// FIXME: Why do we keep invalid blocks around? Possibly in case we hear
// about them again so we can immediately dismiss them, but needs some
// looking into.
- add_block_as_invalid(ch_ent->second, get_block_hash(ch_ent->second.bl));
- MERROR("The block was inserted as invalid while connecting new alternative chain, block_id: " << get_block_hash(ch_ent->second.bl));
- m_alternative_chains.erase(*alt_ch_iter++);
+ const crypto::hash blkid = cryptonote::get_block_hash(bei.bl);
+ add_block_as_invalid(bei, blkid);
+ MERROR("The block was inserted as invalid while connecting new alternative chain, block_id: " << blkid);
+ m_db->remove_alt_block(blkid);
+ alt_ch_iter++;
for(auto alt_ch_to_orph_iter = alt_ch_iter; alt_ch_to_orph_iter != alt_chain.end(); )
{
- add_block_as_invalid((*alt_ch_to_orph_iter)->second, (*alt_ch_to_orph_iter)->first);
- m_alternative_chains.erase(*alt_ch_to_orph_iter++);
+ const auto &bei = *alt_ch_to_orph_iter++;
+ const crypto::hash blkid = cryptonote::get_block_hash(bei.bl);
+ add_block_as_invalid(bei, blkid);
+ m_db->remove_alt_block(blkid);
}
return false;
}
@@ -1102,9 +1110,9 @@ bool Blockchain::switch_to_alternative_blockchain(std::list<blocks_ext_by_hash::
}
//removing alt_chain entries from alternative chains container
- for (auto ch_ent: alt_chain)
+ for (const auto &bei: alt_chain)
{
- m_alternative_chains.erase(ch_ent);
+ m_db->remove_alt_block(cryptonote::get_block_hash(bei.bl));
}
m_hardfork->reorganize_from_chain_height(split_height);
@@ -1120,7 +1128,7 @@ bool Blockchain::switch_to_alternative_blockchain(std::list<blocks_ext_by_hash::
//------------------------------------------------------------------
// This function calculates the difficulty target for the block being added to
// an alternate chain.
-difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std::list<blocks_ext_by_hash::const_iterator>& alt_chain, block_extended_info& bei) const
+difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std::list<block_extended_info>& alt_chain, block_extended_info& bei) const
{
if (m_fixed_difficulty)
{
@@ -1138,7 +1146,7 @@ difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std:
CRITICAL_REGION_LOCAL(m_blockchain_lock);
// Figure out start and stop offsets for main chain blocks
- size_t main_chain_stop_offset = alt_chain.size() ? alt_chain.front()->second.height : bei.height;
+ size_t main_chain_stop_offset = alt_chain.size() ? alt_chain.front().height : bei.height;
size_t main_chain_count = DIFFICULTY_BLOCKS_COUNT - std::min(static_cast<size_t>(DIFFICULTY_BLOCKS_COUNT), alt_chain.size());
main_chain_count = std::min(main_chain_count, main_chain_stop_offset);
size_t main_chain_start_offset = main_chain_stop_offset - main_chain_count;
@@ -1156,10 +1164,10 @@ difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std:
// make sure we haven't accidentally grabbed too many blocks...maybe don't need this check?
CHECK_AND_ASSERT_MES((alt_chain.size() + timestamps.size()) <= DIFFICULTY_BLOCKS_COUNT, false, "Internal error, alt_chain.size()[" << alt_chain.size() << "] + vtimestampsec.size()[" << timestamps.size() << "] NOT <= DIFFICULTY_WINDOW[]" << DIFFICULTY_BLOCKS_COUNT);
- for (auto it : alt_chain)
+ for (const auto &bei : alt_chain)
{
- timestamps.push_back(it->second.bl.timestamp);
- cumulative_difficulties.push_back(it->second.cumulative_difficulty);
+ timestamps.push_back(bei.bl.timestamp);
+ cumulative_difficulties.push_back(bei.cumulative_difficulty);
}
}
// if the alt chain is long enough for the difficulty calc, grab difficulties
@@ -1171,10 +1179,10 @@ difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std:
size_t count = 0;
size_t max_i = timestamps.size()-1;
// get difficulties and timestamps from most recent blocks in alt chain
- for(auto it: boost::adaptors::reverse(alt_chain))
+ for (const auto bei: boost::adaptors::reverse(alt_chain))
{
- timestamps[max_i - count] = it->second.bl.timestamp;
- cumulative_difficulties[max_i - count] = it->second.cumulative_difficulty;
+ timestamps[max_i - count] = bei.bl.timestamp;
+ cumulative_difficulties[max_i - count] = bei.cumulative_difficulty;
count++;
if(count >= DIFFICULTY_BLOCKS_COUNT)
break;
@@ -1393,16 +1401,17 @@ bool Blockchain::create_block_template(block& b, const crypto::hash *from_block,
//build alternative subchain, front -> mainchain, back -> alternative head
//block is not related with head of main chain
//first of all - look in alternative chains container
- auto it_prev = m_alternative_chains.find(*from_block);
+ alt_block_data_t prev_data;
+ bool parent_in_alt = m_db->get_alt_block(*from_block, &prev_data, NULL);
bool parent_in_main = m_db->block_exists(*from_block);
- if(it_prev == m_alternative_chains.end() && !parent_in_main)
+ if (!parent_in_alt && !parent_in_main)
{
MERROR("Unknown from block");
return false;
}
//we have new block in alternative chain
- std::list<blocks_ext_by_hash::const_iterator> alt_chain;
+ std::list<block_extended_info> alt_chain;
block_verification_context bvc = boost::value_initialized<block_verification_context>();
std::vector<uint64_t> timestamps;
if (!build_alt_chain(*from_block, alt_chain, timestamps, bvc))
@@ -1417,7 +1426,7 @@ bool Blockchain::create_block_template(block& b, const crypto::hash *from_block,
}
else
{
- height = alt_chain.back()->second.height + 1;
+ height = alt_chain.back().height + 1;
}
b.major_version = m_hardfork->get_ideal_version(height);
b.minor_version = m_hardfork->get_ideal_version();
@@ -1432,14 +1441,14 @@ bool Blockchain::create_block_template(block& b, const crypto::hash *from_block,
}
else
{
- median_weight = it_prev->second.block_cumulative_weight - it_prev->second.block_cumulative_weight / 20;
- already_generated_coins = alt_chain.back()->second.already_generated_coins;
+ median_weight = prev_data.cumulative_weight - prev_data.cumulative_weight / 20;
+ already_generated_coins = alt_chain.back().already_generated_coins;
}
// FIXME: consider moving away from block_extended_info at some point
block_extended_info bei = boost::value_initialized<block_extended_info>();
bei.bl = b;
- bei.height = alt_chain.size() ? it_prev->second.height + 1 : m_db->get_block_height(*from_block) + 1;
+ bei.height = alt_chain.size() ? prev_data.height + 1 : m_db->get_block_height(*from_block) + 1;
diffic = get_next_difficulty_for_alternative_chain(alt_chain, bei);
}
@@ -1618,16 +1627,25 @@ bool Blockchain::complete_timestamps_vector(uint64_t start_top_height, std::vect
return true;
}
//------------------------------------------------------------------
-bool Blockchain::build_alt_chain(const crypto::hash &prev_id, std::list<blocks_ext_by_hash::const_iterator>& alt_chain, std::vector<uint64_t> &timestamps, block_verification_context& bvc) const
+bool Blockchain::build_alt_chain(const crypto::hash &prev_id, std::list<block_extended_info>& alt_chain, std::vector<uint64_t> &timestamps, block_verification_context& bvc) const
{
//build alternative subchain, front -> mainchain, back -> alternative head
- blocks_ext_by_hash::const_iterator alt_it = m_alternative_chains.find(prev_id);
+ cryptonote::alt_block_data_t data;
+ cryptonote::blobdata blob;
+ bool found = m_db->get_alt_block(prev_id, &data, &blob);
timestamps.clear();
- while(alt_it != m_alternative_chains.end())
+ while(found)
{
- alt_chain.push_front(alt_it);
- timestamps.push_back(alt_it->second.bl.timestamp);
- alt_it = m_alternative_chains.find(alt_it->second.bl.prev_id);
+ block_extended_info bei;
+ CHECK_AND_ASSERT_MES(cryptonote::parse_and_validate_block_from_blob(blob, bei.bl), false, "Failed to parse alt block");
+ bei.height = data.height;
+ bei.block_cumulative_weight = data.cumulative_weight;
+ bei.cumulative_difficulty = data.cumulative_difficulty_high;
+ bei.cumulative_difficulty = (bei.cumulative_difficulty << 64) + data.cumulative_difficulty_low;
+ bei.already_generated_coins = data.already_generated_coins;
+ timestamps.push_back(bei.bl.timestamp);
+ alt_chain.push_front(std::move(bei));
+ found = m_db->get_alt_block(bei.bl.prev_id, &data, &blob);
}
// if block to be added connects to known blocks that aren't part of the
@@ -1635,20 +1653,20 @@ bool Blockchain::build_alt_chain(const crypto::hash &prev_id, std::list<blocks_e
if(!alt_chain.empty())
{
// make sure alt chain doesn't somehow start past the end of the main chain
- CHECK_AND_ASSERT_MES(m_db->height() > alt_chain.front()->second.height, false, "main blockchain wrong height");
+ CHECK_AND_ASSERT_MES(m_db->height() > alt_chain.front().height, false, "main blockchain wrong height");
// make sure that the blockchain contains the block that should connect
// this alternate chain with it.
- if (!m_db->block_exists(alt_chain.front()->second.bl.prev_id))
+ if (!m_db->block_exists(alt_chain.front().bl.prev_id))
{
MERROR("alternate chain does not appear to connect to main chain...");
return false;
}
// make sure block connects correctly to the main chain
- auto h = m_db->get_block_hash_from_height(alt_chain.front()->second.height - 1);
- CHECK_AND_ASSERT_MES(h == alt_chain.front()->second.bl.prev_id, false, "alternative chain has wrong connection to main chain");
- complete_timestamps_vector(m_db->get_block_height(alt_chain.front()->second.bl.prev_id), timestamps);
+ auto h = m_db->get_block_hash_from_height(alt_chain.front().height - 1);
+ CHECK_AND_ASSERT_MES(h == alt_chain.front().bl.prev_id, false, "alternative chain has wrong connection to main chain");
+ complete_timestamps_vector(m_db->get_block_height(alt_chain.front().bl.prev_id), timestamps);
}
// if block not associated with known alternate chain
else
@@ -1703,12 +1721,13 @@ bool Blockchain::handle_alternative_block(const block& b, const crypto::hash& id
//block is not related with head of main chain
//first of all - look in alternative chains container
- auto it_prev = m_alternative_chains.find(b.prev_id);
+ alt_block_data_t prev_data;
+ bool parent_in_alt = m_db->get_alt_block(b.prev_id, &prev_data, NULL);
bool parent_in_main = m_db->block_exists(b.prev_id);
- if(it_prev != m_alternative_chains.end() || parent_in_main)
+ if (parent_in_alt || parent_in_main)
{
//we have new block in alternative chain
- std::list<blocks_ext_by_hash::const_iterator> alt_chain;
+ std::list<block_extended_info> alt_chain;
std::vector<uint64_t> timestamps;
if (!build_alt_chain(b.prev_id, alt_chain, timestamps, bvc))
return false;
@@ -1716,10 +1735,10 @@ bool Blockchain::handle_alternative_block(const block& b, const crypto::hash& id
// FIXME: consider moving away from block_extended_info at some point
block_extended_info bei = boost::value_initialized<block_extended_info>();
bei.bl = b;
- const uint64_t prev_height = alt_chain.size() ? it_prev->second.height : m_db->get_block_height(b.prev_id);
+ const uint64_t prev_height = alt_chain.size() ? prev_data.height : m_db->get_block_height(b.prev_id);
bei.height = prev_height + 1;
uint64_t block_reward = get_outs_money_amount(b.miner_tx);
- bei.already_generated_coins = block_reward + (alt_chain.size() ? it_prev->second.already_generated_coins : m_db->get_block_already_generated_coins(prev_height));
+ bei.already_generated_coins = block_reward + (alt_chain.size() ? prev_data.already_generated_coins : m_db->get_block_already_generated_coins(prev_height));
// verify that the block's timestamp is within the acceptable range
// (not earlier than the median of the last X blocks)
@@ -1763,7 +1782,8 @@ bool Blockchain::handle_alternative_block(const block& b, const crypto::hash& id
difficulty_type main_chain_cumulative_difficulty = m_db->get_block_cumulative_difficulty(m_db->height() - 1);
if (alt_chain.size())
{
- bei.cumulative_difficulty = it_prev->second.cumulative_difficulty;
+ bei.cumulative_difficulty = prev_data.cumulative_difficulty_high;
+ bei.cumulative_difficulty = (bei.cumulative_difficulty << 64) + prev_data.cumulative_difficulty_low;
}
else
{
@@ -1774,15 +1794,21 @@ bool Blockchain::handle_alternative_block(const block& b, const crypto::hash& id
// add block to alternate blocks storage,
// as well as the current "alt chain" container
- auto i_res = m_alternative_chains.insert(blocks_ext_by_hash::value_type(id, bei));
- CHECK_AND_ASSERT_MES(i_res.second, false, "insertion of new alternative block returned as it already exist");
- alt_chain.push_back(i_res.first);
+ CHECK_AND_ASSERT_MES(!m_db->get_alt_block(id, NULL, NULL), false, "insertion of new alternative block returned as it already exists");
+ cryptonote::alt_block_data_t data;
+ data.height = bei.height;
+ data.cumulative_weight = bei.block_cumulative_weight;
+ data.cumulative_difficulty_low = (bei.cumulative_difficulty & 0xffffffffffffffff).convert_to<uint64_t>();
+ data.cumulative_difficulty_high = ((bei.cumulative_difficulty >> 64) & 0xffffffffffffffff).convert_to<uint64_t>();
+ data.already_generated_coins = bei.already_generated_coins;
+ m_db->add_alt_block(id, data, cryptonote::block_to_blob(bei.bl));
+ alt_chain.push_back(bei);
// FIXME: is it even possible for a checkpoint to show up not on the main chain?
if(is_a_checkpoint)
{
//do reorganize!
- MGINFO_GREEN("###### REORGANIZE on height: " << alt_chain.front()->second.height << " of " << m_db->height() - 1 << ", checkpoint is found in alternative chain on height " << bei.height);
+ MGINFO_GREEN("###### REORGANIZE on height: " << alt_chain.front().height << " of " << m_db->height() - 1 << ", checkpoint is found in alternative chain on height " << bei.height);
bool r = switch_to_alternative_blockchain(alt_chain, true);
@@ -1794,7 +1820,7 @@ bool Blockchain::handle_alternative_block(const block& b, const crypto::hash& id
else if(main_chain_cumulative_difficulty < bei.cumulative_difficulty) //check if difficulty bigger then in main chain
{
//do reorganize!
- MGINFO_GREEN("###### REORGANIZE on height: " << alt_chain.front()->second.height << " of " << m_db->height() - 1 << " with cum_difficulty " << m_db->get_block_cumulative_difficulty(m_db->height() - 1) << std::endl << " alternative blockchain size: " << alt_chain.size() << " with cum_difficulty " << bei.cumulative_difficulty);
+ MGINFO_GREEN("###### REORGANIZE on height: " << alt_chain.front().height << " of " << m_db->height() - 1 << " with cum_difficulty " << m_db->get_block_cumulative_difficulty(m_db->height() - 1) << std::endl << " alternative blockchain size: " << alt_chain.size() << " with cum_difficulty " << bei.cumulative_difficulty);
bool r = switch_to_alternative_blockchain(alt_chain, false);
if (r)
@@ -1814,7 +1840,7 @@ bool Blockchain::handle_alternative_block(const block& b, const crypto::hash& id
//block orphaned
bvc.m_marked_as_orphaned = true;
MERROR_VER("Block recognized as orphaned and rejected, id = " << id << ", height " << block_height
- << ", parent in alt " << (it_prev != m_alternative_chains.end()) << ", parent in main " << parent_in_main
+ << ", parent in alt " << parent_in_alt << ", parent in main " << parent_in_main
<< " (parent " << b.prev_id << ", current top " << get_tail_id() << ", chain height " << get_current_blockchain_height() << ")");
}
@@ -1912,8 +1938,6 @@ bool Blockchain::handle_get_objects(NOTIFY_REQUEST_GET_OBJECTS::request& arg, NO
//pack block
e.block = std::move(bl.first);
}
- //get and pack other transactions, if needed
- get_transactions_blobs(arg.txs, rsp.txs, rsp.missed_ids);
return true;
}
@@ -1923,11 +1947,20 @@ bool Blockchain::get_alternative_blocks(std::vector<block>& blocks) const
LOG_PRINT_L3("Blockchain::" << __func__);
CRITICAL_REGION_LOCAL(m_blockchain_lock);
- blocks.reserve(m_alternative_chains.size());
- for (const auto& alt_bl: m_alternative_chains)
- {
- blocks.push_back(alt_bl.second.bl);
- }
+ blocks.reserve(m_db->get_alt_block_count());
+ m_db->for_all_alt_blocks([&blocks](const crypto::hash &blkid, const cryptonote::alt_block_data_t &data, const cryptonote::blobdata *blob) {
+ if (!blob)
+ {
+ MERROR("No blob, but blobs were requested");
+ return false;
+ }
+ cryptonote::block bl;
+ if (cryptonote::parse_and_validate_block_from_blob(*blob, bl))
+ blocks.push_back(std::move(bl));
+ else
+ MERROR("Failed to parse block from blob");
+ return true;
+ }, true);
return true;
}
//------------------------------------------------------------------
@@ -1935,7 +1968,7 @@ size_t Blockchain::get_alternative_blocks_count() const
{
LOG_PRINT_L3("Blockchain::" << __func__);
CRITICAL_REGION_LOCAL(m_blockchain_lock);
- return m_alternative_chains.size();
+ return m_db->get_alt_block_count();
}
//------------------------------------------------------------------
// This function adds the output specified by <amount, i> to the result_outs container
@@ -2039,7 +2072,6 @@ bool Blockchain::get_output_distribution(uint64_t amount, uint64_t from_height,
if (to_height > 0 && to_height < from_height)
return false;
- const uint64_t real_start_height = start_height;
if (from_height > start_height)
start_height = from_height;
@@ -2053,7 +2085,7 @@ bool Blockchain::get_output_distribution(uint64_t amount, uint64_t from_height,
{
std::vector<uint64_t> heights;
heights.reserve(to_height + 1 - start_height);
- uint64_t real_start_height = start_height > 0 ? start_height-1 : start_height;
+ const uint64_t real_start_height = start_height > 0 ? start_height-1 : start_height;
for (uint64_t h = real_start_height; h <= to_height; ++h)
heights.push_back(h);
distribution = m_db->get_block_cumulative_rct_outputs(heights);
@@ -2423,9 +2455,9 @@ bool Blockchain::have_block(const crypto::hash& id) const
return true;
}
- if(m_alternative_chains.count(id))
+ if(m_db->get_alt_block(id, NULL, NULL))
{
- LOG_PRINT_L2("block " << id << " found in m_alternative_chains");
+ LOG_PRINT_L2("block " << id << " found in alternative chains");
return true;
}
@@ -2579,7 +2611,7 @@ void Blockchain::on_new_tx_from_block(const cryptonote::transaction &tx)
// This function overloads its sister function with
// an extra value (hash of highest block that holds an output used as input)
// as a return-by-reference.
-bool Blockchain::check_tx_inputs(transaction& tx, uint64_t& max_used_block_height, crypto::hash& max_used_block_id, tx_verification_context &tvc, bool kept_by_block)
+bool Blockchain::check_tx_inputs(transaction& tx, uint64_t& max_used_block_height, crypto::hash& max_used_block_id, tx_verification_context &tvc, bool kept_by_block) const
{
LOG_PRINT_L3("Blockchain::" << __func__);
CRITICAL_REGION_LOCAL(m_blockchain_lock);
@@ -2610,7 +2642,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, uint64_t& max_used_block_heigh
return true;
}
//------------------------------------------------------------------
-bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context &tvc)
+bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context &tvc) const
{
LOG_PRINT_L3("Blockchain::" << __func__);
CRITICAL_REGION_LOCAL(m_blockchain_lock);
@@ -2719,7 +2751,7 @@ bool Blockchain::have_tx_keyimges_as_spent(const transaction &tx) const
}
return false;
}
-bool Blockchain::expand_transaction_2(transaction &tx, const crypto::hash &tx_prefix_hash, const std::vector<std::vector<rct::ctkey>> &pubkeys)
+bool Blockchain::expand_transaction_2(transaction &tx, const crypto::hash &tx_prefix_hash, const std::vector<std::vector<rct::ctkey>> &pubkeys) const
{
PERF_TIMER(expand_transaction_2);
CHECK_AND_ASSERT_MES(tx.version == 2, false, "Transaction version is not 2");
@@ -2795,7 +2827,7 @@ bool Blockchain::expand_transaction_2(transaction &tx, const crypto::hash &tx_pr
// check_tx_input() rather than here, and use this function simply
// to iterate the inputs as necessary (splitting the task
// using threads, etc.)
-bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc, uint64_t* pmax_used_block_height)
+bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc, uint64_t* pmax_used_block_height) const
{
PERF_TIMER(check_tx_inputs);
LOG_PRINT_L3("Blockchain::" << __func__);
@@ -2807,6 +2839,19 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
const uint8_t hf_version = m_hardfork->get_current_version();
+ if (hf_version >= HF_VERSION_MIN_2_OUTPUTS)
+ {
+ if (tx.version >= 2)
+ {
+ if (tx.vout.size() < 2)
+ {
+ MERROR_VER("Tx " << get_transaction_hash(tx) << " has fewer than two outputs");
+ tvc.m_too_few_outputs = true;
+ return false;
+ }
+ }
+ }
+
// from hard fork 2, we require mixin at least 2 unless one output cannot mix with 2 others
// if one output cannot mix with 2 others, we accept at most 1 output that can mix
if (hf_version >= 2)
@@ -2901,13 +2946,6 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
}
}
}
- auto it = m_check_txin_table.find(tx_prefix_hash);
- if(it == m_check_txin_table.end())
- {
- m_check_txin_table.emplace(tx_prefix_hash, std::unordered_map<crypto::key_image, bool>());
- it = m_check_txin_table.find(tx_prefix_hash);
- assert(it != m_check_txin_table.end());
- }
std::vector<std::vector<rct::ctkey>> pubkeys(tx.vin.size());
std::vector < uint64_t > results;
@@ -2939,29 +2977,12 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
{
// basically, make sure number of inputs == number of signatures
CHECK_AND_ASSERT_MES(sig_index < tx.signatures.size(), false, "wrong transaction: not signature entry for input with index= " << sig_index);
-
-#if defined(CACHE_VIN_RESULTS)
- auto itk = it->second.find(in_to_key.k_image);
- if(itk != it->second.end())
- {
- if(!itk->second)
- {
- MERROR_VER("Failed ring signature for tx " << get_transaction_hash(tx) << " vin key with k_image: " << in_to_key.k_image << " sig_index: " << sig_index);
- return false;
- }
-
- // txin has been verified already, skip
- sig_index++;
- continue;
- }
-#endif
}
// make sure that output being spent matches up correctly with the
// signature spending it.
if (!check_tx_input(tx.version, in_to_key, tx_prefix_hash, tx.version == 1 ? tx.signatures[sig_index] : std::vector<crypto::signature>(), tx.rct_signatures, pubkeys[sig_index], pmax_used_block_height))
{
- it->second[in_to_key.k_image] = false;
MERROR_VER("Failed to check ring signature for tx " << get_transaction_hash(tx) << " vin key with k_image: " << in_to_key.k_image << " sig_index: " << sig_index);
if (pmax_used_block_height) // a default value of NULL is used when called from Blockchain::handle_block_to_main_chain()
{
@@ -2984,7 +3005,6 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
check_ring_signature(tx_prefix_hash, in_to_key.k_image, pubkeys[sig_index], tx.signatures[sig_index], results[sig_index]);
if (!results[sig_index])
{
- it->second[in_to_key.k_image] = false;
MERROR_VER("Failed to check ring signature for tx " << get_transaction_hash(tx) << " vin key with k_image: " << in_to_key.k_image << " sig_index: " << sig_index);
if (pmax_used_block_height) // a default value of NULL is used when called from Blockchain::handle_block_to_main_chain()
@@ -2994,7 +3014,6 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
return false;
}
- it->second[in_to_key.k_image] = true;
}
}
@@ -3012,7 +3031,6 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
for (size_t i = 0; i < tx.vin.size(); i++)
{
const txin_to_key& in_to_key = boost::get<txin_to_key>(tx.vin[i]);
- it->second[in_to_key.k_image] = results[i];
if(!failed && !results[i])
failed = true;
}
@@ -3186,7 +3204,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
}
//------------------------------------------------------------------
-void Blockchain::check_ring_signature(const crypto::hash &tx_prefix_hash, const crypto::key_image &key_image, const std::vector<rct::ctkey> &pubkeys, const std::vector<crypto::signature>& sig, uint64_t &result)
+void Blockchain::check_ring_signature(const crypto::hash &tx_prefix_hash, const crypto::key_image &key_image, const std::vector<rct::ctkey> &pubkeys, const std::vector<crypto::signature>& sig, uint64_t &result) const
{
std::vector<const crypto::public_key *> p_output_keys;
p_output_keys.reserve(pubkeys.size());
@@ -3254,7 +3272,6 @@ uint64_t Blockchain::get_dynamic_base_fee(uint64_t block_reward, size_t median_b
bool Blockchain::check_fee(size_t tx_weight, uint64_t fee) const
{
const uint8_t version = get_current_hard_fork_version();
- const uint64_t blockchain_height = m_db->height();
uint64_t median = 0;
uint64_t already_generated_coins = 0;
@@ -3373,7 +3390,7 @@ bool Blockchain::is_tx_spendtime_unlocked(uint64_t unlock_time) const
// This function locates all outputs associated with a given input (mixins)
// and validates that they exist and are usable. It also checks the ring
// signature for each input.
-bool Blockchain::check_tx_input(size_t tx_version, const txin_to_key& txin, const crypto::hash& tx_prefix_hash, const std::vector<crypto::signature>& sig, const rct::rctSig &rct_signatures, std::vector<rct::ctkey> &output_keys, uint64_t* pmax_related_block_height)
+bool Blockchain::check_tx_input(size_t tx_version, const txin_to_key& txin, const crypto::hash& tx_prefix_hash, const std::vector<crypto::signature>& sig, const rct::rctSig &rct_signatures, std::vector<rct::ctkey> &output_keys, uint64_t* pmax_related_block_height) const
{
LOG_PRINT_L3("Blockchain::" << __func__);
@@ -3962,14 +3979,12 @@ bool Blockchain::update_next_cumulative_weight_limit(uint64_t *long_term_effecti
const uint64_t db_height = m_db->height();
const uint8_t hf_version = get_current_hard_fork_version();
uint64_t full_reward_zone = get_min_block_weight(hf_version);
- uint64_t long_term_block_weight;
if (hf_version < HF_VERSION_LONG_TERM_BLOCK_WEIGHT)
{
std::vector<uint64_t> weights;
get_last_n_blocks_weights(weights, CRYPTONOTE_REWARD_BLOCKS_WINDOW);
m_current_block_cumul_weight_median = epee::misc_utils::median(weights);
- long_term_block_weight = weights.back();
}
else
{
@@ -3991,7 +4006,7 @@ bool Blockchain::update_next_cumulative_weight_limit(uint64_t *long_term_effecti
m_long_term_effective_median_block_weight = std::max<uint64_t>(CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V5, long_term_median);
uint64_t short_term_constraint = m_long_term_effective_median_block_weight + m_long_term_effective_median_block_weight * 2 / 5;
- long_term_block_weight = std::min<uint64_t>(block_weight, short_term_constraint);
+ uint64_t long_term_block_weight = std::min<uint64_t>(block_weight, short_term_constraint);
if (db_height == 1)
{
@@ -4212,7 +4227,6 @@ bool Blockchain::cleanup_handle_incoming_blocks(bool force_sync)
m_blocks_longhash_table.clear();
m_scan_table.clear();
m_blocks_txs_check.clear();
- m_check_txin_table.clear();
// when we're well clear of the precomputed hashes, free the memory
if (!m_blocks_hash_check.empty() && m_db->height() > m_blocks_hash_check.size() + 4096)
@@ -4501,7 +4515,6 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector<block_complete
m_fake_pow_calc_time = 0;
m_scan_table.clear();
- m_check_txin_table.clear();
TIME_MEASURE_FINISH(prepare);
m_fake_pow_calc_time = prepare / blocks_entry.size();
@@ -4810,15 +4823,39 @@ std::map<uint64_t, std::tuple<uint64_t, uint64_t, uint64_t>> Blockchain:: get_ou
return m_db->get_output_histogram(amounts, unlocked, recent_cutoff, min_count);
}
-std::list<std::pair<Blockchain::block_extended_info,std::vector<crypto::hash>>> Blockchain::get_alternative_chains() const
+std::vector<std::pair<Blockchain::block_extended_info,std::vector<crypto::hash>>> Blockchain::get_alternative_chains() const
{
- std::list<std::pair<Blockchain::block_extended_info,std::vector<crypto::hash>>> chains;
+ std::vector<std::pair<Blockchain::block_extended_info,std::vector<crypto::hash>>> chains;
+
+ blocks_ext_by_hash alt_blocks;
+ alt_blocks.reserve(m_db->get_alt_block_count());
+ m_db->for_all_alt_blocks([&alt_blocks](const crypto::hash &blkid, const cryptonote::alt_block_data_t &data, const cryptonote::blobdata *blob) {
+ if (!blob)
+ {
+ MERROR("No blob, but blobs were requested");
+ return false;
+ }
+ cryptonote::block bl;
+ block_extended_info bei;
+ if (cryptonote::parse_and_validate_block_from_blob(*blob, bei.bl))
+ {
+ bei.height = data.height;
+ bei.block_cumulative_weight = data.cumulative_weight;
+ bei.cumulative_difficulty = data.cumulative_difficulty_high;
+ bei.cumulative_difficulty = (bei.cumulative_difficulty << 64) + data.cumulative_difficulty_low;
+ bei.already_generated_coins = data.already_generated_coins;
+ alt_blocks.insert(std::make_pair(cryptonote::get_block_hash(bei.bl), std::move(bei)));
+ }
+ else
+ MERROR("Failed to parse block from blob");
+ return true;
+ }, true);
- for (const auto &i: m_alternative_chains)
+ for (const auto &i: alt_blocks)
{
- const crypto::hash &top = i.first;
+ const crypto::hash top = cryptonote::get_block_hash(i.second.bl);
bool found = false;
- for (const auto &j: m_alternative_chains)
+ for (const auto &j: alt_blocks)
{
if (j.second.bl.prev_id == top)
{
@@ -4832,7 +4869,7 @@ std::list<std::pair<Blockchain::block_extended_info,std::vector<crypto::hash>>>
auto h = i.second.bl.prev_id;
chain.push_back(top);
blocks_ext_by_hash::const_iterator prev;
- while ((prev = m_alternative_chains.find(h)) != m_alternative_chains.end())
+ while ((prev = alt_blocks.find(h)) != alt_blocks.end())
{
chain.push_back(h);
h = prev->second.bl.prev_id;
diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h
index 32ed96b5b..f58059a6d 100644
--- a/src/cryptonote_core/blockchain.h
+++ b/src/cryptonote_core/blockchain.h
@@ -92,24 +92,13 @@ namespace cryptonote
{
public:
/**
- * @brief Now-defunct (TODO: remove) struct from in-memory blockchain
- */
- struct transaction_chain_entry
- {
- transaction tx;
- uint64_t m_keeper_block_height;
- size_t m_blob_size;
- std::vector<uint64_t> m_global_output_indexes;
- };
-
- /**
* @brief container for passing a block and metadata about it on the blockchain
*/
struct block_extended_info
{
block bl; //!< the block
uint64_t height; //!< the height of the block in the blockchain
- size_t block_cumulative_weight; //!< the weight of the block
+ uint64_t block_cumulative_weight; //!< the weight of the block
difficulty_type cumulative_difficulty; //!< the accumulated difficulty after that block
uint64_t already_generated_coins; //!< the total coins minted after that block
};
@@ -559,7 +548,7 @@ namespace cryptonote
*
* @return false if any input is invalid, otherwise true
*/
- bool check_tx_inputs(transaction& tx, uint64_t& pmax_used_block_height, crypto::hash& max_used_block_id, tx_verification_context &tvc, bool kept_by_block = false);
+ bool check_tx_inputs(transaction& tx, uint64_t& pmax_used_block_height, crypto::hash& max_used_block_id, tx_verification_context &tvc, bool kept_by_block = false) const;
/**
* @brief get fee quantization mask
@@ -626,7 +615,7 @@ namespace cryptonote
*
* @return false if any outputs do not conform, otherwise true
*/
- bool check_tx_outputs(const transaction& tx, tx_verification_context &tvc);
+ bool check_tx_outputs(const transaction& tx, tx_verification_context &tvc) const;
/**
* @brief gets the block weight limit based on recent blocks
@@ -961,9 +950,9 @@ namespace cryptonote
/**
* @brief returns a set of known alternate chains
*
- * @return a list of chains
+ * @return a vector of chains
*/
- std::list<std::pair<block_extended_info,std::vector<crypto::hash>>> get_alternative_chains() const;
+ std::vector<std::pair<block_extended_info,std::vector<crypto::hash>>> get_alternative_chains() const;
void add_txpool_tx(const crypto::hash &txid, const cryptonote::blobdata &blob, const txpool_tx_meta_t &meta);
void update_txpool_tx(const crypto::hash &txid, const txpool_tx_meta_t &meta);
@@ -1011,20 +1000,12 @@ namespace cryptonote
#endif
// TODO: evaluate whether or not each of these typedefs are left over from blockchain_storage
- typedef std::unordered_map<crypto::hash, size_t> blocks_by_id_index;
-
- typedef std::unordered_map<crypto::hash, transaction_chain_entry> transactions_container;
-
typedef std::unordered_set<crypto::key_image> key_images_container;
typedef std::vector<block_extended_info> blocks_container;
typedef std::unordered_map<crypto::hash, block_extended_info> blocks_ext_by_hash;
- typedef std::unordered_map<crypto::hash, block> blocks_by_hash;
-
- typedef std::map<uint64_t, std::vector<std::pair<crypto::hash, size_t>>> outputs_container; //crypto::hash - tx hash, size_t - index of out in transaction
-
BlockchainDB* m_db;
@@ -1033,14 +1014,12 @@ namespace cryptonote
mutable epee::critical_section m_blockchain_lock; // TODO: add here reader/writer lock
// main chain
- transactions_container m_transactions;
size_t m_current_block_cumul_weight_limit;
size_t m_current_block_cumul_weight_median;
// metadata containers
std::unordered_map<crypto::hash, std::unordered_map<crypto::key_image, std::vector<output_data_t>>> m_scan_table;
std::unordered_map<crypto::hash, crypto::hash> m_blocks_longhash_table;
- std::unordered_map<crypto::hash, std::unordered_map<crypto::key_image, bool>> m_check_txin_table;
// SHA-3 hashes for each block and for fast pow checking
std::vector<crypto::hash> m_blocks_hash_of_hashes;
@@ -1074,9 +1053,6 @@ namespace cryptonote
boost::thread_group m_async_pool;
std::unique_ptr<boost::asio::io_service::work> m_async_work_idle;
- // all alternative chains
- blocks_ext_by_hash m_alternative_chains; // crypto::hash -> block_extended_info
-
// some invalid blocks
blocks_ext_by_hash m_invalid_blocks; // crypto::hash -> block_extended_info
@@ -1150,7 +1126,7 @@ namespace cryptonote
*
* @return false if any output is not yet unlocked, or is missing, otherwise true
*/
- bool check_tx_input(size_t tx_version,const txin_to_key& txin, const crypto::hash& tx_prefix_hash, const std::vector<crypto::signature>& sig, const rct::rctSig &rct_signatures, std::vector<rct::ctkey> &output_keys, uint64_t* pmax_related_block_height);
+ bool check_tx_input(size_t tx_version,const txin_to_key& txin, const crypto::hash& tx_prefix_hash, const std::vector<crypto::signature>& sig, const rct::rctSig &rct_signatures, std::vector<rct::ctkey> &output_keys, uint64_t* pmax_related_block_height) const;
/**
* @brief validate a transaction's inputs and their keys
@@ -1172,7 +1148,7 @@ namespace cryptonote
*
* @return false if any validation step fails, otherwise true
*/
- bool check_tx_inputs(transaction& tx, tx_verification_context &tvc, uint64_t* pmax_used_block_height = NULL);
+ bool check_tx_inputs(transaction& tx, tx_verification_context &tvc, uint64_t* pmax_used_block_height = NULL) const;
/**
* @brief performs a blockchain reorganization according to the longest chain rule
@@ -1186,7 +1162,7 @@ namespace cryptonote
*
* @return false if the reorganization fails, otherwise true
*/
- bool switch_to_alternative_blockchain(std::list<blocks_ext_by_hash::const_iterator>& alt_chain, bool discard_disconnected_chain);
+ bool switch_to_alternative_blockchain(std::list<block_extended_info>& alt_chain, bool discard_disconnected_chain);
/**
* @brief removes the most recent block from the blockchain
@@ -1249,7 +1225,7 @@ namespace cryptonote
*
* @return true on success, false otherwise
*/
- bool build_alt_chain(const crypto::hash &prev_id, std::list<blocks_ext_by_hash::const_iterator>& alt_chain, std::vector<uint64_t> &timestamps, block_verification_context& bvc) const;
+ bool build_alt_chain(const crypto::hash &prev_id, std::list<block_extended_info>& alt_chain, std::vector<uint64_t> &timestamps, block_verification_context& bvc) const;
/**
* @brief gets the difficulty requirement for a new block on an alternate chain
@@ -1259,7 +1235,7 @@ namespace cryptonote
*
* @return the difficulty requirement
*/
- difficulty_type get_next_difficulty_for_alternative_chain(const std::list<blocks_ext_by_hash::const_iterator>& alt_chain, block_extended_info& bei) const;
+ difficulty_type get_next_difficulty_for_alternative_chain(const std::list<block_extended_info>& alt_chain, block_extended_info& bei) const;
/**
* @brief sanity checks a miner transaction before validating an entire block
@@ -1452,7 +1428,7 @@ namespace cryptonote
* @param result false if the ring signature is invalid, otherwise true
*/
void check_ring_signature(const crypto::hash &tx_prefix_hash, const crypto::key_image &key_image,
- const std::vector<rct::ctkey> &pubkeys, const std::vector<crypto::signature> &sig, uint64_t &result);
+ const std::vector<rct::ctkey> &pubkeys, const std::vector<crypto::signature> &sig, uint64_t &result) const;
/**
* @brief loads block hashes from compiled-in data set
@@ -1472,7 +1448,7 @@ namespace cryptonote
* can be reconstituted by the receiver. This function expands
* that implicit data.
*/
- bool expand_transaction_2(transaction &tx, const crypto::hash &tx_prefix_hash, const std::vector<std::vector<rct::ctkey>> &pubkeys);
+ bool expand_transaction_2(transaction &tx, const crypto::hash &tx_prefix_hash, const std::vector<std::vector<rct::ctkey>> &pubkeys) const;
/**
* @brief invalidates any cached block template
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp
index 13426230e..a3a92ab60 100644
--- a/src/cryptonote_core/cryptonote_core.cpp
+++ b/src/cryptonote_core/cryptonote_core.cpp
@@ -208,13 +208,17 @@ namespace cryptonote
"is acted upon."
, ""
};
+ static const command_line::arg_descriptor<bool> arg_keep_alt_blocks = {
+ "keep-alt-blocks"
+ , "Keep alternative blocks on restart"
+ , false
+ };
//-----------------------------------------------------------------------------------------------
core::core(i_cryptonote_protocol* pprotocol):
m_mempool(m_blockchain_storage),
m_blockchain_storage(m_mempool),
m_miner(this),
- m_miner_address(boost::value_initialized<account_public_address>()),
m_starter_message_showed(false),
m_target_blockchain_height(0),
m_checkpoints_path(""),
@@ -325,6 +329,7 @@ namespace cryptonote
command_line::add_arg(desc, arg_prune_blockchain);
command_line::add_arg(desc, arg_reorg_notify);
command_line::add_arg(desc, arg_block_rate_notify);
+ command_line::add_arg(desc, arg_keep_alt_blocks);
miner::init_options(desc);
BlockchainDB::init_options(desc);
@@ -447,6 +452,7 @@ namespace cryptonote
m_nettype = FAKECHAIN;
}
bool r = handle_command_line(vm);
+ CHECK_AND_ASSERT_MES(r, false, "Failed to handle command line");
std::string db_type = command_line::get_arg(vm, cryptonote::arg_db_type);
std::string db_sync_mode = command_line::get_arg(vm, cryptonote::arg_db_sync_mode);
@@ -456,6 +462,7 @@ namespace cryptonote
std::string check_updates_string = command_line::get_arg(vm, arg_check_updates);
size_t max_txpool_weight = command_line::get_arg(vm, arg_max_txpool_weight);
bool prune_blockchain = command_line::get_arg(vm, arg_prune_blockchain);
+ bool keep_alt_blocks = command_line::get_arg(vm, arg_keep_alt_blocks);
boost::filesystem::path folder(m_config_folder);
if (m_nettype == FAKECHAIN)
@@ -634,6 +641,7 @@ namespace cryptonote
};
const difficulty_type fixed_difficulty = command_line::get_arg(vm, arg_fixed_difficulty);
r = m_blockchain_storage.init(db.release(), m_nettype, m_offline, regtest ? &regtest_test_options : test_options, fixed_difficulty, get_checkpoints);
+ CHECK_AND_ASSERT_MES(r, false, "Failed to initialize blockchain storage");
r = m_mempool.init(max_txpool_weight);
CHECK_AND_ASSERT_MES(r, false, "Failed to initialize memory pool");
@@ -671,6 +679,9 @@ namespace cryptonote
r = m_miner.init(vm, m_nettype);
CHECK_AND_ASSERT_MES(r, false, "Failed to initialize miner instance");
+ if (!keep_alt_blocks && !m_blockchain_storage.get_db().is_read_only())
+ m_blockchain_storage.get_db().drop_alt_blocks();
+
if (prune_blockchain)
{
// display a message if the blockchain is not pruned yet
@@ -1833,7 +1844,7 @@ namespace cryptonote
//-----------------------------------------------------------------------------------------------
bool core::check_block_rate()
{
- if (m_offline || m_nettype == FAKECHAIN || m_target_blockchain_height > get_current_blockchain_height())
+ if (m_offline || m_nettype == FAKECHAIN || m_target_blockchain_height > get_current_blockchain_height() || m_target_blockchain_height == 0)
{
MDEBUG("Not checking block rate, offline or syncing");
return true;
diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h
index 2fcf26a17..badbaf936 100644
--- a/src/cryptonote_core/cryptonote_core.h
+++ b/src/cryptonote_core/cryptonote_core.h
@@ -1014,7 +1014,6 @@ namespace cryptonote
//m_miner and m_miner_addres are probably temporary here
miner m_miner; //!< miner instance
- account_public_address m_miner_address; //!< address to mine to (for miner instance)
std::string m_config_folder; //!< folder to look in for configs and other files
diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp
index 854f3d1c5..4cf71e558 100644
--- a/src/cryptonote_core/cryptonote_tx_utils.cpp
+++ b/src/cryptonote_core/cryptonote_tx_utils.cpp
@@ -354,7 +354,7 @@ namespace cryptonote
if (shuffle_outs)
{
- std::shuffle(destinations.begin(), destinations.end(), std::default_random_engine(crypto::rand<unsigned int>()));
+ std::shuffle(destinations.begin(), destinations.end(), crypto::random_device{});
}
// sort ins by their key image
diff --git a/src/cryptonote_core/tx_sanity_check.cpp b/src/cryptonote_core/tx_sanity_check.cpp
index 36be91f2c..e95350f76 100644
--- a/src/cryptonote_core/tx_sanity_check.cpp
+++ b/src/cryptonote_core/tx_sanity_check.cpp
@@ -72,7 +72,7 @@ bool tx_sanity_check(Blockchain &blockchain, const cryptonote::blobdata &tx_blob
if (n_indices <= 10)
{
- MERROR("n_indices is only " << n_indices);
+ MDEBUG("n_indices is only " << n_indices << ", not checking");
return true;
}