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.
This commit is contained in:
moneromooo-monero 2015-10-21 19:18:00 +01:00
parent 55178aed8c
commit 6376627530
No known key found for this signature in database
GPG key ID: 686F07454D6CEFC3
4 changed files with 21 additions and 13 deletions

View file

@ -1033,8 +1033,8 @@ bool Blockchain::create_block_template(block& b, const account_public_address& m
CRITICAL_REGION_BEGIN(m_blockchain_lock); CRITICAL_REGION_BEGIN(m_blockchain_lock);
height = m_db->height(); height = m_db->height();
b.major_version = m_hardfork->get_ideal_version(); b.major_version = m_hardfork->get_current_version();
b.minor_version = 0; b.minor_version = m_hardfork->get_ideal_version();
b.prev_id = get_tail_id(); b.prev_id = get_tail_id();
b.timestamp = time(NULL); b.timestamp = time(NULL);

View file

@ -277,8 +277,8 @@ namespace cryptonote
/************************************************************************/ /************************************************************************/
struct block_header struct block_header
{ {
uint8_t major_version; // now used as a voting mechanism, rather than how this particular block is built uint8_t major_version;
uint8_t minor_version; uint8_t minor_version; // now used as a voting mechanism, rather than how this particular block is built
uint64_t timestamp; uint64_t timestamp;
crypto::hash prev_id; crypto::hash prev_id;
uint32_t nonce; uint32_t nonce;

View file

@ -35,6 +35,17 @@
using namespace cryptonote; 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): 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), db(db),
original_version(original_version), original_version(original_version),
@ -87,7 +98,7 @@ bool HardFork::do_check(uint8_t version) const
bool HardFork::check(const cryptonote::block &block) const bool HardFork::check(const cryptonote::block &block) const
{ {
CRITICAL_REGION_LOCAL(lock); 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) 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) 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() void HardFork::init()
@ -168,7 +179,7 @@ uint8_t HardFork::get_block_version(uint64_t height) const
return original_version; return original_version;
const cryptonote::block &block = db.get_block_from_height(height); 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) 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) { for (uint64_t h = rescan_height; h <= height; ++h) {
cryptonote::block b = db.get_block_from_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]++; last_versions[v]++;
versions.push_back(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; const uint64_t rescan_height = height >= (window_size - 1) ? height - (window_size -1) : 0;
for (uint64_t h = rescan_height; h <= height; ++h) { for (uint64_t h = rescan_height; h <= height; ++h) {
cryptonote::block b = db.get_block_from_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]++; last_versions[v]++;
versions.push_back(v); versions.push_back(v);
} }

View file

@ -131,7 +131,7 @@ private:
static cryptonote::block mkblock(uint8_t version) static cryptonote::block mkblock(uint8_t version)
{ {
cryptonote::block b; cryptonote::block b;
b.major_version = version; b.minor_version = version;
return b; return b;
} }
@ -358,7 +358,6 @@ TEST(new_blocks, denied)
ASSERT_TRUE(hf.add(2, 2, 1)); ASSERT_TRUE(hf.add(2, 2, 1));
hf.init(); hf.init();
ASSERT_FALSE(hf.add(mkblock(0), 0));
ASSERT_TRUE(hf.add(mkblock(1), 0)); ASSERT_TRUE(hf.add(mkblock(1), 0));
ASSERT_TRUE(hf.add(mkblock(1), 1)); ASSERT_TRUE(hf.add(mkblock(1), 1));
ASSERT_TRUE(hf.add(mkblock(1), 2)); ASSERT_TRUE(hf.add(mkblock(1), 2));
@ -384,7 +383,6 @@ TEST(new_version, early)
ASSERT_TRUE(hf.add(2, 4, 1)); ASSERT_TRUE(hf.add(2, 4, 1));
hf.init(); hf.init();
ASSERT_FALSE(hf.add(mkblock(0), 0));
ASSERT_TRUE(hf.add(mkblock(2), 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), 1)); // we have enough votes already
ASSERT_TRUE(hf.add(mkblock(2), 2)); 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_TRUE(v, h) ADD(v, h, TRUE)
#define ADD_FALSE(v, h) ADD(v, h, FALSE) #define ADD_FALSE(v, h) ADD(v, h, FALSE)
ADD_FALSE(0, 0);
ADD_TRUE(1, 0); ADD_TRUE(1, 0);
ADD_TRUE(1, 1); ADD_TRUE(1, 1);
ADD_TRUE(2, 2); ADD_TRUE(2, 2);