Skip to content
This repository has been archived by the owner on Jan 12, 2020. It is now read-only.

Commit

Permalink
Hard fork 1
Browse files Browse the repository at this point in the history
* Block major version 5
* Start height 90000
* LWMA-2 difficulty algorithm
* Minimum of 1 transaction per block
  • Loading branch information
mtl1979 committed May 16, 2019
1 parent 0232b58 commit 4c5a9b9
Show file tree
Hide file tree
Showing 18 changed files with 259 additions and 144 deletions.
41 changes: 27 additions & 14 deletions src/CryptoNoteConfig.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Copyright (c) 2012-2017, The CryptoNote developers, The Bytecoin developers
// Copyright (c) 2018-2019, The Bittorium developers
//
// This file is part of Bytecoin.
//
Expand Down Expand Up @@ -31,15 +32,25 @@ const size_t CRYPTONOTE_MAX_TX_SIZE = 1000000000;
const size_t CRYPTONOTE_MAX_SAFE_TX_SIZE = 115000;
const uint64_t CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX = 0xce;
const uint32_t CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW = 10;
const uint64_t CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT = 60 * 60 * 2;

const size_t BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW = 60;
const size_t BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW_V3 = 11;

const uint64_t DIFFICULTY_TARGET = 240; // seconds
const uint64_t EXPECTED_NUMBER_OF_BLOCKS_PER_DAY = 24 * 60 * 60 / DIFFICULTY_TARGET;

const uint32_t UPGRADE_HEIGHT_V2 = 1;
const uint32_t UPGRADE_HEIGHT_V3 = 2;
const uint32_t UPGRADE_HEIGHT_V4 = 3; // Upgrade height for CN-Lite Variant 1 switch.
const uint32_t UPGRADE_HEIGHT_V5 = 90000; // Upgrade height for LWMA-2
const unsigned UPGRADE_VOTING_THRESHOLD = 90; // percent
const uint32_t UPGRADE_VOTING_WINDOW = EXPECTED_NUMBER_OF_BLOCKS_PER_DAY; // blocks
const uint32_t UPGRADE_WINDOW = EXPECTED_NUMBER_OF_BLOCKS_PER_DAY; // blocks
static_assert(0 < UPGRADE_VOTING_THRESHOLD && UPGRADE_VOTING_THRESHOLD <= 100, "Bad UPGRADE_VOTING_THRESHOLD");
static_assert(UPGRADE_VOTING_WINDOW > 1, "Bad UPGRADE_VOTING_WINDOW");

// MONEY_SUPPLY - total number coins to be generated
const uint64_t MONEY_SUPPLY = UINT64_C(18000000000);
const uint32_t ZAWY_DIFFICULTY_BLOCK_INDEX = 0;
const size_t ZAWY_DIFFICULTY_V2 = 0;
const uint8_t ZAWY_DIFFICULTY_DIFFICULTY_BLOCK_VERSION = 3;
const unsigned EMISSION_SPEED_FACTOR = 19;
const uint64_t GENESIS_BLOCK_REWARD = UINT64_C(1800000000);
static_assert(EMISSION_SPEED_FACTOR <= 8 * sizeof(uint64_t), "Bad EMISSION_SPEED_FACTOR");
Expand All @@ -56,11 +67,16 @@ const uint16_t DEFAULT_MIXIN = 0;
const uint16_t MINIMUM_MIXIN = 0;
const uint64_t DEFAULT_DUST_THRESHOLD = UINT64_C(1);

const uint64_t DIFFICULTY_TARGET = 240; // seconds
const uint64_t EXPECTED_NUMBER_OF_BLOCKS_PER_DAY = 24 * 60 * 60 / DIFFICULTY_TARGET;
const uint32_t ZAWY_DIFFICULTY_BLOCK_INDEX = 0;
const size_t ZAWY_DIFFICULTY_V2 = 0;
const uint8_t ZAWY_DIFFICULTY_DIFFICULTY_BLOCK_VERSION = 3;
const uint64_t LWMA_2_DIFFICULTY_BLOCK_INDEX = UPGRADE_HEIGHT_V5;

