1 #include <gtest/gtest.h>
4 #include "utilmoneystr.h"
5 #include "chainparams.h"
6 #include "utilstrencodings.h"
7 #include "zcash/Address.hpp"
8 #include "wallet/wallet.h"
14 #include <boost/filesystem.hpp>
18 #ifndef disable_founders
20 // ./zcash-gtest --gtest_filter="founders_reward_test.*"
23 // Enable this test to generate and print 48 testnet 2-of-3 multisig addresses.
24 // The output can be copied into chainparams.cpp.
25 // The temporary wallet file can be renamed as wallet.dat and used for testing with zcashd.
28 TEST(founders_reward_test, create_testnet_2of3multisig) {
29 SelectParams(CBaseChainParams::TESTNET);
30 boost::filesystem::path pathTemp = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path();
31 boost::filesystem::create_directories(pathTemp);
32 mapArgs["-datadir"] = pathTemp.string();
34 auto pWallet = std::make_shared<CWallet>("wallet.dat");
35 ASSERT_EQ(DB_LOAD_OK, pWallet->LoadWallet(fFirstRun));
36 pWallet->TopUpKeyPool();
37 std::cout << "Test wallet and logs saved in folder: " << pathTemp.native() << std::endl;
40 std::vector<CPubKey> pubkeys;
43 std::vector<std::string> addresses;
44 for (int i = 0; i < numKeys; i++) {
45 ASSERT_TRUE(pWallet->GetKeyFromPool(newKey));
47 pWallet->SetAddressBook(newKey.GetID(), "", "receive");
49 ASSERT_TRUE(pWallet->GetKeyFromPool(newKey));
51 pWallet->SetAddressBook(newKey.GetID(), "", "receive");
53 ASSERT_TRUE(pWallet->GetKeyFromPool(newKey));
55 pWallet->SetAddressBook(newKey.GetID(), "", "receive");
57 CScript result = GetScriptForMultisig(2, pubkeys);
58 ASSERT_FALSE(result.size() > CScript::MAX_SCRIPT_ELEMENT_SIZE);
59 CScriptID innerID(result);
60 pWallet->AddCScript(result);
61 pWallet->SetAddressBook(innerID, "", "receive");
63 std::string address = EncodeDestination(innerID);
64 addresses.push_back(address);
67 // Print out the addresses, 4 on each line.
68 std::string s = "vFoundersRewardAddress = {\n";
71 ASSERT_TRUE(numKeys % colsPerRow == 0);
72 int numRows = numKeys/colsPerRow;
73 for (int row=0; row<numRows; row++) {
75 for (int col=0; col<colsPerRow; col++) {
76 s += "\"" + addresses[i++] + "\", ";
81 std::cout << s << std::endl;
88 static int GetLastFoundersRewardHeight(const Consensus::Params& params) {
89 int blossomActivationHeight = Params().GetConsensus().vUpgrades[Consensus::UPGRADE_BLOSSOM].nActivationHeight;
90 bool blossom = blossomActivationHeight != Consensus::NetworkUpgrade::NO_ACTIVATION_HEIGHT;
91 return params.GetLastFoundersRewardBlockHeight(blossom ? blossomActivationHeight : 0);
94 // Utility method to check the number of unique addresses from height 1 to maxHeight
95 void checkNumberOfUniqueAddresses(int nUnique) {
96 std::set<std::string> addresses;
97 for (int i = 1; i <= GetLastFoundersRewardHeight(Params().GetConsensus()); i++) {
98 addresses.insert(Params().GetFoundersRewardAddressAtHeight(i));
100 EXPECT_EQ(addresses.size(), nUnique);
104 TEST(founders_reward_test, general) {
105 SelectParams(CBaseChainParams::TESTNET);
107 CChainParams params = Params();
109 // Fourth testnet reward:
110 // address = t2ENg7hHVqqs9JwU5cgjvSbxnT2a9USNfhy
111 // script.ToString() = OP_HASH160 55d64928e69829d9376c776550b6cc710d427153 OP_EQUAL
112 // HexStr(script) = a91455d64928e69829d9376c776550b6cc710d42715387
113 EXPECT_EQ(HexStr(params.GetFoundersRewardScriptAtHeight(1)), "a914ef775f1f997f122a062fff1a2d7443abd1f9c64287");
114 EXPECT_EQ(params.GetFoundersRewardAddressAtHeight(1), "t2UNzUUx8mWBCRYPRezvA363EYXyEpHokyi");
115 EXPECT_EQ(HexStr(params.GetFoundersRewardScriptAtHeight(53126)), "a914ac67f4c072668138d88a86ff21b27207b283212f87");
116 EXPECT_EQ(params.GetFoundersRewardAddressAtHeight(53126), "t2NGQjYMQhFndDHguvUw4wZdNdsssA6K7x2");
117 EXPECT_EQ(HexStr(params.GetFoundersRewardScriptAtHeight(53127)), "a91455d64928e69829d9376c776550b6cc710d42715387");
118 EXPECT_EQ(params.GetFoundersRewardAddressAtHeight(53127), "t2ENg7hHVqqs9JwU5cgjvSbxnT2a9USNfhy");
120 int maxHeight = GetLastFoundersRewardHeight(params.GetConsensus());
122 // If the block height parameter is out of bounds, there is an assert.
123 EXPECT_DEATH(params.GetFoundersRewardScriptAtHeight(0), "nHeight");
124 EXPECT_DEATH(params.GetFoundersRewardScriptAtHeight(maxHeight+1), "nHeight");
125 EXPECT_DEATH(params.GetFoundersRewardAddressAtHeight(0), "nHeight");
126 EXPECT_DEATH(params.GetFoundersRewardAddressAtHeight(maxHeight+1), "nHeight");
129 TEST(founders_reward_test, regtest_get_last_block_blossom) {
130 int blossomActivationHeight = Consensus::PRE_BLOSSOM_REGTEST_HALVING_INTERVAL / 2; // = 75
131 auto params = RegtestActivateBlossom(false, blossomActivationHeight);
132 int lastFRHeight = params.GetLastFoundersRewardBlockHeight(blossomActivationHeight);
133 EXPECT_EQ(0, params.Halving(lastFRHeight));
134 EXPECT_EQ(1, params.Halving(lastFRHeight + 1));
135 RegtestDeactivateBlossom();
138 TEST(founders_reward_test, mainnet_get_last_block) {
139 SelectParams(CBaseChainParams::MAIN);
140 auto params = Params().GetConsensus();
141 int lastFRHeight = GetLastFoundersRewardHeight(params);
142 EXPECT_EQ(0, params.Halving(lastFRHeight));
143 EXPECT_EQ(1, params.Halving(lastFRHeight + 1));
146 #define NUM_MAINNET_FOUNDER_ADDRESSES 48
148 TEST(founders_reward_test, mainnet) {
149 SelectParams(CBaseChainParams::MAIN);
150 checkNumberOfUniqueAddresses(NUM_MAINNET_FOUNDER_ADDRESSES);
154 #define NUM_TESTNET_FOUNDER_ADDRESSES 48
156 TEST(founders_reward_test, testnet) {
157 SelectParams(CBaseChainParams::TESTNET);
158 checkNumberOfUniqueAddresses(NUM_TESTNET_FOUNDER_ADDRESSES);
162 #define NUM_REGTEST_FOUNDER_ADDRESSES 1
164 TEST(founders_reward_test, regtest) {
165 SelectParams(CBaseChainParams::REGTEST);
166 checkNumberOfUniqueAddresses(NUM_REGTEST_FOUNDER_ADDRESSES);
171 // Test that 10% founders reward is fully rewarded after the first halving and slow start shift.
172 // On Mainnet, this would be 2,100,000 ZEC after 850,000 blocks (840,000 + 10,000).
173 TEST(founders_reward_test, slow_start_subsidy) {
174 SelectParams(CBaseChainParams::MAIN);
175 CChainParams params = Params();
177 CAmount totalSubsidy = 0;
178 for (int nHeight = 1; nHeight <= GetLastFoundersRewardHeight(Params().GetConsensus()); nHeight++) {
179 CAmount nSubsidy = GetBlockSubsidy(nHeight, params.GetConsensus()) / 5;
180 totalSubsidy += nSubsidy;
183 ASSERT_TRUE(totalSubsidy == MAX_MONEY/10.0);
187 // For use with mainnet and testnet which each have 48 addresses.
188 // Verify the number of rewards each individual address receives.
189 void verifyNumberOfRewards() {
190 CChainParams params = Params();
191 int maxHeight = GetLastFoundersRewardHeight(params.GetConsensus());
192 std::map<std::string, CAmount> ms;
193 for (int nHeight = 1; nHeight <= maxHeight; nHeight++) {
194 std::string addr = params.GetFoundersRewardAddressAtHeight(nHeight);
195 if (ms.count(addr) == 0) {
198 ms[addr] = ms[addr] + GetBlockSubsidy(nHeight, params.GetConsensus()) / 5;
201 EXPECT_EQ(ms[params.GetFoundersRewardAddressAtIndex(0)], 1960039937500);
202 EXPECT_EQ(ms[params.GetFoundersRewardAddressAtIndex(1)], 4394460062500);
203 for (int i = 2; i <= 46; i++) {
204 EXPECT_EQ(ms[params.GetFoundersRewardAddressAtIndex(i)], 17709 * COIN * 2.5);
206 EXPECT_EQ(ms[params.GetFoundersRewardAddressAtIndex(47)], 17677 * COIN * 2.5);
209 // Verify the number of rewards going to each mainnet address
210 TEST(founders_reward_test, per_address_reward_mainnet) {
211 SelectParams(CBaseChainParams::MAIN);
212 verifyNumberOfRewards();
215 // Verify the number of rewards going to each testnet address
216 TEST(founders_reward_test, per_address_reward_testnet) {
217 SelectParams(CBaseChainParams::TESTNET);
218 verifyNumberOfRewards();