2015-09-18 11:55:31 +00:00
|
|
|
// Copyright (c) 2011-2015 The Cryptonote developers
|
|
|
|
// Distributed under the MIT/X11 software license, see the accompanying
|
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
2014-08-13 10:51:37 +00:00
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <cstdint>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
#include <boost/utility.hpp>
|
2015-07-30 15:22:07 +00:00
|
|
|
#include "../CryptoNoteConfig.h"
|
2015-05-27 12:08:46 +00:00
|
|
|
#include "../crypto/hash.h"
|
|
|
|
#include "../Logging/LoggerRef.h"
|
2015-07-30 15:22:07 +00:00
|
|
|
#include "CryptoNoteBasic.h"
|
|
|
|
#include "Difficulty.h"
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
namespace CryptoNote {
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
class AccountBase;
|
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
class Currency {
|
|
|
|
public:
|
|
|
|
uint64_t maxBlockHeight() const { return m_maxBlockHeight; }
|
|
|
|
size_t maxBlockBlobSize() const { return m_maxBlockBlobSize; }
|
|
|
|
size_t maxTxSize() const { return m_maxTxSize; }
|
|
|
|
uint64_t publicAddressBase58Prefix() const { return m_publicAddressBase58Prefix; }
|
|
|
|
size_t minedMoneyUnlockWindow() const { return m_minedMoneyUnlockWindow; }
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
size_t timestampCheckWindow() const { return m_timestampCheckWindow; }
|
|
|
|
uint64_t blockFutureTimeLimit() const { return m_blockFutureTimeLimit; }
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
uint64_t moneySupply() const { return m_moneySupply; }
|
|
|
|
unsigned int emissionSpeedFactor() const { return m_emissionSpeedFactor; }
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
size_t rewardBlocksWindow() const { return m_rewardBlocksWindow; }
|
|
|
|
size_t blockGrantedFullRewardZone() const { return m_blockGrantedFullRewardZone; }
|
|
|
|
size_t minerTxBlobReservedSize() const { return m_minerTxBlobReservedSize; }
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
size_t numberOfDecimalPlaces() const { return m_numberOfDecimalPlaces; }
|
|
|
|
uint64_t coin() const { return m_coin; }
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
uint64_t minimumFee() const { return m_mininumFee; }
|
|
|
|
uint64_t defaultDustThreshold() const { return m_defaultDustThreshold; }
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
uint64_t difficultyTarget() const { return m_difficultyTarget; }
|
|
|
|
size_t difficultyWindow() const { return m_difficultyWindow; }
|
|
|
|
size_t difficultyLag() const { return m_difficultyLag; }
|
|
|
|
size_t difficultyCut() const { return m_difficultyCut; }
|
|
|
|
size_t difficultyBlocksCount() const { return m_difficultyWindow + m_difficultyLag; }
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
size_t maxBlockSizeInitial() const { return m_maxBlockSizeInitial; }
|
|
|
|
uint64_t maxBlockSizeGrowthSpeedNumerator() const { return m_maxBlockSizeGrowthSpeedNumerator; }
|
|
|
|
uint64_t maxBlockSizeGrowthSpeedDenominator() const { return m_maxBlockSizeGrowthSpeedDenominator; }
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
uint64_t lockedTxAllowedDeltaSeconds() const { return m_lockedTxAllowedDeltaSeconds; }
|
|
|
|
size_t lockedTxAllowedDeltaBlocks() const { return m_lockedTxAllowedDeltaBlocks; }
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
uint64_t mempoolTxLiveTime() const { return m_mempoolTxLiveTime; }
|
|
|
|
uint64_t mempoolTxFromAltBlockLiveTime() const { return m_mempoolTxFromAltBlockLiveTime; }
|
2015-07-15 12:23:00 +00:00
|
|
|
uint64_t numberOfPeriodsToForgetTxDeletedFromPool() const { return m_numberOfPeriodsToForgetTxDeletedFromPool; }
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-08-11 14:33:19 +00:00
|
|
|
size_t fusionTxMaxSize() const { return m_fusionTxMaxSize; }
|
|
|
|
size_t fusionTxMinInputCount() const { return m_fusionTxMinInputCount; }
|
|
|
|
size_t fusionTxMinInOutCountRatio() const { return m_fusionTxMinInOutCountRatio; }
|
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
const std::string& blocksFileName() const { return m_blocksFileName; }
|
|
|
|
const std::string& blocksCacheFileName() const { return m_blocksCacheFileName; }
|
|
|
|
const std::string& blockIndexesFileName() const { return m_blockIndexesFileName; }
|
|
|
|
const std::string& txPoolFileName() const { return m_txPoolFileName; }
|
2015-07-30 15:22:07 +00:00
|
|
|
const std::string& blockchinIndicesFileName() const { return m_blockchinIndicesFileName; }
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
bool isTestnet() const { return m_testnet; }
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
const Block& genesisBlock() const { return m_genesisBlock; }
|
2015-07-30 15:22:07 +00:00
|
|
|
const Crypto::Hash& genesisBlockHash() const { return m_genesisBlockHash; }
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
bool getBlockReward(size_t medianSize, size_t currentBlockSize, uint64_t alreadyGeneratedCoins, uint64_t fee,
|
2015-09-18 11:55:31 +00:00
|
|
|
uint64_t& reward, int64_t& emissionChange) const;
|
2015-05-27 12:08:46 +00:00
|
|
|
size_t maxBlockCumulativeSize(uint64_t height) const;
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
bool constructMinerTx(uint32_t height, size_t medianSize, uint64_t alreadyGeneratedCoins, size_t currentBlockSize,
|
|
|
|
uint64_t fee, const AccountPublicAddress& minerAddress, Transaction& tx,
|
2015-09-18 11:55:31 +00:00
|
|
|
const BinaryArray& extraNonce = BinaryArray(), size_t maxOuts = 1) const;
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-08-11 14:33:19 +00:00
|
|
|
bool isFusionTransaction(const Transaction& transaction) const;
|
2015-08-27 18:55:14 +00:00
|
|
|
bool isFusionTransaction(const Transaction& transaction, size_t size) const;
|
|
|
|
bool isFusionTransaction(const std::vector<uint64_t>& inputsAmounts, const std::vector<uint64_t>& outputsAmounts, size_t size) const;
|
|
|
|
bool isAmountApplicableInFusionTransactionInput(uint64_t amount, uint64_t threshold) const;
|
|
|
|
bool isAmountApplicableInFusionTransactionInput(uint64_t amount, uint64_t threshold, uint8_t& amountPowerOfTen) const;
|
2015-08-11 14:33:19 +00:00
|
|
|
|
2015-07-30 15:22:07 +00:00
|
|
|
std::string accountAddressAsString(const AccountBase& account) const;
|
2015-07-15 12:23:00 +00:00
|
|
|
std::string accountAddressAsString(const AccountPublicAddress& accountPublicAddress) const;
|
2015-05-27 12:08:46 +00:00
|
|
|
bool parseAccountAddressString(const std::string& str, AccountPublicAddress& addr) const;
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
std::string formatAmount(uint64_t amount) const;
|
2015-08-11 14:33:19 +00:00
|
|
|
std::string formatAmount(int64_t amount) const;
|
2015-05-27 12:08:46 +00:00
|
|
|
bool parseAmount(const std::string& str, uint64_t& amount) const;
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
difficulty_type nextDifficulty(std::vector<uint64_t> timestamps, std::vector<difficulty_type> cumulativeDifficulties) const;
|
2015-07-30 15:22:07 +00:00
|
|
|
bool checkProofOfWork(Crypto::cn_context& context, const Block& block, difficulty_type currentDiffic, Crypto::Hash& proofOfWork) const;
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-08-27 18:55:14 +00:00
|
|
|
size_t getApproximateMaximumInputCount(size_t transactionSize, size_t outputCount, size_t mixinCount) const;
|
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
private:
|
|
|
|
Currency(Logging::ILogger& log) : logger(log, "currency") {
|
|
|
|
}
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
bool init();
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
bool generateGenesisBlock();
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
private:
|
|
|
|
uint64_t m_maxBlockHeight;
|
|
|
|
size_t m_maxBlockBlobSize;
|
|
|
|
size_t m_maxTxSize;
|
|
|
|
uint64_t m_publicAddressBase58Prefix;
|
|
|
|
size_t m_minedMoneyUnlockWindow;
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
size_t m_timestampCheckWindow;
|
|
|
|
uint64_t m_blockFutureTimeLimit;
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
uint64_t m_moneySupply;
|
|
|
|
unsigned int m_emissionSpeedFactor;
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
size_t m_rewardBlocksWindow;
|
|
|
|
size_t m_blockGrantedFullRewardZone;
|
|
|
|
size_t m_minerTxBlobReservedSize;
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
size_t m_numberOfDecimalPlaces;
|
|
|
|
uint64_t m_coin;
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
uint64_t m_mininumFee;
|
|
|
|
uint64_t m_defaultDustThreshold;
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
uint64_t m_difficultyTarget;
|
|
|
|
size_t m_difficultyWindow;
|
|
|
|
size_t m_difficultyLag;
|
|
|
|
size_t m_difficultyCut;
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
size_t m_maxBlockSizeInitial;
|
|
|
|
uint64_t m_maxBlockSizeGrowthSpeedNumerator;
|
|
|
|
uint64_t m_maxBlockSizeGrowthSpeedDenominator;
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
uint64_t m_lockedTxAllowedDeltaSeconds;
|
|
|
|
size_t m_lockedTxAllowedDeltaBlocks;
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
uint64_t m_mempoolTxLiveTime;
|
|
|
|
uint64_t m_mempoolTxFromAltBlockLiveTime;
|
2015-07-15 12:23:00 +00:00
|
|
|
uint64_t m_numberOfPeriodsToForgetTxDeletedFromPool;
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-08-11 14:33:19 +00:00
|
|
|
size_t m_fusionTxMaxSize;
|
|
|
|
size_t m_fusionTxMinInputCount;
|
|
|
|
size_t m_fusionTxMinInOutCountRatio;
|
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
std::string m_blocksFileName;
|
|
|
|
std::string m_blocksCacheFileName;
|
|
|
|
std::string m_blockIndexesFileName;
|
|
|
|
std::string m_txPoolFileName;
|
2015-07-30 15:22:07 +00:00
|
|
|
std::string m_blockchinIndicesFileName;
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-08-27 18:55:14 +00:00
|
|
|
static const std::vector<uint64_t> PRETTY_AMOUNTS;
|
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
bool m_testnet;
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
Block m_genesisBlock;
|
2015-07-30 15:22:07 +00:00
|
|
|
Crypto::Hash m_genesisBlockHash;
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
Logging::LoggerRef logger;
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
friend class CurrencyBuilder;
|
|
|
|
};
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
class CurrencyBuilder : boost::noncopyable {
|
|
|
|
public:
|
|
|
|
CurrencyBuilder(Logging::ILogger& log);
|
|
|
|
|
|
|
|
Currency currency() {
|
|
|
|
if (!m_currency.init()) {
|
|
|
|
throw std::runtime_error("Failed to initialize currency object");
|
2014-08-13 10:51:37 +00:00
|
|
|
}
|
2015-05-27 12:08:46 +00:00
|
|
|
return m_currency;
|
|
|
|
}
|
|
|
|
|
2015-09-18 11:55:31 +00:00
|
|
|
Transaction generateGenesisTransaction();
|
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
CurrencyBuilder& maxBlockNumber(uint64_t val) { m_currency.m_maxBlockHeight = val; return *this; }
|
|
|
|
CurrencyBuilder& maxBlockBlobSize(size_t val) { m_currency.m_maxBlockBlobSize = val; return *this; }
|
|
|
|
CurrencyBuilder& maxTxSize(size_t val) { m_currency.m_maxTxSize = val; return *this; }
|
|
|
|
CurrencyBuilder& publicAddressBase58Prefix(uint64_t val) { m_currency.m_publicAddressBase58Prefix = val; return *this; }
|
|
|
|
CurrencyBuilder& minedMoneyUnlockWindow(size_t val) { m_currency.m_minedMoneyUnlockWindow = val; return *this; }
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
CurrencyBuilder& timestampCheckWindow(size_t val) { m_currency.m_timestampCheckWindow = val; return *this; }
|
|
|
|
CurrencyBuilder& blockFutureTimeLimit(uint64_t val) { m_currency.m_blockFutureTimeLimit = val; return *this; }
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
CurrencyBuilder& moneySupply(uint64_t val) { m_currency.m_moneySupply = val; return *this; }
|
|
|
|
CurrencyBuilder& emissionSpeedFactor(unsigned int val);
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
CurrencyBuilder& rewardBlocksWindow(size_t val) { m_currency.m_rewardBlocksWindow = val; return *this; }
|
|
|
|
CurrencyBuilder& blockGrantedFullRewardZone(size_t val) { m_currency.m_blockGrantedFullRewardZone = val; return *this; }
|
|
|
|
CurrencyBuilder& minerTxBlobReservedSize(size_t val) { m_currency.m_minerTxBlobReservedSize = val; return *this; }
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
CurrencyBuilder& numberOfDecimalPlaces(size_t val);
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
CurrencyBuilder& mininumFee(uint64_t val) { m_currency.m_mininumFee = val; return *this; }
|
|
|
|
CurrencyBuilder& defaultDustThreshold(uint64_t val) { m_currency.m_defaultDustThreshold = val; return *this; }
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
CurrencyBuilder& difficultyTarget(uint64_t val) { m_currency.m_difficultyTarget = val; return *this; }
|
|
|
|
CurrencyBuilder& difficultyWindow(size_t val);
|
|
|
|
CurrencyBuilder& difficultyLag(size_t val) { m_currency.m_difficultyLag = val; return *this; }
|
|
|
|
CurrencyBuilder& difficultyCut(size_t val) { m_currency.m_difficultyCut = val; return *this; }
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
CurrencyBuilder& maxBlockSizeInitial(size_t val) { m_currency.m_maxBlockSizeInitial = val; return *this; }
|
|
|
|
CurrencyBuilder& maxBlockSizeGrowthSpeedNumerator(uint64_t val) { m_currency.m_maxBlockSizeGrowthSpeedNumerator = val; return *this; }
|
|
|
|
CurrencyBuilder& maxBlockSizeGrowthSpeedDenominator(uint64_t val) { m_currency.m_maxBlockSizeGrowthSpeedDenominator = val; return *this; }
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
CurrencyBuilder& lockedTxAllowedDeltaSeconds(uint64_t val) { m_currency.m_lockedTxAllowedDeltaSeconds = val; return *this; }
|
|
|
|
CurrencyBuilder& lockedTxAllowedDeltaBlocks(size_t val) { m_currency.m_lockedTxAllowedDeltaBlocks = val; return *this; }
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
CurrencyBuilder& mempoolTxLiveTime(uint64_t val) { m_currency.m_mempoolTxLiveTime = val; return *this; }
|
|
|
|
CurrencyBuilder& mempoolTxFromAltBlockLiveTime(uint64_t val) { m_currency.m_mempoolTxFromAltBlockLiveTime = val; return *this; }
|
2015-07-15 12:23:00 +00:00
|
|
|
CurrencyBuilder& numberOfPeriodsToForgetTxDeletedFromPool(uint64_t val) { m_currency.m_numberOfPeriodsToForgetTxDeletedFromPool = val; return *this; }
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-08-11 14:33:19 +00:00
|
|
|
CurrencyBuilder& fusionTxMaxSize(size_t val) { m_currency.m_fusionTxMaxSize = val; return *this; }
|
|
|
|
CurrencyBuilder& fusionTxMinInputCount(size_t val) { m_currency.m_fusionTxMinInputCount = val; return *this; }
|
|
|
|
CurrencyBuilder& fusionTxMinInOutCountRatio(size_t val) { m_currency.m_fusionTxMinInOutCountRatio = val; return *this; }
|
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
CurrencyBuilder& blocksFileName(const std::string& val) { m_currency.m_blocksFileName = val; return *this; }
|
|
|
|
CurrencyBuilder& blocksCacheFileName(const std::string& val) { m_currency.m_blocksCacheFileName = val; return *this; }
|
|
|
|
CurrencyBuilder& blockIndexesFileName(const std::string& val) { m_currency.m_blockIndexesFileName = val; return *this; }
|
|
|
|
CurrencyBuilder& txPoolFileName(const std::string& val) { m_currency.m_txPoolFileName = val; return *this; }
|
2015-07-30 15:22:07 +00:00
|
|
|
CurrencyBuilder& blockchinIndicesFileName(const std::string& val) { m_currency.m_blockchinIndicesFileName = val; return *this; }
|
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
CurrencyBuilder& testnet(bool val) { m_currency.m_testnet = val; return *this; }
|
2014-08-13 10:51:37 +00:00
|
|
|
|
2015-05-27 12:08:46 +00:00
|
|
|
private:
|
|
|
|
Currency m_currency;
|
|
|
|
};
|
2014-08-13 10:51:37 +00:00
|
|
|
|
|
|
|
}
|