From 718aebc138002032f645f915513b59da68f162be Mon Sep 17 00:00:00 2001 From: levonpetrosyan93 Date: Fri, 12 Apr 2024 13:27:31 +0400 Subject: [PATCH 1/8] getrealsupply fixed --- src/rpc/misc.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 74479aaa71..76b3152af1 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -1582,6 +1582,10 @@ UniValue gettotalsupply(const JSONRPCRequest& request) if(!pblocktree->ReadTotalSupply(total)) throw JSONRPCError(RPC_DATABASE_ERROR, "Cannot read the total supply from the database. This functionality requires -addressindex to be enabled. Enabling -addressindex requires reindexing."); + total += 44666700000000; // The estimated amount of coins forged during the Zerocoin attacks + total += 23750000000000; // The estimated amount of coins forged during the Lelantus attacks. + total += 4302972000000; // The remaining amount of forged coins during CVE-2018-17144 attacks, after subtracting burnt Coins sent to unrecoverable address https://explorer.firo.org/tx/0b53178c1b22bae4c04ef943ee6d6d30f2483327fe9beb54952951592e8ce368 + UniValue result(UniValue::VOBJ); result.push_back(Pair("total", total)); From 1e166f562952a1c41cd76c669bedb3effb70dce4 Mon Sep 17 00:00:00 2001 From: levonpetrosyan93 Date: Mon, 29 Apr 2024 11:26:21 +0400 Subject: [PATCH 2/8] Update numbers --- src/rpc/misc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 76b3152af1..aecc12980c 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -1582,9 +1582,9 @@ UniValue gettotalsupply(const JSONRPCRequest& request) if(!pblocktree->ReadTotalSupply(total)) throw JSONRPCError(RPC_DATABASE_ERROR, "Cannot read the total supply from the database. This functionality requires -addressindex to be enabled. Enabling -addressindex requires reindexing."); - total += 44666700000000; // The estimated amount of coins forged during the Zerocoin attacks + total += 49839700000000; // The estimated amount of coins forged during the Zerocoin attacks (the negative balance of the pool) total += 23750000000000; // The estimated amount of coins forged during the Lelantus attacks. - total += 4302972000000; // The remaining amount of forged coins during CVE-2018-17144 attacks, after subtracting burnt Coins sent to unrecoverable address https://explorer.firo.org/tx/0b53178c1b22bae4c04ef943ee6d6d30f2483327fe9beb54952951592e8ce368 + total += 3131972000000; // The remaining amount of forged coins during CVE-2018-17144 attacks, after subtracting locked coins and burnt Coins sent to unrecoverable address https://explorer.firo.org/tx/0b53178c1b22bae4c04ef943ee6d6d30f2483327fe9beb54952951592e8ce368 UniValue result(UniValue::VOBJ); result.push_back(Pair("total", total)); From c8dd7c4429c03f1be568606aa06fd1bab80a3c5f Mon Sep 17 00:00:00 2001 From: levonpetrosyan93 Date: Mon, 10 Jun 2024 11:12:25 +0400 Subject: [PATCH 3/8] The comment fixed --- src/rpc/misc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index aecc12980c..df4e4c9301 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -1582,7 +1582,7 @@ UniValue gettotalsupply(const JSONRPCRequest& request) if(!pblocktree->ReadTotalSupply(total)) throw JSONRPCError(RPC_DATABASE_ERROR, "Cannot read the total supply from the database. This functionality requires -addressindex to be enabled. Enabling -addressindex requires reindexing."); - total += 49839700000000; // The estimated amount of coins forged during the Zerocoin attacks (the negative balance of the pool) + total += 49839700000000; // The actual amount of coins forged during the Zerocoin attacks (the negative balance after the pool closed) total += 23750000000000; // The estimated amount of coins forged during the Lelantus attacks. total += 3131972000000; // The remaining amount of forged coins during CVE-2018-17144 attacks, after subtracting locked coins and burnt Coins sent to unrecoverable address https://explorer.firo.org/tx/0b53178c1b22bae4c04ef943ee6d6d30f2483327fe9beb54952951592e8ce368 From eb5231bf32cf0f58831b42f4614ccec933f563b9 Mon Sep 17 00:00:00 2001 From: levonpetrosyan93 Date: Sun, 16 Jun 2024 07:01:35 +0400 Subject: [PATCH 4/8] Add getzerocoinpoolbalance rpc --- src/rpc/misc.cpp | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index df4e4c9301..758c46db1d 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -1582,8 +1582,7 @@ UniValue gettotalsupply(const JSONRPCRequest& request) if(!pblocktree->ReadTotalSupply(total)) throw JSONRPCError(RPC_DATABASE_ERROR, "Cannot read the total supply from the database. This functionality requires -addressindex to be enabled. Enabling -addressindex requires reindexing."); - total += 49839700000000; // The actual amount of coins forged during the Zerocoin attacks (the negative balance after the pool closed) - total += 23750000000000; // The estimated amount of coins forged during the Lelantus attacks. + total += 49839700000000; // The actual amount of coins forged during the Zerocoin attacks (the negative balance after the pool closed), you can verify the number by calling getzerocoinpoolbalance rpc total += 3131972000000; // The remaining amount of forged coins during CVE-2018-17144 attacks, after subtracting locked coins and burnt Coins sent to unrecoverable address https://explorer.firo.org/tx/0b53178c1b22bae4c04ef943ee6d6d30f2483327fe9beb54952951592e8ce368 UniValue result(UniValue::VOBJ); @@ -1592,6 +1591,44 @@ UniValue gettotalsupply(const JSONRPCRequest& request) return result; } +UniValue getzerocoinpoolbalance(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 0) + throw std::runtime_error( + "getzerocoinpoolbalance\n" + "\nReturns the total coin amount, which remains after zerocoin pool closed.\n" + "\nArguments: none\n" + "\nResult:\n" + "{\n" + " \"total\" (string) The total balance\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("getzerocoinpoolbalance", "") + + HelpExampleRpc("getzerocoinpoolbalance", "") + ); + + CAmount nTotalAmount = 0; + + // Iterate over all mints + std::vector > addressIndex; + if (GetAddressIndex(uint160(), AddressType::zerocoinMint, addressIndex)) { + for (std::vector >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) { + nTotalAmount += it->second; + } + } + addressIndex.clear(); + + // Iterate over all spends + if (GetAddressIndex(uint160(), AddressType::zerocoinSpend, addressIndex)) { + for (std::vector < std::pair < CAddressIndexKey, CAmount > > ::const_iterator it = addressIndex.begin(); + it != addressIndex.end(); it++) { + nTotalAmount += it->second; + } + } + + return UniValue(nTotalAmount); +} + UniValue getinfoex(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 0) @@ -1717,7 +1754,7 @@ static const CRPCCommand commands[] = /* Not shown in help */ { "hidden", "getinfoex", &getinfoex, false }, { "addressindex", "gettotalsupply", &gettotalsupply, false }, - + { "addressindex", "getzerocoinpoolbalance", &getzerocoinpoolbalance, false }, /* Mobile related */ { "mobile", "getanonymityset", &getanonymityset, false }, { "mobile", "getmintmetadata", &getmintmetadata, true }, From be2deaaeb20190afbd1f27675122783f4dcb7da2 Mon Sep 17 00:00:00 2001 From: levonpetrosyan93 Date: Mon, 24 Jun 2024 03:53:19 +0400 Subject: [PATCH 5/8] Add getCVE17144amount rpc --- src/rpc/misc.cpp | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 758c46db1d..e0e7f8ad77 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -1629,6 +1629,49 @@ UniValue getzerocoinpoolbalance(const JSONRPCRequest& request) return UniValue(nTotalAmount); } +UniValue getCVE17144amount(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() != 0) + throw std::runtime_error( + "getCVE17144amount\n" + "\nReturns the total amount of forged coins during CVE-2018-17144 attacks.\n" + "\nArguments: none\n" + "\nResult:\n" + "{\n" + " \"total\" (string) The total balance\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("getCVE17144amount", "") + + HelpExampleRpc("getCVE17144amount", "") + ); + // as the attack happened at block 293526, + // get the block + CBlockIndex *mintBlock = chainActive[293526]; + CBlock block; + if (!ReadBlockFromDisk(block, mintBlock, ::Params().GetConsensus())) { + throw std::runtime_error(std::string("can't read block from disk, ")); + } + CAmount amount = 0; + for (CTransactionRef tx : block.vtx) { + std::set vInOutPoints; + if (!tx->IsCoinBase() && !tx->HasNoRegularInputs()) { + std::set vInOutPoints; + for (const auto& txin : tx->vin) + { + if (!vInOutPoints.insert(txin.prevout).second) { + CTransactionRef tx; + uint256 hashBlock; + if (!GetTransaction(txin.prevout.hash, tx, Params().GetConsensus(), hashBlock, true)) { + continue; + } + amount += tx->vout[txin.prevout.n].nValue; + } + } + } + } + return amount; +} + UniValue getinfoex(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 0) @@ -1754,7 +1797,8 @@ static const CRPCCommand commands[] = /* Not shown in help */ { "hidden", "getinfoex", &getinfoex, false }, { "addressindex", "gettotalsupply", &gettotalsupply, false }, - { "addressindex", "getzerocoinpoolbalance", &getzerocoinpoolbalance, false }, + { "addressindex", "getzerocoinpoolbalance", &getzerocoinpoolbalance, false }, + { "addressindex", "getCVE17144amount", &getCVE17144amount, false }, /* Mobile related */ { "mobile", "getanonymityset", &getanonymityset, false }, { "mobile", "getmintmetadata", &getmintmetadata, true }, From 5019320010b5d678825bf67875de1f2dd1cd79ee Mon Sep 17 00:00:00 2001 From: levonpetrosyan93 Date: Tue, 3 Dec 2024 18:12:05 +0200 Subject: [PATCH 6/8] Calculate instead of hardcoded numbers --- src/rpc/misc.cpp | 109 ++++++++++++++++++++++++++--------------------- 1 file changed, 60 insertions(+), 49 deletions(-) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index e67fbd103f..6ad6049e12 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -1759,6 +1759,60 @@ UniValue getspentinfo(const JSONRPCRequest& request) return obj; } +CAmount getzerocoinpoolbalance() +{ + CAmount nTotalAmount = 0; + + // Iterate over all mints + std::vector > addressIndex; + if (GetAddressIndex(uint160(), AddressType::zerocoinMint, addressIndex)) { + for (std::vector >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) { + nTotalAmount += it->second; + } + } + addressIndex.clear(); + + // Iterate over all spends + if (GetAddressIndex(uint160(), AddressType::zerocoinSpend, addressIndex)) { + for (std::vector < std::pair < CAddressIndexKey, CAmount > > ::const_iterator it = addressIndex.begin(); + it != addressIndex.end(); it++) { + nTotalAmount += it->second; + } + } + + return nTotalAmount; +} + +CAmount getCVE17144amount() +{ + // as the attack happened at block 293526, + // get the block + CBlockIndex *mintBlock = chainActive[293526]; + CBlock block; + if (!ReadBlockFromDisk(block, mintBlock, ::Params().GetConsensus())) { + throw std::runtime_error(std::string("can't read block from disk, ")); + } + CAmount amount = 0; + for (CTransactionRef tx : block.vtx) { + std::set vInOutPoints; + if (!tx->IsCoinBase() && !tx->HasNoRegularInputs()) { + std::set vInOutPoints; + for (const auto& txin : tx->vin) + { + if (!vInOutPoints.insert(txin.prevout).second) { + CTransactionRef tx; + uint256 hashBlock; + if (!GetTransaction(txin.prevout.hash, tx, Params().GetConsensus(), hashBlock, true)) { + continue; + } + amount += tx->vout[txin.prevout.n].nValue; + } + } + } + } + return amount; +} + UniValue gettotalsupply(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 0) @@ -1780,9 +1834,9 @@ UniValue gettotalsupply(const JSONRPCRequest& request) if(!pblocktree->ReadTotalSupply(total)) throw JSONRPCError(RPC_DATABASE_ERROR, "Cannot read the total supply from the database. This functionality requires -addressindex to be enabled. Enabling -addressindex requires reindexing."); - total += 49839700000000; // The actual amount of coins forged during the Zerocoin attacks (the negative balance after the pool closed), you can verify the number by calling getzerocoinpoolbalance rpc - total += 3131972000000; // The remaining amount of forged coins during CVE-2018-17144 attacks, after subtracting locked coins and burnt Coins sent to unrecoverable address https://explorer.firo.org/tx/0b53178c1b22bae4c04ef943ee6d6d30f2483327fe9beb54952951592e8ce368 - + total -= getzerocoinpoolbalance(); //498,397.00000000 The actual amount of coins forged during the Zerocoin attacks (the negative balance after the pool closed), + total += getCVE17144amount(); //320,841.99803185 The cmount of forged coins during CVE-2018-17144 attacks, + total -= 16810168037465;// burnt Coins sent to unrecoverable address https://explorer.firo.org/tx/0b53178c1b22bae4c04ef943ee6d6d30f2483327fe9beb54952951592e8ce368 UniValue result(UniValue::VOBJ); result.push_back(Pair("total", total)); @@ -1805,26 +1859,7 @@ UniValue getzerocoinpoolbalance(const JSONRPCRequest& request) + HelpExampleRpc("getzerocoinpoolbalance", "") ); - CAmount nTotalAmount = 0; - - // Iterate over all mints - std::vector > addressIndex; - if (GetAddressIndex(uint160(), AddressType::zerocoinMint, addressIndex)) { - for (std::vector >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) { - nTotalAmount += it->second; - } - } - addressIndex.clear(); - - // Iterate over all spends - if (GetAddressIndex(uint160(), AddressType::zerocoinSpend, addressIndex)) { - for (std::vector < std::pair < CAddressIndexKey, CAmount > > ::const_iterator it = addressIndex.begin(); - it != addressIndex.end(); it++) { - nTotalAmount += it->second; - } - } - - return UniValue(nTotalAmount); + return getzerocoinpoolbalance(); } UniValue getCVE17144amount(const JSONRPCRequest& request) @@ -1842,32 +1877,8 @@ UniValue getCVE17144amount(const JSONRPCRequest& request) + HelpExampleCli("getCVE17144amount", "") + HelpExampleRpc("getCVE17144amount", "") ); - // as the attack happened at block 293526, - // get the block - CBlockIndex *mintBlock = chainActive[293526]; - CBlock block; - if (!ReadBlockFromDisk(block, mintBlock, ::Params().GetConsensus())) { - throw std::runtime_error(std::string("can't read block from disk, ")); - } - CAmount amount = 0; - for (CTransactionRef tx : block.vtx) { - std::set vInOutPoints; - if (!tx->IsCoinBase() && !tx->HasNoRegularInputs()) { - std::set vInOutPoints; - for (const auto& txin : tx->vin) - { - if (!vInOutPoints.insert(txin.prevout).second) { - CTransactionRef tx; - uint256 hashBlock; - if (!GetTransaction(txin.prevout.hash, tx, Params().GetConsensus(), hashBlock, true)) { - continue; - } - amount += tx->vout[txin.prevout.n].nValue; - } - } - } - } - return amount; + + return getCVE17144amount(); } UniValue getinfoex(const JSONRPCRequest& request) From 401a88f15714443b87092864a2905cab22bfa6a7 Mon Sep 17 00:00:00 2001 From: levonpetrosyan93 Date: Wed, 4 Dec 2024 10:07:29 +0200 Subject: [PATCH 7/8] Review comments applied --- src/rpc/misc.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 6ad6049e12..f252b75b53 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -1766,17 +1766,16 @@ CAmount getzerocoinpoolbalance() // Iterate over all mints std::vector > addressIndex; if (GetAddressIndex(uint160(), AddressType::zerocoinMint, addressIndex)) { - for (std::vector >::const_iterator it=addressIndex.begin(); it!=addressIndex.end(); it++) { - nTotalAmount += it->second; + for (auto& it : addressIndex) { + nTotalAmount += it.second; } } addressIndex.clear(); // Iterate over all spends if (GetAddressIndex(uint160(), AddressType::zerocoinSpend, addressIndex)) { - for (std::vector < std::pair < CAddressIndexKey, CAmount > > ::const_iterator it = addressIndex.begin(); - it != addressIndex.end(); it++) { - nTotalAmount += it->second; + for (auto& it : addressIndex) { + nTotalAmount += it.second; } } @@ -1787,9 +1786,18 @@ CAmount getCVE17144amount() { // as the attack happened at block 293526, // get the block - CBlockIndex *mintBlock = chainActive[293526]; + LOCK(cs_main); + if (chainActive.Height() < 293526) { + throw std::runtime_error("Chain height is less than 293,526."); + } + + if (!Params().GetConsensus().IsMain()) { + throw std::runtime_error("It is not on right chain, atack happened on mainnet"); + } + + CBlockIndex *atackedBlock = chainActive[293526]; CBlock block; - if (!ReadBlockFromDisk(block, mintBlock, ::Params().GetConsensus())) { + if (!ReadBlockFromDisk(block, atackedBlock, ::Params().GetConsensus())) { throw std::runtime_error(std::string("can't read block from disk, ")); } CAmount amount = 0; From 76bc9ecdc006c51998df9d3f03eb12e4a4649f86 Mon Sep 17 00:00:00 2001 From: levonpetrosyan93 Date: Wed, 4 Dec 2024 12:00:35 +0200 Subject: [PATCH 8/8] coderabbitai comment applied --- src/rpc/misc.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index f252b75b53..fafbd6e0ce 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -1784,25 +1784,25 @@ CAmount getzerocoinpoolbalance() CAmount getCVE17144amount() { - // as the attack happened at block 293526, - // get the block + // CVE-2018-17144 was a critical bug that allowed double-spending of inputs + // in the same transaction. This function calculates the total amount of coins + // that were created due to this vulnerability at block 293526. LOCK(cs_main); if (chainActive.Height() < 293526) { throw std::runtime_error("Chain height is less than 293,526."); } if (!Params().GetConsensus().IsMain()) { - throw std::runtime_error("It is not on right chain, atack happened on mainnet"); + throw std::runtime_error("Attack only occurred on mainnet"); } CBlockIndex *atackedBlock = chainActive[293526]; CBlock block; if (!ReadBlockFromDisk(block, atackedBlock, ::Params().GetConsensus())) { - throw std::runtime_error(std::string("can't read block from disk, ")); + throw std::runtime_error("Failed to read block 293526 from disk"); } CAmount amount = 0; for (CTransactionRef tx : block.vtx) { - std::set vInOutPoints; if (!tx->IsCoinBase() && !tx->HasNoRegularInputs()) { std::set vInOutPoints; for (const auto& txin : tx->vin) @@ -1813,6 +1813,9 @@ CAmount getCVE17144amount() if (!GetTransaction(txin.prevout.hash, tx, Params().GetConsensus(), hashBlock, true)) { continue; } + if (txin.prevout.n >= tx->vout.size()) { + continue; // Skip if output index is out of bounds + } amount += tx->vout[txin.prevout.n].nValue; } }