From 1642be242d51c183532752bd482a04767c263740 Mon Sep 17 00:00:00 2001 From: Thomas Winget Date: Wed, 7 Oct 2015 22:28:11 -0400 Subject: minor bugfixes and refactoring - Blockchain should store if it's running on testnet or not - moved loading compiled-in block hashes to its own function for clarity - on handle_get_objects, should now correctly return false if a block's transactions are missing - replace instances of BOOST_FOREACH with C++11 for loops in Blockchain. --- src/cryptonote_core/blockchain.cpp | 133 +++++++++++++++++++++---------------- src/cryptonote_core/blockchain.h | 11 +++ 2 files changed, 88 insertions(+), 56 deletions(-) (limited to 'src/cryptonote_core') diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 02f592b61..f18173ae8 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -270,7 +270,8 @@ bool Blockchain::init(BlockchainDB* db, const bool testnet, const bool fakechain m_db = db; - if (testnet) { + m_testnet = testnet; + if (m_testnet) { m_hardfork = new HardFork(*db, 1, testnet_hard_fork_version_1_till); for (size_t n = 0; n < sizeof(testnet_hard_forks) / sizeof(testnet_hard_forks[0]); ++n) m_hardfork->add_fork(testnet_hard_forks[n].version, testnet_hard_forks[n].height, testnet_hard_forks[n].threshold, testnet_hard_forks[n].time); @@ -292,7 +293,7 @@ bool Blockchain::init(BlockchainDB* db, const bool testnet, const bool fakechain LOG_PRINT_L0("Blockchain not loaded, generating genesis block."); block bl = boost::value_initialized(); block_verification_context bvc = boost::value_initialized(); - if (testnet) + if (m_testnet) { generate_genesis_block(bl, config::testnet::GENESIS_TX, config::testnet::GENESIS_NONCE); } @@ -330,45 +331,8 @@ bool Blockchain::init(BlockchainDB* db, const bool testnet, const bool fakechain m_async_pool.create_thread(boost::bind(&boost::asio::io_service::run, &m_async_service)); #if defined(PER_BLOCK_CHECKPOINT) - if (!fakechain && m_fast_sync && get_blocks_dat_start(testnet) != nullptr) - { - if (get_blocks_dat_size(testnet) > 4) - { - const unsigned char *p = get_blocks_dat_start(testnet); - const uint32_t nblocks = *p | ((*(p+1))<<8) | ((*(p+2))<<16) | ((*(p+3))<<24); - const size_t size_needed = 4 + nblocks * sizeof(crypto::hash); - if(nblocks > 0 && nblocks > m_db->height() && get_blocks_dat_size(testnet) >= size_needed) - { - LOG_PRINT_L0("Loading precomputed blocks: " << nblocks); - p += sizeof(uint32_t); - for (uint32_t i = 0; i < nblocks; i++) - { - crypto::hash hash; - memcpy(hash.data, p, sizeof(hash.data)); - p += sizeof(hash.data); - m_blocks_hash_check.push_back(hash); - } - - // FIXME: clear tx_pool because the process might have been - // terminated and caused it to store txs kept by blocks. - // The core will not call check_tx_inputs(..) for these - // transactions in this case. Consequently, the sanity check - // for tx hashes will fail in handle_block_to_main_chain(..) - std::list txs; - m_tx_pool.get_transactions(txs); - - size_t blob_size; - uint64_t fee; - bool relayed; - transaction pool_tx; - for(const transaction &tx : txs) - { - crypto::hash tx_hash = get_transaction_hash(tx); - m_tx_pool.take_tx(tx_hash, pool_tx, blob_size, fee, relayed); - } - } - } - } + if (!fakechain) + load_compiled_in_block_hashes(); #endif LOG_PRINT_GREEN("Blockchain initialized. last block: " << m_db->height() - 1 << ", " << epee::misc_utils::get_time_interval_string(timestamp_diff) << " time ago, current difficulty: " << get_difficulty_for_next_block(), LOG_LEVEL_0); @@ -652,10 +616,10 @@ void Blockchain::get_all_known_block_ids(std::list &main, std::lis main.push_back(a); } - BOOST_FOREACH(const blocks_ext_by_hash::value_type &v, m_alternative_chains) + for (const blocks_ext_by_hash::value_type &v: m_alternative_chains) alt.push_back(v.first); - BOOST_FOREACH(const blocks_ext_by_hash::value_type &v, m_invalid_blocks) + for (const blocks_ext_by_hash::value_type &v: m_invalid_blocks) invalid.push_back(v.first); } //------------------------------------------------------------------ @@ -836,7 +800,7 @@ bool Blockchain::switch_to_alternative_blockchain(std::list blocks; get_blocks(arg.blocks, blocks, rsp.missed_ids); - BOOST_FOREACH(const auto& bl, blocks) + for (const auto& bl: blocks) { - std::list missed_tx_id; + std::list missed_tx_ids; std::list txs; - get_transactions(bl.tx_hashes, txs, rsp.missed_ids); - CHECK_AND_ASSERT_MES(!missed_tx_id.size(), false, "Internal error: has missed missed_tx_id.size()=" << missed_tx_id.size() - << std::endl << "for block id = " << get_block_hash(bl)); + get_transactions(bl.tx_hashes, txs, missed_tx_ids); + + if (missed_tx_ids.size() != 0) + { + LOG_ERROR("Error retrieving blocks, missed " << missed_tx_ids.size() + << " transactions for block with hash: " << get_block_hash(bl) + << std::endl + ); + rsp.missed_ids.push_back(get_block_hash(bl)); + + // append missed transaction hashes to response missed_ids field, + // as done below if any standalone transactions were requested + // and missed. + rsp.missed_ids.splice(rsp.missed_ids.end(), missed_tx_ids); + return false; + } + rsp.blocks.push_back(block_complete_entry()); block_complete_entry& e = rsp.blocks.back(); //pack block e.block = t_serializable_object_to_blob(bl); //pack transactions - BOOST_FOREACH(transaction& tx, txs) + for (transaction& tx: txs) e.txs.push_back(t_serializable_object_to_blob(tx)); } //get another transactions, if need std::list txs; get_transactions(arg.txs, txs, rsp.missed_ids); //pack aside transactions - BOOST_FOREACH(const auto& tx, txs) + for (const auto& tx: txs) rsp.txs.push_back(t_serializable_object_to_blob(tx)); return true; @@ -1439,7 +1417,7 @@ bool Blockchain::get_alternative_blocks(std::list& blocks) const LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); - BOOST_FOREACH(const auto& alt_bl, m_alternative_chains) + for (const auto& alt_bl: m_alternative_chains) { blocks.push_back(alt_bl.second.bl); } @@ -1988,7 +1966,7 @@ bool Blockchain::check_tx_outputs(const transaction& tx) // from hard fork 2, we forbid dust and compound outputs if (m_hardfork->get_current_version() >= 2) { - BOOST_FOREACH(auto &o, tx.vout) { + for (auto &o: tx.vout) { if (!is_valid_decomposed_amount(o.amount)) { return false; } @@ -2001,7 +1979,7 @@ bool Blockchain::check_tx_outputs(const transaction& tx) bool Blockchain::have_tx_keyimges_as_spent(const transaction &tx) const { LOG_PRINT_L3("Blockchain::" << __func__); - BOOST_FOREACH(const txin_v& in, tx.vin) + for (const txin_v& in: tx.vin) { CHECKED_GET_SPECIFIC_VARIANT(in, const txin_to_key, in_to_key, true); if(have_tx_keyimg_as_spent(in_to_key.k_image)) @@ -3249,6 +3227,49 @@ bool Blockchain::get_hard_fork_voting_info(uint8_t version, uint32_t &window, ui return m_hardfork->get_voting_info(version, window, votes, threshold, earliest_height, voting); } +void Blockchain::load_compiled_in_block_hashes() +{ + if (m_fast_sync && get_blocks_dat_start(m_testnet) != nullptr) + { + if (get_blocks_dat_size(m_testnet) > 4) + { + const unsigned char *p = get_blocks_dat_start(m_testnet); + const uint32_t nblocks = *p | ((*(p+1))<<8) | ((*(p+2))<<16) | ((*(p+3))<<24); + const size_t size_needed = 4 + nblocks * sizeof(crypto::hash); + if(nblocks > 0 && nblocks > m_db->height() && get_blocks_dat_size(m_testnet) >= size_needed) + { + LOG_PRINT_L0("Loading precomputed blocks: " << nblocks); + p += sizeof(uint32_t); + for (uint32_t i = 0; i < nblocks; i++) + { + crypto::hash hash; + memcpy(hash.data, p, sizeof(hash.data)); + p += sizeof(hash.data); + m_blocks_hash_check.push_back(hash); + } + + // FIXME: clear tx_pool because the process might have been + // terminated and caused it to store txs kept by blocks. + // The core will not call check_tx_inputs(..) for these + // transactions in this case. Consequently, the sanity check + // for tx hashes will fail in handle_block_to_main_chain(..) + std::list txs; + m_tx_pool.get_transactions(txs); + + size_t blob_size; + uint64_t fee; + bool relayed; + transaction pool_tx; + for(const transaction &tx : txs) + { + crypto::hash tx_hash = get_transaction_hash(tx); + m_tx_pool.take_tx(tx_hash, pool_tx, blob_size, fee, relayed); + } + } + } + } +} + bool Blockchain::for_all_key_images(std::function f) const { return m_db->for_all_key_images(f); diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h index ecabf5376..89f623f90 100644 --- a/src/cryptonote_core/blockchain.h +++ b/src/cryptonote_core/blockchain.h @@ -239,6 +239,8 @@ namespace cryptonote HardFork *m_hardfork; + bool m_testnet; + template inline bool scan_outputkeys_for_indexes(const txin_to_key& tx_in_to_key, visitor_t &vis, const crypto::hash &tx_prefix_hash, uint64_t* pmax_related_block_height = NULL) const; bool check_tx_input(const txin_to_key& txin, const crypto::hash& tx_prefix_hash, const std::vector& sig, std::vector &output_keys, uint64_t* pmax_related_block_height); @@ -274,5 +276,14 @@ namespace cryptonote void get_timestamp_and_difficulty(uint64_t ×tamp, difficulty_type &difficulty, const int offset) const; void check_ring_signature(const crypto::hash &tx_prefix_hash, const crypto::key_image &key_image, const std::vector &pubkeys, const std::vector &sig, uint64_t &result); + + /** + * @brief loads block hashes from compiled-in data set + * + * A (possibly empty) set of block hashes can be compiled into the + * monero daemon binary. This function loads those hashes into + * a useful state. + */ + void load_compiled_in_block_hashes(); }; } // namespace cryptonote -- cgit v1.2.3 From 7658ac0f45c4aba0d88935047b225bfbc0ba2548 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 3 Feb 2016 21:08:03 +0000 Subject: blockchain: revert handle_get_objects adding block id on tx not found This differs from the original CN code, and there seems to be no reason to include the block itself, if it was found --- src/cryptonote_core/blockchain.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/cryptonote_core') diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index f18173ae8..afc479a4b 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -1385,7 +1385,6 @@ bool Blockchain::handle_get_objects(NOTIFY_REQUEST_GET_OBJECTS::request& arg, NO << " transactions for block with hash: " << get_block_hash(bl) << std::endl ); - rsp.missed_ids.push_back(get_block_hash(bl)); // append missed transaction hashes to response missed_ids field, // as done below if any standalone transactions were requested -- cgit v1.2.3