text: // Copyright (c) 2012-2017, The CryptoNote developers, The Bytecoin developers
  // Copyright (c) 2014-2018, The Monero Project
  // Copyright (c) 2018, The TurtleCoin Developers
  // Copyright (c) 2018, The BLOC Developers
  //
  // Please see the included LICENSE file for more information.
  
  #pragma once
  
  #include <cstddef>
  #include <cstdint>
  #include <string>
  #include <limits>
  #include <initializer_list>
  #include <boost/uuid/uuid.hpp>
  
  namespace CryptoNote {
  namespace parameters {
  
  const uint64_t DIFFICULTY_TARGET                             = 120; // seconds
  
  const uint32_t CRYPTONOTE_MAX_BLOCK_NUMBER                   = 500000000;
  const size_t   CRYPTONOTE_MAX_BLOCK_BLOB_SIZE                = 500000000;
  const size_t   CRYPTONOTE_MAX_TX_SIZE                        = 1000000000;
  const uint64_t CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX       = 249588424;
  const uint32_t CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW          = 50;
  const uint64_t CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT            = 60 * 60 * 2;
  const uint64_t CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT_V3         = 3 * DIFFICULTY_TARGET;
  const uint64_t CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT_V4         = 6 * DIFFICULTY_TARGET;
  
  const size_t   BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW             = 60;
  const size_t   BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW_V3          = 11;
  
  // MONEY_SUPPLY - total number coins to be generated
  const uint64_t MONEY_SUPPLY                                  = UINT64_C(500000000000);
  const uint32_t ZAWY_DIFFICULTY_BLOCK_INDEX                   = 40500;
  const size_t   ZAWY_DIFFICULTY_V2                            = 0;
  const uint8_t  ZAWY_DIFFICULTY_DIFFICULTY_BLOCK_VERSION      = 4;
  
  const uint64_t LWMA_2_DIFFICULTY_BLOCK_INDEX                 = 40500;
  const uint64_t LWMA_2_DIFFICULTY_BLOCK_INDEX_V2              = 40500;
  //const uint64_t LWMA_2_DIFFICULTY_BLOCK_INDEX_V3              = 40000;
  
  //const uint64_t LWMA_3_DIFFICULTY_BLOCK_INDEX                 = 40000;
  
  const unsigned EMISSION_SPEED_FACTOR                         = 21;
  static_assert(EMISSION_SPEED_FACTOR <= 8 * sizeof(uint64_t), "Bad EMISSION_SPEED_FACTOR");
  
  /* Premine amount */
  const uint64_t GENESIS_BLOCK_REWARD                          = UINT64_C(0);
  
  /* How to generate a premine:
  
  * Compile your code
  
  * Run BLOCWallet, ignore that it can't connect to the daemon, and generate an
    address. Save this and the keys somewhere safe.
  
  * Launch the daemon with these arguments:
  --print-genesis-tx --genesis-block-reward-address <premine wallet address>
  
  For example:
  BLOCd --print-genesis-tx --genesis-block-reward-address abLocA4HEsaDXSJHLFMZW4LjQ1c2PExVbLHwq4GW6nZN3njc6LbgRZSKTzV9Jr8zDsC4q3FPg3emoCbsGxYz2i3XJzWzqkkKjrm
  
  * Take the hash printed, and replace it with the hash below in GENESIS_COINBASE_TX_HEX
  
  * Recompile, setup your seed nodes, and start mining
  
  * You should see your premine appear in the previously generated wallet.
  
  */
  const char     GENESIS_COINBASE_TX_HEX[]                     = "010a01ff000180e8eda1ba0102d0c75826c2f5c0e2e3eb082c66b0225fbef62f4df14bcf42150e7617b0291749210142a0214c40b4161a575ed4427aa009e29a907647af2699b7505fb3c7986d9d81";
  static_assert(sizeof(GENESIS_COINBASE_TX_HEX)/sizeof(*GENESIS_COINBASE_TX_HEX) != 1, "GENESIS_COINBASE_TX_HEX must not be empty.");
  
  /* This is the unix timestamp of the first "mined" block (technically block 2, not the genesis block)
     You can get this value by doing "print_block 2" in BLOCd. It is used to know what timestamp
     to import from when the block height cannot be found in the node or the node is offline. */
  const uint64_t GENESIS_BLOCK_TIMESTAMP                       = 1525226704;
  
  const size_t   CRYPTONOTE_REWARD_BLOCKS_WINDOW               = 100;
  const size_t   CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE     = 1000000; //size of block (bytes) after which reward for block calculated using block size
  const size_t   CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2  = 1000000;
  const size_t   CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V1  = 1000000;
  const size_t   CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_CURRENT = CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE;
  const size_t   CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE        = 600;
  
  const size_t   CRYPTONOTE_DISPLAY_DECIMAL_POINT              = 4;
  
  const uint64_t MINIMUM_FEE                                   = UINT64_C(1);
  
  /* This section defines our minimum and maximum mixin counts required for transactions */
  const uint64_t MINIMUM_MIXIN_V1                              = 0;
  const uint64_t MAXIMUM_MIXIN_V1                              = 10;
  
  const uint64_t MINIMUM_MIXIN_V2                              = 0;
  const uint64_t MAXIMUM_MIXIN_V2                              = 10;
  
  const uint64_t MINIMUM_MIXIN_V3                              = 0;
  const uint64_t MAXIMUM_MIXIN_V3                              = 10;
  
  /* The heights to activate the mixin limits at */
  const uint32_t MIXIN_LIMITS_V1_HEIGHT                        = 5;
  const uint32_t MIXIN_LIMITS_V2_HEIGHT                        = 100;
  const uint32_t MIXIN_LIMITS_V3_HEIGHT                        = 40500;
  
  /* The mixin to use by default with zedwallet and turtle-service */
  /* DEFAULT_MIXIN_V0 is the mixin used before MIXIN_LIMITS_V1_HEIGHT is started */
  const uint64_t DEFAULT_MIXIN_V0                              = 3;
  const uint64_t DEFAULT_MIXIN_V1                              = 0;
  const uint64_t DEFAULT_MIXIN_V2                              = 0;
  const uint64_t DEFAULT_MIXIN_V3                              = 0;
  
  const uint64_t DEFAULT_DUST_THRESHOLD                        = UINT64_C(1);
  const uint64_t DEFAULT_DUST_THRESHOLD_V2                     = UINT64_C(1);
  
  const uint32_t DUST_THRESHOLD_V2_HEIGHT                      = MIXIN_LIMITS_V2_HEIGHT;
  const uint32_t FUSION_DUST_THRESHOLD_HEIGHT_V2               = 40500;
  const uint64_t EXPECTED_NUMBER_OF_BLOCKS_PER_DAY             = 24 * 60 * 60 / DIFFICULTY_TARGET;
  
  const size_t   DIFFICULTY_WINDOW                             = EXPECTED_NUMBER_OF_BLOCKS_PER_DAY;
  const size_t   DIFFICULTY_WINDOW_V1                          = 2880;
  const size_t   DIFFICULTY_WINDOW_V2                          = 2880;
  const uint64_t DIFFICULTY_WINDOW_V3                          = 60;
  const uint64_t DIFFICULTY_BLOCKS_COUNT_V3                    = DIFFICULTY_WINDOW_V3 + 1;
  const uint64_t FINAL_SUBSIDY_PER_MINUTE                      = UINT64_C(0);
  
  const size_t   DIFFICULTY_CUT                                = 60;  // timestamps to cut after sorting
  const size_t   DIFFICULTY_CUT_V1                             = 60;
  const size_t   DIFFICULTY_CUT_V2                             = 60;
  const size_t   DIFFICULTY_LAG                                = 15;  // !!!
  const size_t   DIFFICULTY_LAG_V1                             = 15;
  const size_t   DIFFICULTY_LAG_V2                             = 15;
  static_assert(2 * DIFFICULTY_CUT <= DIFFICULTY_WINDOW - 2, "Bad DIFFICULTY_WINDOW or DIFFICULTY_CUT");
  
  const size_t   MAX_BLOCK_SIZE_INITIAL                        = 20 * 1024;
  const uint64_t MAX_BLOCK_SIZE_GROWTH_SPEED_NUMERATOR         = 100 * 1024;
  const uint64_t MAX_BLOCK_SIZE_GROWTH_SPEED_DENOMINATOR       = 365 * 24 * 60 * 60 / DIFFICULTY_TARGET;
  const uint64_t MAX_BLOCK_SIZE_GROWTH_SPEED_NUMERATOR_V2      = 35 * 100 * 1024;
  const size_t   MAX_BLOCK_SIZE_ALLOWED_EVERY_N_BLOCK          = 10; // every 10 blocks, 1 big block is allowed
  const uint64_t MAX_EXTRA_SIZE                                = 140000;
  
  const uint64_t CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_BLOCKS     = 1;
  const uint64_t CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS    = DIFFICULTY_TARGET * CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_BLOCKS;
  
  const uint64_t CRYPTONOTE_MEMPOOL_TX_LIVETIME                = 60 * 60 * 24;     //seconds, one day
  const uint64_t CRYPTONOTE_MEMPOOL_TX_FROM_ALT_BLOCK_LIVETIME = 60 * 60 * 24 * 7; //seconds, one week
  const uint64_t CRYPTONOTE_NUMBER_OF_PERIODS_TO_FORGET_TX_DELETED_FROM_POOL = 7;  // CRYPTONOTE_NUMBER_OF_PERIODS_TO_FORGET_TX_DELETED_FROM_POOL * CRYPTONOTE_MEMPOOL_TX_LIVETIME = time to forget tx
  
  const size_t   FUSION_TX_MAX_SIZE                            = CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_CURRENT * 30 / 100;
  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_MAX_BLOCK_SIZE                 = 65000;
  
  const uint32_t UPGRADE_HEIGHT_V2                             = 50;
  const uint32_t UPGRADE_HEIGHT_V3                             = 100;
  const uint32_t UPGRADE_HEIGHT_V4                             = 40500; // Upgrade height for CN-Heavy Variant Haven (xhv).
  const uint32_t UPGRADE_HEIGHT_CURRENT                        = UPGRADE_HEIGHT_V4;
  
  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 int64_t POISSON_CHECK_TRIGGER = 10; //Reorg size to trigger check
  const int64_t POISSON_CHECK_DEPTH = 60; //Reorg size to trigger check
  const double POISSON_CHECK_LOGP = -75.0; //Reject blocks that are less likely than e^-75.0
  
  /* Block heights we are going to have hard forks at */
  const uint64_t FORK_HEIGHTS[] =
  {
      1,
  	50,
  	100,
  	40500,
  };
  
  /* MAKE SURE TO UPDATE THIS VALUE WITH EVERY MAJOR RELEASE BEFORE A FORK */
  const uint64_t SOFTWARE_SUPPORTED_FORK_INDEX                 = 3;
  
  const uint64_t FORK_HEIGHTS_SIZE = sizeof(FORK_HEIGHTS) / sizeof(*FORK_HEIGHTS);
  
  /* The index in the FORK_HEIGHTS array that this version of the software will
     support. For example, if CURRENT_FORK_INDEX is 3, this version of the
     software will support the fork at 600,000 blocks.
  
     This will default to zero if the FORK_HEIGHTS array is empty, so you don't
     need to change it manually. */
  const uint8_t CURRENT_FORK_INDEX = FORK_HEIGHTS_SIZE == 0 ? 0 : SOFTWARE_SUPPORTED_FORK_INDEX;
  
  static_assert(CURRENT_FORK_INDEX >= 0, "CURRENT FORK INDEX must be >= 0");
  /* Make sure CURRENT_FORK_INDEX is a valid index, unless FORK_HEIGHTS is empty */
  static_assert(FORK_HEIGHTS_SIZE == 0 || CURRENT_FORK_INDEX < FORK_HEIGHTS_SIZE, "CURRENT_FORK_INDEX out of range of FORK_HEIGHTS!");
  
  const char     CRYPTONOTE_BLOCKS_FILENAME[]                  = "blocks.bin";
  const char     CRYPTONOTE_BLOCKINDEXES_FILENAME[]            = "blockindexes.bin";
  const char     CRYPTONOTE_POOLDATA_FILENAME[]                = "poolstate.bin";
  const char     P2P_NET_DATA_FILENAME[]                       = "p2pstate.bin";
  const char     MINER_CONFIG_FILE_NAME[]                      = "miner_conf.json";
  } // parameters
  
  const char     CRYPTONOTE_NAME[]                             = "BLOC";
  
  const uint8_t  TRANSACTION_VERSION_1                         =  1;
  const uint8_t  TRANSACTION_VERSION_2                         =  2;
  const uint8_t  CURRENT_TRANSACTION_VERSION                   =  TRANSACTION_VERSION_1;
  
  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_MINOR_VERSION_0                         =  0;
  const uint8_t  BLOCK_MINOR_VERSION_1                         =  0;
  
  const size_t   BLOCKS_IDS_SYNCHRONIZING_DEFAULT_COUNT        =  10000;  //by default, blocks ids count in synchronizing
  const size_t   BLOCKS_SYNCHRONIZING_DEFAULT_COUNT            =  100;    //by default, blocks count in blocks downloading
  const size_t   COMMAND_RPC_GET_BLOCKS_FAST_MAX_COUNT         =  1000;
  
  const int      P2P_DEFAULT_PORT                              =  2082;
  const int      RPC_DEFAULT_PORT                              =  2086;
  const int      SERVICE_DEFAULT_PORT                          =  8070;
  
  const size_t   P2P_LOCAL_WHITE_PEERLIST_LIMIT                =  1000;
  const size_t   P2P_LOCAL_GRAY_PEERLIST_LIMIT                 =  5000;
  
  // P2P Network Configuration Section - This defines our current P2P network version
  // and the minimum version for communication between nodes
  const uint8_t  P2P_CURRENT_VERSION                           = 3;
  const uint8_t  P2P_MINIMUM_VERSION                           = 1;
  // This defines the number of versions ahead we must see peers before we start displaying
  // warning messages that we need to upgrade our software.
  const uint8_t  P2P_UPGRADE_WINDOW                            = 2;
  
  const size_t   P2P_CONNECTION_MAX_WRITE_BUFFER_SIZE          = 32 * 1024 * 1024; // 32 MB
  const uint32_t P2P_DEFAULT_CONNECTIONS_COUNT                 = 8;
  const size_t   P2P_DEFAULT_WHITELIST_CONNECTIONS_PERCENT     = 70;
  const uint32_t P2P_DEFAULT_HANDSHAKE_INTERVAL                = 60;            // seconds
  const uint32_t P2P_DEFAULT_PACKET_MAX_SIZE                   = 50000000;      // 50000000 bytes maximum packet size
  const uint32_t P2P_DEFAULT_PEERS_IN_HANDSHAKE                = 250;
  const uint32_t P2P_DEFAULT_CONNECTION_TIMEOUT                = 5000;          // 5 seconds
  const uint32_t P2P_DEFAULT_PING_CONNECTION_TIMEOUT           = 2000;          // 2 seconds
  const uint64_t P2P_DEFAULT_INVOKE_TIMEOUT                    = 60 * 2 * 1000; // 2 minutes
  const size_t   P2P_DEFAULT_HANDSHAKE_INVOKE_TIMEOUT          = 5000;          // 5 seconds
  const char     P2P_STAT_TRUSTED_PUB_KEY[]                    = "";
  
  const uint64_t DATABASE_WRITE_BUFFER_MB_DEFAULT_SIZE         = 256;
  const uint64_t DATABASE_READ_BUFFER_MB_DEFAULT_SIZE          = 10;
  const uint32_t DATABASE_DEFAULT_MAX_OPEN_FILES               = 100;
  const uint16_t DATABASE_DEFAULT_BACKGROUND_THREADS_COUNT     = 2;
  
  const char     LATEST_VERSION_URL[]                          = "https://bloc.money/download";
  const std::string LICENSE_URL                                = "https://github.com/furiousteam/BLOC/blob/master/LICENSE";
  const static   boost::uuids::uuid CRYPTONOTE_NETWORK         =
  {
      {  0x21, 0x21, 0x32, 0xf2, 0x2f, 0x29, 0x2c, 0x23, 0x22, 0x8f, 0x8c, 0x12, 0x37, 0x27, 0x9d, 0x98  }
  };
  
  const char* const SEED_NODES[] = {
      "174.138.59.135:2082",//atlantic
      "138.197.208.94:2082",//pacific
   	"95.216.3.162:2082",//baltic
   	"88.198.57.162:2082",//europe
   	"206.189.42.115:2082"//asia
  };
  } // CryptoNote
  