diff --git a/CMakeLists.txt b/CMakeLists.txt index c33f90c62d..7993997eb6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,7 +41,7 @@ if(MSVC) include_directories(SYSTEM src/platform/msc) else() if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") - # This option has no effect in glibc version less than 2.20. + # This option has no effect in glibc version less than 2.20. # Since glibc 2.20 _BSD_SOURCE is deprecated, this macro is recomended instead add_definitions("-D_DEFAULT_SOURCE -D_GNU_SOURCE") endif() @@ -85,7 +85,7 @@ else() set(RELEASE_FLAGS "-Ofast -DNDEBUG -Wno-unused-variable") if(NOT APPLE) # There is a clang bug that does not allow to compile code that uses AES-NI intrinsics if -flto is enabled - if (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_SYSTEM_NAME STREQUAL "Linux" + if (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_SYSTEM_NAME STREQUAL "Linux" AND CMAKE_BUILD_TYPE STREQUAL "Release" AND ((CMAKE_C_COMPILER_VERSION VERSION_GREATER 4.9) OR (CMAKE_C_COMPILER_VERSION VERSION_EQUAL 4.9))) # On linux, to build in lto mode, check that ld.gold linker is used: 'update-alternatives --install /usr/bin/ld ld /usr/bin/ld.gold HIGHEST_PRIORITY' set(CMAKE_AR gcc-ar) diff --git a/README.md b/README.md index 02819498ec..a0a7a6fe4c 100644 --- a/README.md +++ b/README.md @@ -1,207 +1,20 @@ -This is the reference code for [CryptoNote](https://cryptonote.org) cryptocurrency protocol. +## **Dogemone: The Future of Privacy Coins** -* Launch your own CryptoNote currency: [CryptoNote Starter](https://cryptonotestarter.org/) -* CryptoNote reference implementation: [CryptoNoteCoin](https://cryptonote-coin.org) -* Discussion board and support: [CryptoNote Forum](https://forum.cryptonote.org) +Dogemone is a cutting-edge privacy coin built on the robust Cryptonote protocol, ensuring unparalleled transaction confidentiality and security. With a maximum supply of 300 million, Dogemone follows a meticulously designed emission curve, providing a predictable and fair distribution over time. The coin leverages the Cryptonight algorithm, known for its ASIC resistance and efficiency in CPU and GPU mining, promoting decentralization. Dogemone is committed to protecting your financial privacy while maintaining a secure and decentralized network, making it a standout choice in the realm of cryptocurrency. Join us in shaping a future where privacy and security are paramount. -## CryptoNote forking how-to +### **Key Features:** +- **Privacy-Focused**: Utilizes Cryptonote protocol for untraceable and unlinkable transactions. +- **Controlled Supply**: Capped at 300 million coins with a fair emission curve. +- **Efficient Mining**: Cryptonight algorithm ensures equitable mining opportunities. +- **No Premine**: 100% fair launch with no premine. +- **Developer Fee**: 10% of the block reward is allocated to development, taken slowly over time. +- **Difficulty Adjustment**: Adaptive difficulty adjustment every 120 seconds for network stability. +- **Decentralized Network**: Promotes decentralization and security. -### Preparation +Embrace the future of privacy with Dogemone. -1. Create an account on [GitHub.com](github.com) -2. Fork [CryptoNote repository](https://github.com/cryptonotefoundation/cryptonote) -3. Buy one or two Ubuntu-based dedicated servers (at least 2Gb of RAM) for seed nodes. - - -### First step. Give a name to your coin - -**Good name must be unique.** Check uniqueness with [google](http://google.com) and [Map of Coins](mapofcoins.com) or any other similar service. - -Name must be specified twice: - -**1. in file src/CryptoNoteConfig.h** - `CRYPTONOTE_NAME` constant - -Example: -``` -const char CRYPTONOTE_NAME[] = "furiouscoin"; -``` - -**2. in src/CMakeList.txt file** - set_property(TARGET daemon PROPERTY OUTPUT_NAME "YOURCOINNAME**d**") - -Example: -``` -set_property(TARGET daemon PROPERTY OUTPUT_NAME "furiouscoind") -``` - -**Note:** You should also change a repository name. - - -### Second step. Emission logic - -**1. Total money supply** (src/CryptoNoteConfig.h) - -Total amount of coins to be emitted. Most of CryptoNote based coins use `(uint64_t)(-1)` (equals to 18446744073709551616). You can define number explicitly (for example `UINT64_C(858986905600000000)`). - -Example: -``` -const uint64_t MONEY_SUPPLY = (uint64_t)(-1); -``` - -**2. Emission curve** (src/CryptoNoteConfig.h) - -Be default CryptoNote provides emission formula with slight decrease of block reward with each block. This is different from Bitcoin where block reward halves every 4 years. - -`EMISSION_SPEED_FACTOR` constant defines emission curve slope. This parameter is required to calulate block reward. - -Example: -``` -const unsigned EMISSION_SPEED_FACTOR = 18; -``` - -**3. Difficulty target** (src/CryptoNoteConfig.h) - -Difficulty target is an ideal time period between blocks. In case an average time between blocks becomes less than difficulty target, the difficulty increases. Difficulty target is measured in seconds. - -Difficulty target directly influences several aspects of coin's behavior: - -- transaction confirmation speed: the longer the time between the blocks is, the slower transaction confirmation is -- emission speed: the longer the time between the blocks is the slower the emission process is -- orphan rate: chains with very fast blocks have greater orphan rate - -For most coins difficulty target is 60 or 120 seconds. - -Example: -``` -const uint64_t DIFFICULTY_TARGET = 120; -``` - -**4. Block reward formula** - -In case you are not satisfied with CryptoNote default implementation of block reward logic you can also change it. The implementation is in `src/CryptoNoteCore/Currency.cpp`: -``` -bool Currency::getBlockReward(size_t medianSize, size_t currentBlockSize, uint64_t alreadyGeneratedCoins, uint64_t fee, uint64_t& reward, int64_t& emissionChange) const -``` - -This function has two parts: - -- basic block reward calculation: `uint64_t baseReward = (m_moneySupply - alreadyGeneratedCoins) >> m_emissionSpeedFactor;` -- big block penalty calculation: this is the way CryptoNote protects the block chain from transaction flooding attacks and preserves opportunities for organic network growth at the same time. - -Only the first part of this function is directly related to the emission logic. You can change it the way you want. See MonetaVerde and DuckNote as the examples where this function is modified. - - -### Third step. Networking - -**1. Default ports for P2P and RPC networking** (src/CryptoNoteConfig.h) - -P2P port is used by daemons to talk to each other through P2P protocol. -RPC port is used by wallet and other programs to talk to daemon. - -It's better to choose ports that aren't used by other software or coins. See known TCP ports lists: - -* http://www.speedguide.net/ports.php -* http://www.networksorcery.com/enp/protocol/ip/ports00000.htm -* http://keir.net/portlist.html - -Example: -``` -const int P2P_DEFAULT_PORT = 17236; -const int RPC_DEFAULT_PORT = 18236; -``` - - -**2. Network identifier** (src/P2p/P2pNetworks.h) - -This identifier is used in network packages in order not to mix two different cryptocoin networks. Change all the bytes to random values for your network: -``` -const static boost::uuids::uuid CRYPTONOTE_NETWORK = { { 0xA1, 0x1A, 0xA1, 0x1A, 0xA1, 0x0A, 0xA1, 0x0A, 0xA0, 0x1A, 0xA0, 0x1A, 0xA0, 0x1A, 0xA1, 0x1A } }; -``` - - -**3. Seed nodes** (src/CryptoNoteConfig.h) - -Add IP addresses of your seed nodes. - -Example: -``` -const std::initializer_list SEED_NODES = { - "111.11.11.11:17236", - "222.22.22.22:17236", -}; -``` - - -### Fourth step. Transaction fee and related parameters - -**1. Minimum transaction fee** (src/CryptoNoteConfig.h) - -Zero minimum fee can lead to transaction flooding. Transactions cheaper than the minimum transaction fee wouldn't be accepted by daemons. 100000 value for `MINIMUM_FEE` is usually enough. - -Example: -``` -const uint64_t MINIMUM_FEE = 100000; -``` - - -**2. Penalty free block size** (src/CryptoNoteConfig.h) - -CryptoNote protects chain from tx flooding by reducing block reward for blocks larger than the median block size. However, this rule applies for blocks larger than `CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE` bytes. - -Example: -``` -const size_t CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE = 20000; -``` - - -### Fifth step. Address prefix - -You may choose a letter (in some cases several letters) all the coin's public addresses will start with. It is defined by `CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX` constant. Since the rules for address prefixes are nontrivial you may use the [prefix generator tool](https://cryptonotestarter.org/tools.html). - -Example: -``` -const uint64_t CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX = 0xe9; // addresses start with "f" -``` - - -### Sixth step. Genesis block - -**1. Build the binaries with blank genesis tx hex** (src/CryptoNoteConfig.h) - -You should leave `const char GENESIS_COINBASE_TX_HEX[]` blank and compile the binaries without it. - -Example: -``` -const char GENESIS_COINBASE_TX_HEX[] = ""; -``` - - -**2. Start the daemon to print out the genesis block** - -Run your daemon with `--print-genesis-tx` argument. It will print out the genesis block coinbase transaction hash. - -Example: -``` -furiouscoind --print-genesis-tx -``` - - -**3. Copy the printed transaction hash** (src/CryptoNoteConfig.h) - -Copy the tx hash that has been printed by the daemon to `GENESIS_COINBASE_TX_HEX` in `src/CryptoNoteConfig.h` - -Example: -``` -const char GENESIS_COINBASE_TX_HEX[] = "013c01ff0001ffff...785a33d9ebdba68b0"; -``` - - -**4. Recompile the binaries** - -Recompile everything again. Your coin code is ready now. Make an announcement for the potential users and enjoy! - - -## Building CryptoNote +## Building Dogemone ### On *nix @@ -238,4 +51,4 @@ cmake -G "Visual Studio 12 Win64" .. ``` And then do Build. -Good luck! \ No newline at end of file +We would recommend using the prebuild binaries from the release section, Good luck! diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b02ec2896e..c84cfe526b 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -61,7 +61,7 @@ if (MSVC) target_link_libraries(System ws2_32) endif () -target_link_libraries(ConnectivityTool CryptoNoteCore Common Logging Crypto P2P Rpc Http Serialization System ${Boost_LIBRARIES}) +target_link_libraries(ConnectivityTool CryptoNoteCore Logging Crypto P2P Rpc Http Serialization Common System ${Boost_LIBRARIES}) target_link_libraries(Daemon CryptoNoteCore P2P Rpc Serialization System Http Logging Common Crypto upnpc-static BlockchainExplorer ${Boost_LIBRARIES}) target_link_libraries(SimpleWallet Wallet NodeRpcProxy Transfers Rpc Http Serialization CryptoNoteCore System Logging Common Crypto ${Boost_LIBRARIES}) target_link_libraries(PaymentGateService PaymentGate JsonRpcServer Wallet NodeRpcProxy Transfers CryptoNoteCore Crypto P2P Rpc Http Serialization System Logging Common InProcessNode upnpc-static BlockchainExplorer ${Boost_LIBRARIES}) @@ -80,4 +80,4 @@ set_property(TARGET SimpleWallet PROPERTY OUTPUT_NAME "simplewallet") set_property(TARGET PaymentGateService PROPERTY OUTPUT_NAME "walletd") set_property(TARGET Miner PROPERTY OUTPUT_NAME "miner") #TODO Specify the name of daemon for your currency -set_property(TARGET Daemon PROPERTY OUTPUT_NAME "cryptonoted") +set_property(TARGET Daemon PROPERTY OUTPUT_NAME "dogemoned") diff --git a/src/CryptoNoteConfig.h b/src/CryptoNoteConfig.h index 4506f667c9..7468e3f897 100644 --- a/src/CryptoNoteConfig.h +++ b/src/CryptoNoteConfig.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011-2016 The Cryptonote developers +// Copyright (c) 2011-2024 The Cryptonote developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -6,45 +6,38 @@ #include #include +#include namespace CryptoNote { + const std::string DEVELOPER_ADDRESS = "dmzGHGJdKQnfuUoXfUb37nYDNgQDS8NGWhLBo5pf4kDj4MzH9YBhVnW26xpwREXvMraJKzifutKUQBEVxX8gSrbZ3mtMMdsYGx"; namespace parameters { const uint64_t CRYPTONOTE_MAX_BLOCK_NUMBER = 500000000; const size_t CRYPTONOTE_MAX_BLOCK_BLOB_SIZE = 500000000; -const size_t CRYPTONOTE_MAX_TX_SIZE = 1000000000; -//TODO Currency-specific address prefix -const uint64_t CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX = ; -//TODO Choose maturity period for your currency +const size_t CRYPTONOTE_MAX_TX_SIZE = 2000000; // Adjusted to 2 MB +const uint64_t CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX = 0x6f5b; // Unique prefix for Dogemone const size_t CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW = 60; const uint64_t CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT = 60 * 60 * 2; const size_t BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW = 60; -//TODO Specify total number of available coins -//TODO ((uint64_t)(-1)) equals to 18446744073709551616 coins -//TODO or you can define number explicitly UINT64_C(858986905600000000) -const uint64_t MONEY_SUPPLY = ; -const unsigned EMISSION_SPEED_FACTOR = 18; +const uint64_t MONEY_SUPPLY = UINT64_C(300000000000000000); // Total supply +const unsigned EMISSION_SPEED_FACTOR = 20; static_assert(EMISSION_SPEED_FACTOR <= 8 * sizeof(uint64_t), "Bad EMISSION_SPEED_FACTOR"); -//TODO Define number of blocks for block size median calculation const size_t CRYPTONOTE_REWARD_BLOCKS_WINDOW = 100; -const size_t CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE = 10000; //size of block (bytes) after which reward for block calculated using block size +// Increased to 50 KB to allow more transactions per block +const size_t CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE = 50000; const size_t CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE = 600; -//TODO Define number of digits -const size_t CRYPTONOTE_DISPLAY_DECIMAL_POINT = 8; -//TODO Define minimum fee for transactions -const uint64_t MINIMUM_FEE = ; +const size_t CRYPTONOTE_DISPLAY_DECIMAL_POINT = 9; +// Adjusted minimum fee to 0.01 Dogemone (10,000,000 atomic units) +const uint64_t MINIMUM_FEE = 10000000; const uint64_t DEFAULT_DUST_THRESHOLD = MINIMUM_FEE; -//TODO Define preferred block's target time -const uint64_t DIFFICULTY_TARGET = 120; // seconds +const uint64_t DIFFICULTY_TARGET = 120; // Block time in seconds const uint64_t EXPECTED_NUMBER_OF_BLOCKS_PER_DAY = 24 * 60 * 60 / DIFFICULTY_TARGET; -//TODO There are options to tune CryptoNote's difficulty retargeting function. -//TODO We recommend not to change it. -const size_t DIFFICULTY_WINDOW = EXPECTED_NUMBER_OF_BLOCKS_PER_DAY; // blocks -const size_t DIFFICULTY_CUT = 60; // timestamps to cut after sorting +const size_t DIFFICULTY_WINDOW = EXPECTED_NUMBER_OF_BLOCKS_PER_DAY; +const size_t DIFFICULTY_CUT = 60; const size_t DIFFICULTY_LAG = 15; static_assert(2 * DIFFICULTY_CUT <= DIFFICULTY_WINDOW - 2, "Bad DIFFICULTY_WINDOW or DIFFICULTY_CUT"); @@ -55,8 +48,8 @@ const uint64_t MAX_BLOCK_SIZE_GROWTH_SPEED_DENOMINATOR = 365 * 24 * 60 * 6 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_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 * 30 / 100; @@ -72,22 +65,19 @@ const char CRYPTONOTE_BLOCKCHAIN_INDICES_FILENAME[] = "blockchainindice const char MINER_CONFIG_FILE_NAME[] = "miner_conf.json"; } // parameters -//TODO Put here the name of your currency -const char CRYPTONOTE_NAME[] = ""; -const char GENESIS_COINBASE_TX_HEX[] = ""; +const char CRYPTONOTE_NAME[] = "dogemone"; +const char GENESIS_COINBASE_TX_HEX[] = "013c01ff000189a39ae8a908029b2e4c0281c0b02e7c53291a94d1d0cbff8883f8024f5142ee494ffbbd08807121011c257208ff577a7fe234226c02232debf56c45b0ad1508cfe8f99c18d59861e6"; const uint8_t CURRENT_TRANSACTION_VERSION = 1; const uint8_t BLOCK_MAJOR_VERSION_1 = 1; const uint8_t BLOCK_MINOR_VERSION_0 = 0; -const size_t BLOCKS_IDS_SYNCHRONIZING_DEFAULT_COUNT = 10000; //by default, blocks ids count in synchronizing -const size_t BLOCKS_SYNCHRONIZING_DEFAULT_COUNT = 200; //by default, blocks count in blocks downloading +const size_t BLOCKS_IDS_SYNCHRONIZING_DEFAULT_COUNT = 10000; +const size_t BLOCKS_SYNCHRONIZING_DEFAULT_COUNT = 200; const size_t COMMAND_RPC_GET_BLOCKS_FAST_MAX_COUNT = 1000; -//TODO This port will be used by the daemon to establish connections with p2p network -const int P2P_DEFAULT_PORT = ; -//TODO This port will be used by the daemon to interact with simlewallet -const int RPC_DEFAULT_PORT = ; +const int P2P_DEFAULT_PORT = 49200; +const int RPC_DEFAULT_PORT = 53000; const size_t P2P_LOCAL_WHITE_PEERLIST_LIMIT = 1000; const size_t P2P_LOCAL_GRAY_PEERLIST_LIMIT = 5000; @@ -96,7 +86,7 @@ const size_t P2P_CONNECTION_MAX_WRITE_BUFFER_SIZE = 16 * 1024 * 1024; 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_PACKET_MAX_SIZE = 50000000; // 50 MB 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 @@ -104,10 +94,9 @@ const uint64_t P2P_DEFAULT_INVOKE_TIMEOUT = 60 * 2 * 1000; // const size_t P2P_DEFAULT_HANDSHAKE_INVOKE_TIMEOUT = 5000; // 5 seconds const char P2P_STAT_TRUSTED_PUB_KEY[] = "8f80f9a5a434a9f1510d13336228debfee9c918ce505efe225d8c94d045fa115"; -//TODO Add here your network seed nodes const std::initializer_list SEED_NODES = { - //"your_seed_ip1.com:8080", - //"your_seed_ip2.com:8080", + "45.32.154.224:49200", + "45.77.148.37:49200", }; struct CheckpointData { @@ -115,14 +104,13 @@ struct CheckpointData { const char* blockId; }; -#ifdef __GNUC__ -__attribute__((unused)) -#endif - -// You may add here other checkpoints using the following format: -// {, ""}, const std::initializer_list CHECKPOINTS = { - //{ 10000, "84b6345731e2702cdaadc6ce5e5238c4ca5ecf48e3447136b2ed829b8a95f3ad" }, + {1, "545dc29fd34e78128689e5fbd9db24d2f84d97f33848e82fb2e532936ad63f99"}, + {2, "f69081183bea62b16fa65b76cfcf94c52a8f24cb091536e136a3836f4dafaf56"}, + {3, "7c2cbaa9726584e134492f4e634382b39f8f3659b975c4a24006edb61fa835b5"}, + {4, "45e152dc9e61701d0e27e9b6a82afa12a6a0e8df0188aa1dba8e1bd0ab063f07"}, + {5, "9f6e5679c683141df4c946fabdb7e730d4069a16cba39e8d45cc38f6e25d91d1"}, + {10, "d00484acc0acfbc4b730a110658e7ce9ebb777e499ed7066f79da3f841ec4d7b"}, }; } // CryptoNote diff --git a/src/CryptoNoteCore/Currency.cpp b/src/CryptoNoteCore/Currency.cpp index bfdc7b9e09..50adda8b2e 100755 --- a/src/CryptoNoteCore/Currency.cpp +++ b/src/CryptoNoteCore/Currency.cpp @@ -15,6 +15,7 @@ #include "CryptoNoteFormatUtils.h" #include "CryptoNoteTools.h" #include "TransactionExtra.h" +#include "CryptoNoteConfig.h" #undef ERROR @@ -135,7 +136,7 @@ bool Currency::constructMinerTx(uint32_t height, size_t medianSize, uint64_t alr KeyPair txkey = generateKeyPair(); addTransactionPublicKeyToExtra(tx.extra, txkey.publicKey); - if (!extraNonce.empty()) { + if (!extraNonce.empty() && extraNonce.size() <= 255) { // Ensure extraNonce size is within limit if (!addExtraNonceToTransactionExtra(tx.extra, extraNonce)) { return false; } @@ -151,38 +152,28 @@ bool Currency::constructMinerTx(uint32_t height, size_t medianSize, uint64_t alr return false; } - std::vector outAmounts; - decompose_amount_into_digits(blockReward, m_defaultDustThreshold, - [&outAmounts](uint64_t a_chunk) { outAmounts.push_back(a_chunk); }, - [&outAmounts](uint64_t a_dust) { outAmounts.push_back(a_dust); }); + uint64_t minerReward = blockReward + fee; // Adding the fee to the block reward - if (!(1 <= maxOuts)) { logger(ERROR, BRIGHT_RED) << "max_out must be non-zero"; return false; } - while (maxOuts < outAmounts.size()) { - outAmounts[outAmounts.size() - 2] += outAmounts.back(); - outAmounts.resize(outAmounts.size() - 1); - } - - uint64_t summaryAmounts = 0; - for (size_t no = 0; no < outAmounts.size(); no++) { - Crypto::KeyDerivation derivation = boost::value_initialized(); - Crypto::PublicKey outEphemeralPubKey = boost::value_initialized(); - - bool r = Crypto::generate_key_derivation(minerAddress.viewPublicKey, txkey.secretKey, derivation); - - if (!(r)) { - logger(ERROR, BRIGHT_RED) - << "while creating outs: failed to generate_key_derivation(" - << minerAddress.viewPublicKey << ", " << txkey.secretKey << ")"; + if (height % 10 == 0) { + // Allocate the block reward of every 10th block to the developer address + AccountPublicAddress devAddress; + bool parseSuccess = parseAccountAddressString(DEVELOPER_ADDRESS, devAddress); + if (!parseSuccess) { + logger(ERROR, BRIGHT_RED) << "Failed to parse developer address"; return false; } - r = Crypto::derive_public_key(derivation, no, minerAddress.spendPublicKey, outEphemeralPubKey); + Crypto::KeyDerivation derivation; + bool r = Crypto::generate_key_derivation(devAddress.viewPublicKey, txkey.secretKey, derivation); + if (!r) { + logger(ERROR, BRIGHT_RED) << "Failed to generate key derivation for developer address"; + return false; + } - if (!(r)) { - logger(ERROR, BRIGHT_RED) - << "while creating outs: failed to derive_public_key(" - << derivation << ", " << no << ", " - << minerAddress.spendPublicKey << ")"; + Crypto::PublicKey outEphemeralPubKey; + r = Crypto::derive_public_key(derivation, 0, devAddress.spendPublicKey, outEphemeralPubKey); + if (!r) { + logger(ERROR, BRIGHT_RED) << "Failed to derive public key for developer address"; return false; } @@ -190,23 +181,77 @@ bool Currency::constructMinerTx(uint32_t height, size_t medianSize, uint64_t alr tk.key = outEphemeralPubKey; TransactionOutput out; - summaryAmounts += out.amount = outAmounts[no]; + out.amount = minerReward; out.target = tk; tx.outputs.push_back(out); - } + } else { + // Regular miner reward + std::vector outAmounts; + decompose_amount_into_digits(minerReward, m_defaultDustThreshold, + [&outAmounts](uint64_t a_chunk) { outAmounts.push_back(a_chunk); }, + [&outAmounts](uint64_t a_dust) { outAmounts.push_back(a_dust); }); + + if (!(1 <= maxOuts)) { + logger(ERROR, BRIGHT_RED) << "max_out must be non-zero"; + return false; + } - if (!(summaryAmounts == blockReward)) { - logger(ERROR, BRIGHT_RED) << "Failed to construct miner tx, summaryAmounts = " << summaryAmounts << " not equal blockReward = " << blockReward; - return false; + while (maxOuts < outAmounts.size()) { + outAmounts[outAmounts.size() - 2] += outAmounts.back(); + outAmounts.resize(outAmounts.size() - 1); + } + + uint64_t summaryAmounts = 0; + for (size_t no = 0; no < outAmounts.size(); no++) { + Crypto::KeyDerivation derivation = boost::value_initialized(); + Crypto::PublicKey outEphemeralPubKey = boost::value_initialized(); + + bool r = Crypto::generate_key_derivation(minerAddress.viewPublicKey, txkey.secretKey, derivation); + + if (!r) { + logger(ERROR, BRIGHT_RED) << "while creating outs: failed to generate_key_derivation(" + << minerAddress.viewPublicKey << ", " << txkey.secretKey << ")"; + return false; + } + + r = Crypto::derive_public_key(derivation, no, minerAddress.spendPublicKey, outEphemeralPubKey); + + if (!r) { + logger(ERROR, BRIGHT_RED) << "while creating outs: failed to derive_public_key(" + << derivation << ", " << no << ", " << minerAddress.spendPublicKey << ")"; + return false; + } + + KeyOutput tk; + tk.key = outEphemeralPubKey; + + TransactionOutput out; + summaryAmounts += out.amount = outAmounts[no]; + out.target = tk; + tx.outputs.push_back(out); + } + + // Ensure summary amounts match block reward + fee + if (summaryAmounts != minerReward) { + logger(ERROR, BRIGHT_RED) << "Failed to construct miner tx, summaryAmounts = " << summaryAmounts << " not equal minerReward = " << minerReward; + return false; + } } tx.version = CURRENT_TRANSACTION_VERSION; - //lock tx.unlockTime = height + m_minedMoneyUnlockWindow; tx.inputs.push_back(in); + + // Log transaction outputs + logger(INFO) << "Transaction outputs:"; + for (const auto& output : tx.outputs) { + logger(INFO) << "Output amount: " << output.amount; + } + return true; } + bool Currency::isFusionTransaction(const std::vector& inputsAmounts, const std::vector& outputsAmounts, size_t size) const { if (size > fusionTxMaxSize()) { return false; @@ -270,7 +315,7 @@ bool Currency::isAmountApplicableInFusionTransactionInput(uint64_t amount, uint6 auto it = std::lower_bound(PRETTY_AMOUNTS.begin(), PRETTY_AMOUNTS.end(), amount); if (it == PRETTY_AMOUNTS.end() || amount != *it) { return false; - } + } amountPowerOfTen = static_cast(std::distance(PRETTY_AMOUNTS.begin(), it) / 9); return true; diff --git a/src/P2p/P2pNetworks.h b/src/P2p/P2pNetworks.h index 90401a03eb..9a72d3b5bd 100644 --- a/src/P2p/P2pNetworks.h +++ b/src/P2p/P2pNetworks.h @@ -6,5 +6,5 @@ namespace CryptoNote { - const static boost::uuids::uuid CRYPTONOTE_NETWORK = { { 0x43, 0x52, 0x59, 0x50, 0x54, 0x4f, 0x4e, 0x4f, 0x54, 0x45, 0x00, 0x12, 0x10, 0x11, 0x01, 0x10 } }; + const static boost::uuids::uuid CRYPTONOTE_NETWORK = { { 0x50, 0x52, 0x59, 0x50, 0x54, 0x4f, 0x4e, 0x4f, 0x54, 0x45, 0x00, 0x12, 0x10, 0x11, 0x01, 0x11 } }; } diff --git a/src/Platform/Windows/System/Dispatcher.cpp b/src/Platform/Windows/System/Dispatcher.cpp index 1243460808..d7902b3038 100644 --- a/src/Platform/Windows/System/Dispatcher.cpp +++ b/src/Platform/Windows/System/Dispatcher.cpp @@ -13,6 +13,7 @@ #endif #include #include "ErrorMessage.h" +#include namespace System { @@ -70,7 +71,7 @@ Dispatcher::Dispatcher() { BOOL result2 = ConvertFiberToThread(); assert(result == TRUE); } - + DeleteCriticalSection(reinterpret_cast(criticalSection)); throw std::runtime_error("Dispatcher::Dispatcher, " + message); } diff --git a/src/Platform/Windows/System/Ipv4Resolver.cpp b/src/Platform/Windows/System/Ipv4Resolver.cpp index 2a0e2bbfe5..081f2a3112 100755 --- a/src/Platform/Windows/System/Ipv4Resolver.cpp +++ b/src/Platform/Windows/System/Ipv4Resolver.cpp @@ -13,6 +13,7 @@ #include #include #include +#include namespace System { @@ -52,7 +53,7 @@ Ipv4Address Ipv4Resolver::resolve(const std::string& host) { if (result != 0) { throw std::runtime_error("Ipv4Resolver::resolve, getaddrinfo failed, " + errorMessage(result)); } - + size_t count = 0; for (addrinfo* addressInfo = addressInfos; addressInfo != nullptr; addressInfo = addressInfo->ai_next) { ++count; diff --git a/src/Platform/Windows/System/TcpConnection.cpp b/src/Platform/Windows/System/TcpConnection.cpp index 3526856e06..2181aa23ca 100644 --- a/src/Platform/Windows/System/TcpConnection.cpp +++ b/src/Platform/Windows/System/TcpConnection.cpp @@ -13,6 +13,7 @@ #include #include "Dispatcher.h" #include "ErrorMessage.h" +#include namespace System { diff --git a/src/Platform/Windows/System/TcpConnector.cpp b/src/Platform/Windows/System/TcpConnector.cpp index a4187609e6..45a7100b83 100644 --- a/src/Platform/Windows/System/TcpConnector.cpp +++ b/src/Platform/Windows/System/TcpConnector.cpp @@ -14,6 +14,7 @@ #include "Dispatcher.h" #include "ErrorMessage.h" #include "TcpConnection.h" +#include namespace System { diff --git a/src/Platform/Windows/System/TcpListener.cpp b/src/Platform/Windows/System/TcpListener.cpp index 997bad2565..5c30794a40 100644 --- a/src/Platform/Windows/System/TcpListener.cpp +++ b/src/Platform/Windows/System/TcpListener.cpp @@ -14,6 +14,7 @@ #include "Dispatcher.h" #include "ErrorMessage.h" #include "TcpConnection.h" +#include namespace System { diff --git a/src/Serialization/SerializationOverloads.cpp b/src/Serialization/SerializationOverloads.cpp index d341b89cc3..35566ee425 100644 --- a/src/Serialization/SerializationOverloads.cpp +++ b/src/Serialization/SerializationOverloads.cpp @@ -3,6 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "Serialization/SerializationOverloads.h" +#include #include