diff options
Diffstat (limited to 'src/cryptonote_core')
-rw-r--r-- | src/cryptonote_core/blockchain.cpp | 44 | ||||
-rw-r--r-- | src/cryptonote_core/blockchain.h | 17 | ||||
-rw-r--r-- | src/cryptonote_core/cryptonote_core.cpp | 4 | ||||
-rw-r--r-- | src/cryptonote_core/cryptonote_tx_utils.cpp | 53 | ||||
-rw-r--r-- | src/cryptonote_core/cryptonote_tx_utils.h | 7 |
5 files changed, 119 insertions, 6 deletions
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 5cf4952ae..bcf99bbed 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -95,7 +95,8 @@ Blockchain::Blockchain(tx_memory_pool& tx_pool) : m_difficulty_for_next_block_top_hash(crypto::null_hash), m_difficulty_for_next_block(1), m_btc_valid(false), - m_batch_success(true) + m_batch_success(true), + m_prepare_height(0) { LOG_PRINT_L3("Blockchain::" << __func__); } @@ -754,6 +755,13 @@ crypto::hash Blockchain::get_block_id_by_height(uint64_t height) const return null_hash; } //------------------------------------------------------------------ +crypto::hash Blockchain::get_pending_block_id_by_height(uint64_t height) const +{ + if (m_prepare_height && height >= m_prepare_height && height - m_prepare_height < m_prepare_nblocks) + return (*m_prepare_blocks)[height - m_prepare_height].hash; + return get_block_id_by_height(height); +} +//------------------------------------------------------------------ bool Blockchain::get_block_by_hash(const crypto::hash &h, block &blk, bool *orphan) const { LOG_PRINT_L3("Blockchain::" << __func__); @@ -1029,6 +1037,7 @@ bool Blockchain::switch_to_alternative_blockchain(std::list<block_extended_info> } m_hardfork->reorganize_from_chain_height(split_height); + get_block_longhash_reorg(split_height); std::shared_ptr<tools::Notify> reorg_notify = m_reorg_notify; if (reorg_notify) @@ -1684,7 +1693,30 @@ bool Blockchain::handle_alternative_block(const block& b, const crypto::hash& id difficulty_type current_diff = get_next_difficulty_for_alternative_chain(alt_chain, bei); CHECK_AND_ASSERT_MES(current_diff, false, "!!!!!!! DIFFICULTY OVERHEAD !!!!!!!"); crypto::hash proof_of_work = null_hash; - get_block_longhash(bei.bl, proof_of_work, bei.height); + if (b.major_version >= RX_BLOCK_VERSION) + { + crypto::hash seedhash = null_hash; + uint64_t seedheight = rx_seedheight(bei.height); + // seedblock is on the alt chain somewhere + if (alt_chain.size() && alt_chain.front().height <= seedheight) + { + for (auto it=alt_chain.begin(); it != alt_chain.end(); it++) + { + if (it->height == seedheight+1) + { + seedhash = it->bl.prev_id; + break; + } + } + } else + { + seedhash = get_block_id_by_height(seedheight); + } + get_altblock_longhash(bei.bl, proof_of_work, get_current_blockchain_height(), bei.height, seedheight, seedhash); + } else + { + get_block_longhash(this, bei.bl, proof_of_work, bei.height, 0); + } if(!check_hash(proof_of_work, current_diff)) { MERROR_VER("Block with id: " << id << std::endl << " for alternative chain, does not have enough proof of work: " << proof_of_work << std::endl << " expected difficulty: " << current_diff); @@ -3613,7 +3645,7 @@ leave: proof_of_work = it->second; } else - proof_of_work = get_block_longhash(bl, blockchain_height); + proof_of_work = get_block_longhash(this, bl, blockchain_height, 0); // validate proof_of_work versus difficulty target if(!check_hash(proof_of_work, current_diffic)) @@ -4114,7 +4146,7 @@ void Blockchain::block_longhash_worker(uint64_t height, const epee::span<const b if (m_cancel) break; crypto::hash id = get_block_hash(block); - crypto::hash pow = get_block_longhash(block, height++); + crypto::hash pow = get_block_longhash(this, block, height++, 0); map.emplace(id, pow); } @@ -4430,6 +4462,9 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector<block_complete m_blocks_longhash_table.clear(); uint64_t thread_height = height; tools::threadpool::waiter waiter; + m_prepare_height = height; + m_prepare_nblocks = blocks_entry.size(); + m_prepare_blocks = &blocks; for (unsigned int i = 0; i < threads; i++) { unsigned nblocks = batches; @@ -4440,6 +4475,7 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector<block_complete } waiter.wait(&tpool); + m_prepare_height = 0; if (m_cancel) return false; diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h index 178b2cb24..552a53e89 100644 --- a/src/cryptonote_core/blockchain.h +++ b/src/cryptonote_core/blockchain.h @@ -206,6 +206,18 @@ namespace cryptonote crypto::hash get_block_id_by_height(uint64_t height) const; /** + * @brief gets a block's hash given a height + * + * Used only by prepare_handle_incoming_blocks. Will look in the list of incoming blocks + * if the height is contained there. + * + * @param height the height of the block + * + * @return the hash of the block at the requested height, or a zeroed hash if there is no such block + */ + crypto::hash get_pending_block_id_by_height(uint64_t height) const; + + /** * @brief gets the block with a given hash * * @param h the hash to look for @@ -1077,6 +1089,11 @@ namespace cryptonote std::shared_ptr<tools::Notify> m_block_notify; std::shared_ptr<tools::Notify> m_reorg_notify; + // for prepare_handle_incoming_blocks + uint64_t m_prepare_height; + uint64_t m_prepare_nblocks; + std::vector<block> *m_prepare_blocks; + /** * @brief collects the keys for all outputs being "spent" as an input * diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index e34ab8fbd..245be5778 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -219,7 +219,7 @@ namespace cryptonote core::core(i_cryptonote_protocol* pprotocol): m_mempool(m_blockchain_storage), m_blockchain_storage(m_mempool), - m_miner(this), + m_miner(this, &m_blockchain_storage), m_starter_message_showed(false), m_target_blockchain_height(0), m_checkpoints_path(""), @@ -655,6 +655,8 @@ namespace cryptonote CHECK_AND_ASSERT_MES(r, false, "Failed to initialize blockchain storage"); block_sync_size = command_line::get_arg(vm, arg_block_sync_size); + if (block_sync_size > BLOCKS_SYNCHRONIZING_MAX_COUNT) + MERROR("Error --block-sync-size cannot be greater than " << BLOCKS_SYNCHRONIZING_MAX_COUNT); MGINFO("Loading checkpoints"); diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp index 955d6a4b0..d2e022347 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.cpp +++ b/src/cryptonote_core/cryptonote_tx_utils.cpp @@ -37,6 +37,7 @@ using namespace epee; #include "common/apply_permutation.h" #include "cryptonote_tx_utils.h" #include "cryptonote_config.h" +#include "blockchain.h" #include "cryptonote_basic/miner.h" #include "cryptonote_basic/tx_extra.h" #include "crypto/crypto.h" @@ -658,9 +659,59 @@ namespace cryptonote bl.minor_version = CURRENT_BLOCK_MINOR_VERSION; bl.timestamp = 0; bl.nonce = nonce; - miner::find_nonce_for_given_block(bl, 1, 0); + miner::find_nonce_for_given_block(NULL, bl, 1, 0); bl.invalidate_hashes(); return true; } //--------------------------------------------------------------- + void get_altblock_longhash(const block& b, crypto::hash& res, const uint64_t main_height, const uint64_t height, const uint64_t seed_height, const crypto::hash& seed_hash) + { + blobdata bd = get_block_hashing_blob(b); + rx_slow_hash(main_height, seed_height, seed_hash.data, bd.data(), bd.size(), res.data, 0, 1); + } + + bool get_block_longhash(const Blockchain *pbc, const block& b, crypto::hash& res, const uint64_t height, const int miners) + { + // block 202612 bug workaround + if (height == 202612) + { + static const std::string longhash_202612 = "84f64766475d51837ac9efbef1926486e58563c95a19fef4aec3254f03000000"; + epee::string_tools::hex_to_pod(longhash_202612, res); + return true; + } + blobdata bd = get_block_hashing_blob(b); + if (b.major_version >= RX_BLOCK_VERSION) + { + uint64_t seed_height, main_height; + crypto::hash hash; + if (pbc != NULL) + { + seed_height = rx_seedheight(height); + hash = pbc->get_pending_block_id_by_height(seed_height); + main_height = pbc->get_current_blockchain_height(); + } else + { + memset(&hash, 0, sizeof(hash)); // only happens when generating genesis block + seed_height = 0; + main_height = 0; + } + rx_slow_hash(main_height, seed_height, hash.data, bd.data(), bd.size(), res.data, miners, 0); + } else { + const int pow_variant = b.major_version >= 7 ? b.major_version - 6 : 0; + crypto::cn_slow_hash(bd.data(), bd.size(), res, pow_variant, height); + } + return true; + } + + crypto::hash get_block_longhash(const Blockchain *pbc, const block& b, const uint64_t height, const int miners) + { + crypto::hash p = crypto::null_hash; + get_block_longhash(pbc, b, p, height, miners); + return p; + } + + void get_block_longhash_reorg(const uint64_t split_height) + { + rx_reorg(split_height); + } } diff --git a/src/cryptonote_core/cryptonote_tx_utils.h b/src/cryptonote_core/cryptonote_tx_utils.h index b03eb6e70..309e4177f 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.h +++ b/src/cryptonote_core/cryptonote_tx_utils.h @@ -132,6 +132,13 @@ namespace cryptonote , uint32_t nonce ); + class Blockchain; + bool get_block_longhash(const Blockchain *pb, const block& b, crypto::hash& res, const uint64_t height, const int miners); + void get_altblock_longhash(const block& b, crypto::hash& res, const uint64_t main_height, const uint64_t height, + const uint64_t seed_height, const crypto::hash& seed_hash); + crypto::hash get_block_longhash(const Blockchain *pb, const block& b, const uint64_t height, const int miners); + void get_block_longhash_reorg(const uint64_t split_height); + } BOOST_CLASS_VERSION(cryptonote::tx_source_entry, 1) |