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

Commit

Permalink
Version 2.0.4 -- Add support for hard fork 1.
Browse files Browse the repository at this point in the history
  • Loading branch information
mtl1979 committed May 16, 2019
1 parent b308827 commit a4206e4
Show file tree
Hide file tree
Showing 56 changed files with 1,056 additions and 179 deletions.
10 changes: 9 additions & 1 deletion cryptonote/.gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
.git* export-ignore
/CMakeLists.txt export-subst
/CMakeLists.txt export-subst
*.sh text eol=lf
*.h text
*.c text
*.cc text
*.cpp text
*.java text
*.md text
*.rc text eol=crlf
6 changes: 6 additions & 0 deletions cryptonote/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,9 @@ Run `./src/Bittoriumd` to connect to the network and let it sync (it may take a
#### Thanks
Cryptonote Developers, Bytecoin Developers, Monero Developers, TurtleCoin Developers, Forknote Project, PinkstarcoinV2 Developers, Bittorium Developers.
"# Bittorium"

#### Donate
Donate to our project and help us achieve more for you!
Our BTC Address: 326LiKxxdm9tJ2KPGG353PvfgiyNpYNoQ3


5 changes: 5 additions & 0 deletions cryptonote/include/INode.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, The Bittorium developers
//
// This file is part of Bytecoin.
//
Expand Down Expand Up @@ -99,6 +100,8 @@ class INode {
virtual uint32_t getLocalBlockCount() const = 0;
virtual uint32_t getKnownBlockCount() const = 0;
virtual uint64_t getLastLocalBlockTimestamp() const = 0;
virtual std::string getLastFeeAddress() const = 0;
virtual std::string getLastCollateralHash() const = 0;

virtual void getBlockHashesByTimestamps(uint64_t timestampBegin, size_t secondsCount, std::vector<Crypto::Hash>& blockHashes, const Callback& callback) = 0;
virtual void getTransactionHashesByPaymentId(const Crypto::Hash& paymentId, std::vector<Crypto::Hash>& transactionHashes, const Callback& callback) = 0;
Expand All @@ -116,6 +119,8 @@ class INode {
virtual void getBlocks(const std::vector<Crypto::Hash>& blockHashes, std::vector<BlockDetails>& blocks, const Callback& callback) = 0;
virtual void getBlock(const uint32_t blockHeight, BlockDetails &block, const Callback& callback) = 0;
virtual void getTransactions(const std::vector<Crypto::Hash>& transactionHashes, std::vector<TransactionDetails>& transactions, const Callback& callback) = 0;
virtual void getFeeAddress(std::string &feeAddress, const Callback& callback) = 0;
virtual void getCollateralHash(std::string &collateralHash, const Callback & callback) = 0;
virtual void isSynchronized(bool& syncStatus, const Callback& callback) = 0;
};

Expand Down
19 changes: 19 additions & 0 deletions cryptonote/src/Common/Util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,25 @@ std::string get_nix_version_display_string()

return "";
}

std::wstring get_special_folder_path_w(int nfolder, bool iscreate)
{
namespace fs = boost::filesystem;
wchar_t psz_path[MAX_PATH] = L"";

if (SHGetSpecialFolderPathW(NULL, psz_path, nfolder, iscreate)) {
return psz_path;
}

return L"";
}

std::wstring getDefaultDataDirectoryW()
{
std::wstring ws(strlen(CryptoNote::CRYPTONOTE_NAME), L' ');
ws.resize(std::mbstowcs(&ws[0], CryptoNote::CRYPTONOTE_NAME, strlen(CryptoNote::CRYPTONOTE_NAME)));
return get_special_folder_path_w(CSIDL_APPDATA, true) + std::wstring(L"/") + ws;
}
#endif

std::string getDefaultDataDirectory()
Expand Down
3 changes: 3 additions & 0 deletions cryptonote/src/Common/Util.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
namespace Tools
{
std::string getDefaultDataDirectory();
#ifdef WIN32
std::wstring getDefaultDataDirectoryW();
#endif
std::string getDefaultCacheFile(const std::string& dataDir);
std::string get_os_version_string();
bool create_directories_if_necessary(const std::string& path);
Expand Down
45 changes: 30 additions & 15 deletions cryptonote/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 Expand Up @@ -137,7 +150,9 @@ const char P2P_STAT_TRUSTED_PUB_KEY[] = "";

const char* const SEED_NODES[] = {
"95.216.187.5:34902",
"95.216.187.3:34902"
"95.216.187.3:34902",
"95.216.163.155:34902",
"193.70.84.52:34902"
};
} // CryptoNote

3 changes: 3 additions & 0 deletions cryptonote/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
15 changes: 13 additions & 2 deletions cryptonote/src/CryptoNoteCore/BlockchainCache.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 @@ -590,6 +591,16 @@ BinaryArray BlockchainCache::getRawTransaction(uint32_t index, uint32_t transact
}
}