const size_t DIFFICULTY_WINDOW = 17;
const size_t DIFFICULTY_WINDOW_V1 = 360;
const size_t DIFFICULTY_WINDOW_V2 = 360;
const size_t DIFFICULTY_WINDOW_V3 = 60;
const uint64_t DIFFICULTY_BLOCKS_COUNT_V3 = DIFFICULTY_WINDOW_V3 + 1;
const size_t DIFFICULTY_CUT = 0; // timestamps to cut after sorting
const size_t DIFFICULTY_CUT_V1 = 60;
const size_t DIFFICULTY_CUT_V2 = 60;
Expand All @@ -85,14 +101,10 @@ const size_t FUSION_TX_MIN_INPUT_COUNT = 12;
const size_t FUSION_TX_MIN_IN_OUT_COUNT_RATIO = 4;

const uint32_t KEY_IMAGE_CHECKING_BLOCK_INDEX = 0;
const uint32_t UPGRADE_HEIGHT_V2 = 1;
const uint32_t UPGRADE_HEIGHT_V3 = 2;
const uint32_t UPGRADE_HEIGHT_V4 = 3; // Upgrade height for CN-Lite Variant 1 switch.
const unsigned UPGRADE_VOTING_THRESHOLD = 90; // percent
const uint32_t UPGRADE_VOTING_WINDOW = EXPECTED_NUMBER_OF_BLOCKS_PER_DAY; // blocks
const uint32_t UPGRADE_WINDOW = EXPECTED_NUMBER_OF_BLOCKS_PER_DAY; // blocks
static_assert(0 < UPGRADE_VOTING_THRESHOLD && UPGRADE_VOTING_THRESHOLD <= 100, "Bad UPGRADE_VOTING_THRESHOLD");
static_assert(UPGRADE_VOTING_WINDOW > 1, "Bad UPGRADE_VOTING_WINDOW");

const uint64_t CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT_V1 = 60 * 60 * 2;
const uint64_t CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT_V2 = 7 * DIFFICULTY_TARGET;
const uint64_t CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT_V2_UPGRADE_HEIGHT = UPGRADE_HEIGHT_V5;

const char CRYPTONOTE_BLOCKS_FILENAME[] = "blocks.bin";
const char CRYPTONOTE_BLOCKINDEXES_FILENAME[] = "blockindexes.bin";
Expand All @@ -110,6 +122,7 @@ const uint8_t BLOCK_MAJOR_VERSION_1 = 1;
const uint8_t BLOCK_MAJOR_VERSION_2 = 2;
const uint8_t BLOCK_MAJOR_VERSION_3 = 3;
const uint8_t BLOCK_MAJOR_VERSION_4 = 4;
const uint8_t BLOCK_MAJOR_VERSION_5 = 5;
const uint8_t BLOCK_MINOR_VERSION_0 = 0;
const uint8_t BLOCK_MINOR_VERSION_1 = 1;

Expand Down
3 changes: 3 additions & 0 deletions src/CryptoNoteCore/BlockValidationErrors.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Copyright (c) 2012-2017, The CryptoNote developers, The Bytecoin developers
// Copyright (c) 2018-2019, The Bittorium developers
//
// This file is part of Bytecoin.
//
Expand Down Expand Up @@ -35,6 +36,7 @@ enum class BlockValidationError {
BLOCK_REWARD_MISMATCH,
CHECKPOINT_BLOCK_HASH_MISMATCH,
PROOF_OF_WORK_TOO_WEAK,
NOT_ENOUGH_TRANSACTIONS,
TRANSACTION_ABSENT_IN_POOL
};

