]>
Commit | Line | Data |
---|---|---|
db0f9315 S |
1 | #include <gtest/gtest.h> |
2 | ||
3 | #include "main.h" | |
4 | #include "utilmoneystr.h" | |
5 | #include "chainparams.h" | |
6 | #include "utilstrencodings.h" | |
7 | #include "zcash/Address.hpp" | |
8 | #include "wallet/wallet.h" | |
9 | #include "amount.h" | |
10 | #include <memory> | |
11 | #include <string> | |
12 | #include <set> | |
13 | #include <vector> | |
14 | #include <boost/filesystem.hpp> | |
32bf097f | 15 | #include "util.h" |
1188c9ad | 16 | #include "utiltest.h" |
db0f9315 | 17 | |
679496c3 | 18 | #ifndef disable_founders |
db0f9315 S |
19 | // To run tests: |
20 | // ./zcash-gtest --gtest_filter="founders_reward_test.*" | |
21 | ||
22 | // | |
23 | // Enable this test to generate and print 48 testnet 2-of-3 multisig addresses. | |
24 | // The output can be copied into chainparams.cpp. | |
88fd8101 | 25 | // The temporary wallet file can be renamed as wallet.dat and used for testing with zcashd. |
db0f9315 S |
26 | // |
27 | #if 0 | |
28 | TEST(founders_reward_test, create_testnet_2of3multisig) { | |
db0f9315 | 29 | SelectParams(CBaseChainParams::TESTNET); |
32bf097f S |
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(); | |
db0f9315 | 33 | bool fFirstRun; |
32bf097f | 34 | auto pWallet = std::make_shared<CWallet>("wallet.dat"); |
db0f9315 S |
35 | ASSERT_EQ(DB_LOAD_OK, pWallet->LoadWallet(fFirstRun)); |
36 | pWallet->TopUpKeyPool(); | |
32bf097f | 37 | std::cout << "Test wallet and logs saved in folder: " << pathTemp.native() << std::endl; |
db0f9315 S |
38 | |
39 | int numKeys = 48; | |
40 | std::vector<CPubKey> pubkeys; | |
41 | pubkeys.resize(3); | |
42 | CPubKey newKey; | |
43 | std::vector<std::string> addresses; | |
241867b1 | 44 | for (int i = 0; i < numKeys; i++) { |
db0f9315 S |
45 | ASSERT_TRUE(pWallet->GetKeyFromPool(newKey)); |
46 | pubkeys[0] = newKey; | |
2911b357 S |
47 | pWallet->SetAddressBook(newKey.GetID(), "", "receive"); |
48 | ||
db0f9315 S |
49 | ASSERT_TRUE(pWallet->GetKeyFromPool(newKey)); |
50 | pubkeys[1] = newKey; | |
2911b357 S |
51 | pWallet->SetAddressBook(newKey.GetID(), "", "receive"); |
52 | ||
db0f9315 S |
53 | ASSERT_TRUE(pWallet->GetKeyFromPool(newKey)); |
54 | pubkeys[2] = newKey; | |
2911b357 S |
55 | pWallet->SetAddressBook(newKey.GetID(), "", "receive"); |
56 | ||
db0f9315 | 57 | CScript result = GetScriptForMultisig(2, pubkeys); |
a4f9bc97 | 58 | ASSERT_FALSE(result.size() > CScript::MAX_SCRIPT_ELEMENT_SIZE); |
db0f9315 | 59 | CScriptID innerID(result); |
2911b357 S |
60 | pWallet->AddCScript(result); |
61 | pWallet->SetAddressBook(innerID, "", "receive"); | |
62 | ||
b6be3e88 | 63 | std::string address = EncodeDestination(innerID); |
db0f9315 S |
64 | addresses.push_back(address); |
65 | } | |
66 | ||
67 | // Print out the addresses, 4 on each line. | |
68 | std::string s = "vFoundersRewardAddress = {\n"; | |
69 | int i=0; | |
70 | int colsPerRow = 4; | |
71 | ASSERT_TRUE(numKeys % colsPerRow == 0); | |
72 | int numRows = numKeys/colsPerRow; | |
73 | for (int row=0; row<numRows; row++) { | |
74 | s += " "; | |
75 | for (int col=0; col<colsPerRow; col++) { | |
76 | s += "\"" + addresses[i++] + "\", "; | |
77 | } | |
78 | s += "\n"; | |
79 | } | |
80 | s += " };"; | |
81 | std::cout << s << std::endl; | |
88fd8101 S |
82 | |
83 | pWallet->Flush(true); | |
db0f9315 S |
84 | } |
85 | #endif | |
86 | ||
87 | ||
42a21ef0 | 88 | static int GetLastFoundersRewardHeight(const Consensus::Params& params) { |
93452c97 EOW |
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); | |
92 | } | |
93 | ||
3b30d836 | 94 | // Utility method to check the number of unique addresses from height 1 to maxHeight |
241867b1 | 95 | void checkNumberOfUniqueAddresses(int nUnique) { |
3b30d836 | 96 | std::set<std::string> addresses; |
93452c97 | 97 | for (int i = 1; i <= GetLastFoundersRewardHeight(Params().GetConsensus()); i++) { |
3b30d836 S |
98 | addresses.insert(Params().GetFoundersRewardAddressAtHeight(i)); |
99 | } | |
93452c97 | 100 | EXPECT_EQ(addresses.size(), nUnique); |
3b30d836 | 101 | } |
db0f9315 | 102 | |
3b30d836 S |
103 | |
104 | TEST(founders_reward_test, general) { | |
db0f9315 S |
105 | SelectParams(CBaseChainParams::TESTNET); |
106 | ||
107 | CChainParams params = Params(); | |
108 | ||
10031802 S |
109 | // Fourth testnet reward: |
110 | // address = t2ENg7hHVqqs9JwU5cgjvSbxnT2a9USNfhy | |
111 | // script.ToString() = OP_HASH160 55d64928e69829d9376c776550b6cc710d427153 OP_EQUAL | |
112 | // HexStr(script) = a91455d64928e69829d9376c776550b6cc710d42715387 | |
d2fb34fb | 113 | EXPECT_EQ(HexStr(params.GetFoundersRewardScriptAtHeight(1)), "a914ef775f1f997f122a062fff1a2d7443abd1f9c64287"); |
9cf182d4 | 114 | EXPECT_EQ(params.GetFoundersRewardAddressAtHeight(1), "t2UNzUUx8mWBCRYPRezvA363EYXyEpHokyi"); |
d2fb34fb | 115 | EXPECT_EQ(HexStr(params.GetFoundersRewardScriptAtHeight(53126)), "a914ac67f4c072668138d88a86ff21b27207b283212f87"); |
10031802 | 116 | EXPECT_EQ(params.GetFoundersRewardAddressAtHeight(53126), "t2NGQjYMQhFndDHguvUw4wZdNdsssA6K7x2"); |
d2fb34fb | 117 | EXPECT_EQ(HexStr(params.GetFoundersRewardScriptAtHeight(53127)), "a91455d64928e69829d9376c776550b6cc710d42715387"); |
10031802 | 118 | EXPECT_EQ(params.GetFoundersRewardAddressAtHeight(53127), "t2ENg7hHVqqs9JwU5cgjvSbxnT2a9USNfhy"); |
db0f9315 | 119 | |
42a21ef0 | 120 | int maxHeight = GetLastFoundersRewardHeight(params.GetConsensus()); |
db0f9315 S |
121 | |
122 | // If the block height parameter is out of bounds, there is an assert. | |
3b30d836 S |
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"); | |
db0f9315 S |
127 | } |
128 | ||
f9d6b3e7 EOW |
129 | TEST(founders_reward_test, regtest_get_last_block_blossom) { |
130 | int blossomActivationHeight = Consensus::PRE_BLOSSOM_REGTEST_HALVING_INTERVAL / 2; // = 75 | |
1188c9ad | 131 | auto params = RegtestActivateBlossom(false, blossomActivationHeight); |
f9d6b3e7 | 132 | int lastFRHeight = params.GetLastFoundersRewardBlockHeight(blossomActivationHeight); |
b99003c1 EOW |
133 | EXPECT_EQ(0, params.Halving(lastFRHeight)); |
134 | EXPECT_EQ(1, params.Halving(lastFRHeight + 1)); | |
2c35e162 | 135 | RegtestDeactivateBlossom(); |
f9d6b3e7 EOW |
136 | } |
137 | ||
138 | TEST(founders_reward_test, mainnet_get_last_block) { | |
139 | SelectParams(CBaseChainParams::MAIN); | |
140 | auto params = Params().GetConsensus(); | |
141 | int lastFRHeight = GetLastFoundersRewardHeight(params); | |
b99003c1 EOW |
142 | EXPECT_EQ(0, params.Halving(lastFRHeight)); |
143 | EXPECT_EQ(1, params.Halving(lastFRHeight + 1)); | |
1188c9ad | 144 | } |
db0f9315 S |
145 | |
146 | #define NUM_MAINNET_FOUNDER_ADDRESSES 48 | |
147 | ||
148 | TEST(founders_reward_test, mainnet) { | |
149 | SelectParams(CBaseChainParams::MAIN); | |
241867b1 | 150 | checkNumberOfUniqueAddresses(NUM_MAINNET_FOUNDER_ADDRESSES); |
3b30d836 S |
151 | } |
152 | ||
153 | ||
154 | #define NUM_TESTNET_FOUNDER_ADDRESSES 48 | |
155 | ||
156 | TEST(founders_reward_test, testnet) { | |
157 | SelectParams(CBaseChainParams::TESTNET); | |
241867b1 | 158 | checkNumberOfUniqueAddresses(NUM_TESTNET_FOUNDER_ADDRESSES); |
db0f9315 S |
159 | } |
160 | ||
161 | ||
162 | #define NUM_REGTEST_FOUNDER_ADDRESSES 1 | |
163 | ||
164 | TEST(founders_reward_test, regtest) { | |
165 | SelectParams(CBaseChainParams::REGTEST); | |
241867b1 | 166 | checkNumberOfUniqueAddresses(NUM_REGTEST_FOUNDER_ADDRESSES); |
db0f9315 S |
167 | } |
168 | ||
169 | ||
170 | ||
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(); | |
176 | ||
db0f9315 | 177 | CAmount totalSubsidy = 0; |
42a21ef0 | 178 | for (int nHeight = 1; nHeight <= GetLastFoundersRewardHeight(Params().GetConsensus()); nHeight++) { |
241867b1 | 179 | CAmount nSubsidy = GetBlockSubsidy(nHeight, params.GetConsensus()) / 5; |
db0f9315 S |
180 | totalSubsidy += nSubsidy; |
181 | } | |
182 | ||
183 | ASSERT_TRUE(totalSubsidy == MAX_MONEY/10.0); | |
184 | } | |
3b30d836 S |
185 | |
186 | ||
1a21a25e S |
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() { | |
3b30d836 | 190 | CChainParams params = Params(); |
93452c97 EOW |
191 | int maxHeight = GetLastFoundersRewardHeight(params.GetConsensus()); |
192 | std::map<std::string, CAmount> ms; | |
241867b1 | 193 | for (int nHeight = 1; nHeight <= maxHeight; nHeight++) { |
93452c97 EOW |
194 | std::string addr = params.GetFoundersRewardAddressAtHeight(nHeight); |
195 | if (ms.count(addr) == 0) { | |
196 | ms[addr] = 0; | |
197 | } | |
198 | ms[addr] = ms[addr] + GetBlockSubsidy(nHeight, params.GetConsensus()) / 5; | |
3b30d836 S |
199 | } |
200 | ||
93452c97 EOW |
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); | |
3b30d836 | 205 | } |
93452c97 | 206 | EXPECT_EQ(ms[params.GetFoundersRewardAddressAtIndex(47)], 17677 * COIN * 2.5); |
3b30d836 S |
207 | } |
208 | ||
1a21a25e S |
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(); | |
213 | } | |
214 | ||
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(); | |
9cf182d4 | 219 | } |
679496c3 | 220 | #endif |