BinaryArray BlockchainCache::getRawTransaction(const Crypto::Hash &transaction) const {
auto& index = transactions.get<TransactionHashTag>();
auto it = index.find(transaction);
if (it == index.end()) {
return parent->getRawTransaction(transaction);
}

return getRawTransaction(it->blockIndex, it->transactionIndex);
}

std::vector<BinaryArray>
BlockchainCache::getRawTransactions(const std::vector<Crypto::Hash>& requestedTransactions) const {
std::vector<Crypto::Hash> misses;
Expand Down Expand Up @@ -957,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
3 changes: 3 additions & 0 deletions cryptonote/src/CryptoNoteCore/BlockchainCache.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, The Bittorium developers
//
// This file is part of Bytecoin.
//
Expand Down Expand Up @@ -177,6 +178,8 @@ class BlockchainCache : public IBlockchainCache {
std::vector<Crypto::Hash> &missedTransactions) const override;
virtual RawBlock getBlockByIndex(uint32_t index) const override;
virtual BinaryArray getRawTransaction(uint32_t blockIndex, uint32_t transactionIndex) const override;
virtual BinaryArray getRawTransaction(const Crypto::Hash &transaction) const override;

virtual std::vector<Crypto::Hash> getTransactionHashes() const override;
virtual std::vector<uint32_t> getRandomOutsByAmount(uint64_t amount, size_t count, uint32_t blockIndex) const override;
virtual ExtractOutputKeysResult extractKeyOutputs(uint64_t amount, uint32_t blockIndex, Common::ArrayView<uint32_t> globalIndexes,
Expand Down
62 changes: 58 additions & 4 deletions cryptonote/src/CryptoNoteCore/Core.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 @@ -200,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 @@ -458,6 +460,39 @@ bool Core::queryBlocksLite(const std::vector<Crypto::Hash>& knownBlockHashes, ui
}
}

bool Core::getTransaction(const Crypto::Hash& transactionHash, BinaryArray& transaction) const {
assert(!chainsLeaves.empty());
assert(!chainsStorage.empty());
throwIfNotInitialized();

IBlockchainCache* segment = chainsLeaves[0];
assert(segment != nullptr);

// find in main chain
do {
if (segment->hasTransaction(transactionHash)) {
transaction = segment->getRawTransaction(transactionHash);
return true;
}
segment = segment->getParent();
} while (segment != nullptr);

// find in alternative chains
for (size_t chain = 1; chain < chainsLeaves.size(); ++chain) {
segment = chainsLeaves[chain];

while (mainChainSet.count(segment) == 0) {
if (segment->hasTransaction(transactionHash)) {
transaction = segment->getRawTransaction(transactionHash);
return true;
}
segment = segment->getParent();
}
}

return false;
}

void Core::getTransactions(const std::vector<Crypto::Hash>& transactionHashes, std::vector<BinaryArray>& transactions,
std::vector<Crypto::Hash>& missedHashes) const {
assert(!chainsLeaves.empty());
Expand Down Expand Up @@ -519,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 @@ -593,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 @@ -1056,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 @@ -1149,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 @@ -1408,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 @@ -1424,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 @@ -1870,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
1 change: 1 addition & 0 deletions cryptonote/src/CryptoNoteCore/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class Core : public ICore, public ICoreInformation {
uint32_t& startIndex, uint32_t& currentIndex, uint32_t& fullOffset, std::vector<BlockShortInfo>& entries) const override;

virtual bool hasTransaction(const Crypto::Hash& transactionHash) const override;
virtual bool getTransaction(const Crypto::Hash& transactionHash, BinaryArray& transaction) const;
virtual void getTransactions(const std::vector<Crypto::Hash>& transactionHashes, std::vector<BinaryArray>& transactions, std::vector<Crypto::Hash>& missedHashes) const override;

virtual Difficulty getBlockDifficulty(uint32_t blockIndex) const override;
Expand Down
Loading

0 comments on commit a4206e4

Please sign in to comment.