Expand Down Expand Up @@ -66,6 +68,7 @@ class BlockValidationErrorCategory : public std::error_category {
case BlockValidationError::BLOCK_REWARD_MISMATCH: return "Block reward doesn't match expected reward";
case BlockValidationError::CHECKPOINT_BLOCK_HASH_MISMATCH: return "Checkpoint block hash mismatch";
case BlockValidationError::PROOF_OF_WORK_TOO_WEAK: return "Proof of work is too weak";
case BlockValidationError::NOT_ENOUGH_TRANSACTIONS: return "New block must have at least one transaction";
case BlockValidationError::TRANSACTION_ABSENT_IN_POOL: return "Block's transaction is absent in transaction pool";
default: return "Unknown error";
}
Expand Down
6 changes: 3 additions & 3 deletions src/CryptoNoteCore/BlockchainCache.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) 2012-2017, The CryptoNote developers, The Bytecoin developers
// Copyright (c) 2018, The Bittorium developers
// Copyright (c) 2018-2019, The Bittorium developers
//
// This file is part of Bytecoin.
//
Expand Down Expand Up @@ -968,9 +968,9 @@ Difficulty BlockchainCache::getDifficultyForNextBlock() const {
Difficulty BlockchainCache::getDifficultyForNextBlock(uint32_t blockIndex) const {
assert(blockIndex <= getTopBlockIndex());
uint8_t nextBlockMajorVersion = getBlockMajorVersionForHeight(blockIndex+1);
auto timestamps = getLastTimestamps(currency.difficultyBlocksCountByBlockVersion(nextBlockMajorVersion), blockIndex, skipGenesisBlock);
auto timestamps = getLastTimestamps(currency.difficultyBlocksCountByBlockVersion(nextBlockMajorVersion, blockIndex), blockIndex, skipGenesisBlock);
auto commulativeDifficulties =
getLastCumulativeDifficulties(currency.difficultyBlocksCountByBlockVersion(nextBlockMajorVersion), blockIndex, skipGenesisBlock);
getLastCumulativeDifficulties(currency.difficultyBlocksCountByBlockVersion(nextBlockMajorVersion, blockIndex), blockIndex, skipGenesisBlock);
return currency.nextDifficulty(nextBlockMajorVersion, blockIndex, std::move(timestamps), std::move(commulativeDifficulties));
}

Expand Down
30 changes: 25 additions & 5 deletions src/CryptoNoteCore/Core.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (c) 2012-2017, The CryptoNote developers, The Bytecoin developers
// Copyright (c) 2018, The Bittorium developers
// Copyright (c) 2018-2019, The Bittorium developers
//
// This file is part of Bytecoin.
//
Expand Down Expand Up @@ -201,6 +201,7 @@ Core::Core(const Currency& currency, Logging::ILogger& logger, Checkpoints&& che
upgradeManager->addMajorBlockVersion(BLOCK_MAJOR_VERSION_2, currency.upgradeHeight(BLOCK_MAJOR_VERSION_2));
upgradeManager->addMajorBlockVersion(BLOCK_MAJOR_VERSION_3, currency.upgradeHeight(BLOCK_MAJOR_VERSION_3));
upgradeManager->addMajorBlockVersion(BLOCK_MAJOR_VERSION_4, currency.upgradeHeight(BLOCK_MAJOR_VERSION_4));
upgradeManager->addMajorBlockVersion(BLOCK_MAJOR_VERSION_5, currency.upgradeHeight(BLOCK_MAJOR_VERSION_5));

transactionPool = std::unique_ptr<ITransactionPoolCleanWrapper>(new TransactionPoolCleanWrapper(
std::unique_ptr<ITransactionPool>(new TransactionPool(logger)),
Expand Down Expand Up @@ -553,7 +554,7 @@ Difficulty Core::getDifficultyForNextBlock() const {

uint8_t nextBlockMajorVersion = getBlockMajorVersionForHeight(topBlockIndex);

size_t blocksCount = std::min(static_cast<size_t>(topBlockIndex), currency.difficultyBlocksCountByBlockVersion(nextBlockMajorVersion));
size_t blocksCount = std::min(static_cast<size_t>(topBlockIndex), currency.difficultyBlocksCountByBlockVersion(nextBlockMajorVersion, topBlockIndex));

auto timestamps = mainChain->getLastTimestamps(blocksCount);
auto difficulties = mainChain->getLastCumulativeDifficulties(blocksCount);
Expand Down Expand Up @@ -627,6 +628,11 @@ std::error_code Core::addBlock(const CachedBlock& cachedBlock, RawBlock&& rawBlo
return blockValidationResult;
}

if (blockTemplate.majorVersion >= BLOCK_MAJOR_VERSION_5 && blockTemplate.transactionHashes.size() < 1) {
logger(Logging::WARNING) << "New block must have at least one transaction";
return error::BlockValidationError::NOT_ENOUGH_TRANSACTIONS;
}

auto currentDifficulty = cache->getDifficultyForNextBlock(previousBlockIndex);
if (currentDifficulty == 0) {
logger(Logging::DEBUGGING) << "Block " << blockStr << " has difficulty overhead";
Expand Down Expand Up @@ -1090,7 +1096,15 @@ bool Core::getBlockTemplate(BlockTemplate& b, const AccountPublicAddress& adr, c
b.previousBlockHash = getTopBlockHash();
b.timestamp = time(nullptr);

uint64_t blockchain_timestamp_check_window = parameters::BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW;
uint64_t blockchain_timestamp_check_window;
if (height >= parameters::LWMA_2_DIFFICULTY_BLOCK_INDEX)
{
blockchain_timestamp_check_window = parameters::BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW_V3;
}
else
{
blockchain_timestamp_check_window = parameters::BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW;
}
/* Skip the first N blocks, we don't have enough blocks to calculate a proper median yet */
if (height >= blockchain_timestamp_check_window)
{
Expand Down Expand Up @@ -1183,6 +1197,11 @@ bool Core::getBlockTemplate(BlockTemplate& b, const AccountPublicAddress& adr, c
return false;
}

if (b.majorVersion >= BLOCK_MAJOR_VERSION_5 && b.transactionHashes.size() < 1) {
logger(Logging::ERROR, Logging::BRIGHT_RED) << "New block must have at least one transaction";
return false;
}

return true;
}

Expand Down Expand Up @@ -1442,6 +1461,7 @@ std::error_code Core::validateBlock(const CachedBlock& cachedBlock, IBlockchainC
minerReward = 0;

if (upgradeManager->getBlockMajorVersion(cachedBlock.getBlockIndex()) != block.majorVersion) {
logger(Logging::ERROR, Logging::BRIGHT_RED) << "Expected block major version " << static_cast<int>(upgradeManager->getBlockMajorVersion(cachedBlock.getBlockIndex())) << ", got " << static_cast<int>(block.majorVersion);
return error::BlockValidationError::WRONG_VERSION;
}

Expand All @@ -1458,7 +1478,7 @@ std::error_code Core::validateBlock(const CachedBlock& cachedBlock, IBlockchainC
}
}

if (block.timestamp > getAdjustedTime() + currency.blockFutureTimeLimit()) {
if (block.timestamp > getAdjustedTime() + currency.blockFutureTimeLimit(previousBlockIndex+1)) {
return error::BlockValidationError::TIMESTAMP_TOO_FAR_IN_FUTURE;
}

Expand Down Expand Up @@ -1904,7 +1924,7 @@ void Core::fillBlockTemplate(BlockTemplate& block, size_t medianSize, size_t max
block.transactionHashes.emplace_back(cachedTransaction.getTransactionHash());
logger(Logging::TRACE) << "Transaction " << cachedTransaction.getTransactionHash() << " included to block template";
} else {
logger(Logging::TRACE) << "Transaction " << cachedTransaction.getTransactionHash() << " is failed to include to block template";
logger(Logging::TRACE) << "Failed to include transaction " << cachedTransaction.getTransactionHash() << " to block template";
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/CryptoNoteCore/CryptoNoteSerialization.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// Copyright (c) 2012-2017, The CryptoNote developers, The Bytecoin developers
// Copyright (c) 2018-2019, The Bittorium developers
//
// This file is part of Bytecoin.
//
Expand Down Expand Up @@ -366,7 +367,7 @@ void serialize(ParentBlockSerializer& pbs, ISerializer& serializer) {

void serializeBlockHeader(BlockHeader& header, ISerializer& serializer) {
serializer(header.majorVersion, "major_version");
if (header.majorVersion > BLOCK_MAJOR_VERSION_4) {
if (header.majorVersion > BLOCK_MAJOR_VERSION_5) {
throw std::runtime_error("Wrong major version");
}

Expand Down
Loading

0 comments on commit 4c5a9b9

Please sign in to comment.