diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index de3af8e02..5230864ec 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -1259,6 +1259,14 @@ bool Blockchain::handle_alternative_block(const block& b, const crypto::hash& id return false; } + // this is a cheap test + if (!m_hardfork->check_for_height(b, block_height)) + { + LOG_PRINT_L1("Block with id: " << id << std::endl << "has old version for height " << block_height); + bvc.m_verifivation_failed = true; + return false; + } + //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); diff --git a/src/cryptonote_core/hardfork.cpp b/src/cryptonote_core/hardfork.cpp index c63ca36ef..8f9ff97d3 100644 --- a/src/cryptonote_core/hardfork.cpp +++ b/src/cryptonote_core/hardfork.cpp @@ -114,6 +114,19 @@ bool HardFork::check(const cryptonote::block &block) const return do_check(::get_block_version(block), ::get_block_vote(block)); } +bool HardFork::do_check_for_height(uint8_t block_version, uint8_t voting_version, uint64_t height) const +{ + int fork_index = get_voted_fork_index(height); + return block_version == heights[fork_index].version + && voting_version >= heights[fork_index].version; +} + +bool HardFork::check_for_height(const cryptonote::block &block, uint64_t height) const +{ + CRITICAL_REGION_LOCAL(lock); + return do_check_for_height(::get_block_version(block), ::get_block_vote(block), height); +} + bool HardFork::add(uint8_t block_version, uint8_t voting_version, uint64_t height) { CRITICAL_REGION_LOCAL(lock); diff --git a/src/cryptonote_core/hardfork.h b/src/cryptonote_core/hardfork.h index 33b958f9c..8d2edfa2a 100644 --- a/src/cryptonote_core/hardfork.h +++ b/src/cryptonote_core/hardfork.h @@ -113,6 +113,20 @@ namespace cryptonote */ bool check(const cryptonote::block &block) const; + /** + * @brief same as check, but for a particular height, rather than the top + * + * NOTE: this does not play well with voting, and relies on voting to be + * disabled (that is, forks happen on the scheduled date, whether or not + * enough blocks have voted for the fork). + * + * returns true if no error, false otherwise + * + * @param block the new block + * @param height which height to check for + */ + bool check_for_height(const cryptonote::block &block, uint64_t height) const; + /** * @brief add a new block * @@ -211,6 +225,7 @@ namespace cryptonote uint8_t get_block_version(uint64_t height) const; bool do_check(uint8_t block_version, uint8_t voting_version) const; + bool do_check_for_height(uint8_t block_version, uint8_t voting_version, uint64_t height) const; int get_voted_fork_index(uint64_t height) const; uint8_t get_effective_version(uint8_t voting_version) const; bool add(uint8_t block_version, uint8_t voting_version, uint64_t height);