From 63766275301f1c562205e22d5f14b220f321ad58 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 21 Oct 2015 19:18:00 +0100 Subject: [PATCH] hardfork: switch voting to block minor version Using major version would cause older daemons to reject those blocks as they fail to deserialize blocks with a major version which is not 1. There is no such restriction on the minor version, so switching allows older daemons to coexist with newer ones till the actual fork date, when most will hopefully have updated already. Also, for the same reason, we consider a vote for 0 to be a vote for 1, since older daemons set minor version to 0. --- src/cryptonote_core/blockchain.cpp | 4 ++-- src/cryptonote_core/cryptonote_basic.h | 4 ++-- src/cryptonote_core/hardfork.cpp | 21 ++++++++++++++++----- tests/unit_tests/hardfork.cpp | 5 +---- 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index c38b5884..306530f0 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -1033,8 +1033,8 @@ bool Blockchain::create_block_template(block& b, const account_public_address& m CRITICAL_REGION_BEGIN(m_blockchain_lock); height = m_db->height(); - b.major_version = m_hardfork->get_ideal_version(); - b.minor_version = 0; + b.major_version = m_hardfork->get_current_version(); + b.minor_version = m_hardfork->get_ideal_version(); b.prev_id = get_tail_id(); b.timestamp = time(NULL); diff --git a/src/cryptonote_core/cryptonote_basic.h b/src/cryptonote_core/cryptonote_basic.h index d3db5006..94887b5a 100644 --- a/src/cryptonote_core/cryptonote_basic.h +++ b/src/cryptonote_core/cryptonote_basic.h @@ -277,8 +277,8 @@ namespace cryptonote /************************************************************************/ struct block_header { - uint8_t major_version; // now used as a voting mechanism, rather than how this particular block is built - uint8_t minor_version; + uint8_t major_version; + uint8_t minor_version; // now used as a voting mechanism, rather than how this particular block is built uint64_t timestamp; crypto::hash prev_id; uint32_t nonce; diff --git a/src/cryptonote_core/hardfork.cpp b/src/cryptonote_core/hardfork.cpp index 77839678..6ecaff05 100644 --- a/src/cryptonote_core/hardfork.cpp +++ b/src/cryptonote_core/hardfork.cpp @@ -35,6 +35,17 @@ using namespace cryptonote; +static uint8_t get_block_vote(const cryptonote::block &b) +{ + // Pre-hardfork blocks have a minor version hardcoded to 0. + // For the purposes of voting, we consider 0 to refer to + // version number 1, which is what all blocks from the genesis + // block are. It makes things simpler. + if (b.minor_version == 0) + return 1; + return b.minor_version; +} + HardFork::HardFork(cryptonote::BlockchainDB &db, uint8_t original_version, uint64_t original_version_till_height, time_t forked_time, time_t update_time, uint64_t window_size, int threshold_percent): db(db), original_version(original_version), @@ -87,7 +98,7 @@ bool HardFork::do_check(uint8_t version) const bool HardFork::check(const cryptonote::block &block) const { CRITICAL_REGION_LOCAL(lock); - return do_check(block.major_version); + return do_check(get_block_vote(block)); } bool HardFork::add(uint8_t block_version, uint64_t height) @@ -125,7 +136,7 @@ bool HardFork::add(uint8_t block_version, uint64_t height) bool HardFork::add(const cryptonote::block &block, uint64_t height) { - return add(block.major_version, height); + return add(get_block_vote(block), height); } void HardFork::init() @@ -168,7 +179,7 @@ uint8_t HardFork::get_block_version(uint64_t height) const return original_version; const cryptonote::block &block = db.get_block_from_height(height); - return block.major_version; + return get_block_vote(block); } bool HardFork::reorganize_from_block_height(uint64_t height) @@ -192,7 +203,7 @@ bool HardFork::reorganize_from_block_height(uint64_t height) } for (uint64_t h = rescan_height; h <= height; ++h) { cryptonote::block b = db.get_block_from_height(h); - const uint8_t v = get_effective_version(b.major_version); + const uint8_t v = get_effective_version(get_block_vote(b)); last_versions[v]++; versions.push_back(v); } @@ -236,7 +247,7 @@ bool HardFork::rescan_from_block_height(uint64_t height) const uint64_t rescan_height = height >= (window_size - 1) ? height - (window_size -1) : 0; for (uint64_t h = rescan_height; h <= height; ++h) { cryptonote::block b = db.get_block_from_height(h); - const uint8_t v = get_effective_version(b.major_version); + const uint8_t v = get_effective_version(get_block_vote(b)); last_versions[v]++; versions.push_back(v); } diff --git a/tests/unit_tests/hardfork.cpp b/tests/unit_tests/hardfork.cpp index a8d2d381..210c1959 100644 --- a/tests/unit_tests/hardfork.cpp +++ b/tests/unit_tests/hardfork.cpp @@ -131,7 +131,7 @@ private: static cryptonote::block mkblock(uint8_t version) { cryptonote::block b; - b.major_version = version; + b.minor_version = version; return b; } @@ -358,7 +358,6 @@ TEST(new_blocks, denied) ASSERT_TRUE(hf.add(2, 2, 1)); hf.init(); - ASSERT_FALSE(hf.add(mkblock(0), 0)); ASSERT_TRUE(hf.add(mkblock(1), 0)); ASSERT_TRUE(hf.add(mkblock(1), 1)); ASSERT_TRUE(hf.add(mkblock(1), 2)); @@ -384,7 +383,6 @@ TEST(new_version, early) ASSERT_TRUE(hf.add(2, 4, 1)); hf.init(); - ASSERT_FALSE(hf.add(mkblock(0), 0)); ASSERT_TRUE(hf.add(mkblock(2), 0)); ASSERT_TRUE(hf.add(mkblock(2), 1)); // we have enough votes already ASSERT_TRUE(hf.add(mkblock(2), 2)); @@ -417,7 +415,6 @@ TEST(reorganize, changed) #define ADD_TRUE(v, h) ADD(v, h, TRUE) #define ADD_FALSE(v, h) ADD(v, h, FALSE) - ADD_FALSE(0, 0); ADD_TRUE(1, 0); ADD_TRUE(1, 1); ADD_TRUE(2, 2);