]>
Commit | Line | Data |
---|---|---|
9e52ca32 JG |
1 | #include <future> |
2 | #include <thread> | |
6962bb3d TH |
3 | #include <unistd.h> |
4 | #include <boost/filesystem.hpp> | |
9e52ca32 | 5 | |
6962bb3d TH |
6 | #include "coins.h" |
7 | #include "util.h" | |
8 | #include "init.h" | |
9 | #include "primitives/transaction.h" | |
f5edc37f | 10 | #include "base58.h" |
bf8def97 TH |
11 | #include "crypto/equihash.h" |
12 | #include "chainparams.h" | |
f5edc37f JG |
13 | #include "consensus/validation.h" |
14 | #include "main.h" | |
15 | #include "miner.h" | |
a1cd1a27 | 16 | #include "pow.h" |
f5edc37f | 17 | #include "script/sign.h" |
722b0117 TH |
18 | #include "sodium.h" |
19 | #include "streams.h" | |
f5edc37f | 20 | #include "wallet/wallet.h" |
6962bb3d TH |
21 | |
22 | #include "zcbenchmarks.h" | |
23 | ||
2dc35992 SB |
24 | #include "zcash/Zcash.h" |
25 | #include "zcash/IncrementalMerkleTree.hpp" | |
26 | ||
27 | using namespace libzcash; | |
28 | ||
9e52ca32 | 29 | void timer_start(timeval &tv_start) |
6962bb3d TH |
30 | { |
31 | gettimeofday(&tv_start, 0); | |
32 | } | |
33 | ||
9e52ca32 | 34 | double timer_stop(timeval &tv_start) |
6962bb3d TH |
35 | { |
36 | double elapsed; | |
37 | struct timeval tv_end; | |
38 | gettimeofday(&tv_end, 0); | |
39 | elapsed = double(tv_end.tv_sec-tv_start.tv_sec) + | |
40 | (tv_end.tv_usec-tv_start.tv_usec)/double(1000000); | |
41 | return elapsed; | |
42 | } | |
43 | ||
44 | double benchmark_sleep() | |
45 | { | |
9e52ca32 JG |
46 | struct timeval tv_start; |
47 | timer_start(tv_start); | |
6962bb3d | 48 | sleep(1); |
9e52ca32 | 49 | return timer_stop(tv_start); |
6962bb3d TH |
50 | } |
51 | ||
52 | double benchmark_parameter_loading() | |
53 | { | |
54 | // FIXME: this is duplicated with the actual loading code | |
27e3f362 SB |
55 | boost::filesystem::path pk_path = ZC_GetParamsDir() / "sprout-proving.key"; |
56 | boost::filesystem::path vk_path = ZC_GetParamsDir() / "sprout-verifying.key"; | |
6962bb3d | 57 | |
9e52ca32 JG |
58 | struct timeval tv_start; |
59 | timer_start(tv_start); | |
2dc35992 SB |
60 | |
61 | auto newParams = ZCJoinSplit::Unopened(); | |
62 | ||
63 | newParams->loadVerifyingKey(vk_path.string()); | |
64 | newParams->setProvingKeyPath(pk_path.string()); | |
65 | newParams->loadProvingKey(); | |
66 | ||
9e52ca32 | 67 | double ret = timer_stop(tv_start); |
2dc35992 SB |
68 | |
69 | delete newParams; | |
70 | ||
71 | return ret; | |
6962bb3d TH |
72 | } |
73 | ||
74 | double benchmark_create_joinsplit() | |
75 | { | |
21406393 | 76 | uint256 pubKeyHash; |
6962bb3d | 77 | |
6962bb3d | 78 | /* Get the anchor of an empty commitment tree. */ |
5961dcb6 | 79 | uint256 anchor = ZCIncrementalMerkleTree().root(); |
6962bb3d | 80 | |
9e52ca32 JG |
81 | struct timeval tv_start; |
82 | timer_start(tv_start); | |
22de1602 SB |
83 | JSDescription jsdesc(*pzcashParams, |
84 | pubKeyHash, | |
85 | anchor, | |
86 | {JSInput(), JSInput()}, | |
87 | {JSOutput(), JSOutput()}, | |
88 | 0, | |
89 | 0); | |
9e52ca32 | 90 | double ret = timer_stop(tv_start); |
21406393 | 91 | |
22de1602 | 92 | assert(jsdesc.Verify(*pzcashParams, pubKeyHash)); |
6962bb3d TH |
93 | return ret; |
94 | } | |
bf8def97 | 95 | |
a8c68ffe | 96 | double benchmark_verify_joinsplit(const JSDescription &joinsplit) |
a1cd1a27 | 97 | { |
9e52ca32 JG |
98 | struct timeval tv_start; |
99 | timer_start(tv_start); | |
21406393 | 100 | uint256 pubKeyHash; |
2dc35992 | 101 | joinsplit.Verify(*pzcashParams, pubKeyHash); |
9e52ca32 | 102 | return timer_stop(tv_start); |
a1cd1a27 TH |
103 | } |
104 | ||
9e52ca32 | 105 | double benchmark_solve_equihash() |
bf8def97 | 106 | { |
722b0117 TH |
107 | CBlock pblock; |
108 | CEquihashInput I{pblock}; | |
109 | CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); | |
110 | ss << I; | |
111 | ||
e9574728 JG |
112 | unsigned int n = Params(CBaseChainParams::MAIN).EquihashN(); |
113 | unsigned int k = Params(CBaseChainParams::MAIN).EquihashK(); | |
bf8def97 | 114 | crypto_generichash_blake2b_state eh_state; |
e9574728 | 115 | EhInitialiseState(n, k, eh_state); |
722b0117 TH |
116 | crypto_generichash_blake2b_update(&eh_state, (unsigned char*)&ss[0], ss.size()); |
117 | ||
118 | uint256 nonce; | |
119 | randombytes_buf(nonce.begin(), 32); | |
120 | crypto_generichash_blake2b_update(&eh_state, | |
121 | nonce.begin(), | |
122 | nonce.size()); | |
123 | ||
9e52ca32 JG |
124 | struct timeval tv_start; |
125 | timer_start(tv_start); | |
e9574728 | 126 | std::set<std::vector<unsigned int>> solns; |
51eb5273 | 127 | EhOptimisedSolveUncancellable(n, k, eh_state, |
5be6abbf | 128 | [](std::vector<unsigned char> soln) { return false; }); |
9e52ca32 | 129 | return timer_stop(tv_start); |
f7478de6 JG |
130 | } |
131 | ||
9e52ca32 | 132 | std::vector<double> benchmark_solve_equihash_threaded(int nThreads) |
f7478de6 | 133 | { |
9e52ca32 JG |
134 | std::vector<double> ret; |
135 | std::vector<std::future<double>> tasks; | |
136 | std::vector<std::thread> threads; | |
137 | for (int i = 0; i < nThreads; i++) { | |
138 | std::packaged_task<double(void)> task(&benchmark_solve_equihash); | |
139 | tasks.emplace_back(task.get_future()); | |
140 | threads.emplace_back(std::move(task)); | |
141 | } | |
142 | std::future_status status; | |
143 | for (auto it = tasks.begin(); it != tasks.end(); it++) { | |
144 | it->wait(); | |
145 | ret.push_back(it->get()); | |
146 | } | |
147 | for (auto it = threads.begin(); it != threads.end(); it++) { | |
148 | it->join(); | |
149 | } | |
150 | return ret; | |
bf8def97 | 151 | } |
d44feea4 | 152 | |
a1cd1a27 | 153 | double benchmark_verify_equihash() |
d44feea4 | 154 | { |
a1cd1a27 TH |
155 | CChainParams params = Params(CBaseChainParams::MAIN); |
156 | CBlock genesis = Params(CBaseChainParams::MAIN).GenesisBlock(); | |
157 | CBlockHeader genesis_header = genesis.GetBlockHeader(); | |
9e52ca32 JG |
158 | struct timeval tv_start; |
159 | timer_start(tv_start); | |
a1cd1a27 | 160 | CheckEquihashSolution(&genesis_header, params); |
9e52ca32 | 161 | return timer_stop(tv_start); |
d44feea4 | 162 | } |
a1cd1a27 | 163 | |
9c45b501 | 164 | double benchmark_large_tx() |
f5edc37f | 165 | { |
9c45b501 | 166 | // Number of inputs in the spending transaction that we will simulate |
74f15a73 | 167 | const size_t NUM_INPUTS = 555; |
9c45b501 SB |
168 | |
169 | // Create priv/pub key | |
170 | CKey priv; | |
171 | priv.MakeNewKey(false); | |
172 | auto pub = priv.GetPubKey(); | |
173 | CBasicKeyStore tempKeystore; | |
174 | tempKeystore.AddKey(priv); | |
175 | ||
176 | // The "original" transaction that the spending transaction will spend | |
177 | // from. | |
178 | CMutableTransaction m_orig_tx; | |
179 | m_orig_tx.vout.resize(1); | |
180 | m_orig_tx.vout[0].nValue = 1000000; | |
181 | CScript prevPubKey = GetScriptForDestination(pub.GetID()); | |
182 | m_orig_tx.vout[0].scriptPubKey = prevPubKey; | |
183 | ||
184 | auto orig_tx = CTransaction(m_orig_tx); | |
185 | ||
186 | CMutableTransaction spending_tx; | |
805344dc | 187 | auto input_hash = orig_tx.GetHash(); |
9c45b501 SB |
188 | // Add NUM_INPUTS inputs |
189 | for (size_t i = 0; i < NUM_INPUTS; i++) { | |
190 | spending_tx.vin.emplace_back(input_hash, 0); | |
f5edc37f JG |
191 | } |
192 | ||
9c45b501 SB |
193 | // Sign for all the inputs |
194 | for (size_t i = 0; i < NUM_INPUTS; i++) { | |
195 | SignSignature(tempKeystore, prevPubKey, spending_tx, i, SIGHASH_ALL); | |
f5edc37f | 196 | } |
f5edc37f | 197 | |
9c45b501 SB |
198 | // Serialize: |
199 | { | |
200 | CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); | |
201 | ss << spending_tx; | |
202 | //std::cout << "SIZE OF SPENDING TX: " << ss.size() << std::endl; | |
f5edc37f | 203 | |
74f15a73 SB |
204 | auto error = MAX_TX_SIZE / 20; // 5% error |
205 | assert(ss.size() < MAX_TX_SIZE + error); | |
206 | assert(ss.size() > MAX_TX_SIZE - error); | |
f5edc37f JG |
207 | } |
208 | ||
822b84b6 S |
209 | // Spending tx has all its inputs signed and does not need to be mutated anymore |
210 | CTransaction final_spending_tx(spending_tx); | |
211 | ||
9c45b501 | 212 | // Benchmark signature verification costs: |
9e52ca32 JG |
213 | struct timeval tv_start; |
214 | timer_start(tv_start); | |
9c45b501 SB |
215 | for (size_t i = 0; i < NUM_INPUTS; i++) { |
216 | ScriptError serror = SCRIPT_ERR_OK; | |
75c2f268 | 217 | assert(VerifyScript(final_spending_tx.vin[i].scriptSig, |
9c45b501 SB |
218 | prevPubKey, |
219 | STANDARD_SCRIPT_VERIFY_FLAGS, | |
822b84b6 | 220 | TransactionSignatureChecker(&final_spending_tx, i), |
9c45b501 SB |
221 | &serror)); |
222 | } | |
9e52ca32 | 223 | return timer_stop(tv_start); |
f5edc37f JG |
224 | } |
225 |