]> Git Repo - VerusCoin.git/blob - src/zcbenchmarks.cpp
Auto merge of #1486 - str4d:1456-writewitnesscache-exception-safety, r=bitcartel
[VerusCoin.git] / src / zcbenchmarks.cpp
1 #include <future>
2 #include <thread>
3 #include <unistd.h>
4 #include <boost/filesystem.hpp>
5
6 #include "coins.h"
7 #include "util.h"
8 #include "init.h"
9 #include "primitives/transaction.h"
10 #include "base58.h"
11 #include "crypto/equihash.h"
12 #include "chainparams.h"
13 #include "consensus/validation.h"
14 #include "main.h"
15 #include "miner.h"
16 #include "pow.h"
17 #include "script/sign.h"
18 #include "sodium.h"
19 #include "streams.h"
20 #include "wallet/wallet.h"
21
22 #include "zcbenchmarks.h"
23
24 #include "zcash/Zcash.h"
25 #include "zcash/IncrementalMerkleTree.hpp"
26
27 using namespace libzcash;
28
29 void timer_start(timeval &tv_start)
30 {
31     gettimeofday(&tv_start, 0);
32 }
33
34 double timer_stop(timeval &tv_start)
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 {
46     struct timeval tv_start;
47     timer_start(tv_start);
48     sleep(1);
49     return timer_stop(tv_start);
50 }
51
52 double benchmark_parameter_loading()
53 {
54     // FIXME: this is duplicated with the actual loading code
55     boost::filesystem::path pk_path = ZC_GetParamsDir() / "beta2-proving.key";
56     boost::filesystem::path vk_path = ZC_GetParamsDir() / "beta2-verifying.key";
57
58     struct timeval tv_start;
59     timer_start(tv_start);
60
61     auto newParams = ZCJoinSplit::Unopened();
62
63     newParams->loadVerifyingKey(vk_path.string());
64     newParams->setProvingKeyPath(pk_path.string());
65     newParams->loadProvingKey();
66
67     double ret = timer_stop(tv_start);
68
69     delete newParams;
70
71     return ret;
72 }
73
74 double benchmark_create_joinsplit()
75 {
76     uint256 pubKeyHash;
77
78     /* Get the anchor of an empty commitment tree. */
79     uint256 anchor = ZCIncrementalMerkleTree().root();
80
81     struct timeval tv_start;
82     timer_start(tv_start);
83     JSDescription jsdesc(*pzcashParams,
84                          pubKeyHash,
85                          anchor,
86                          {JSInput(), JSInput()},
87                          {JSOutput(), JSOutput()},
88                          0,
89                          0);
90     double ret = timer_stop(tv_start);
91
92     assert(jsdesc.Verify(*pzcashParams, pubKeyHash));
93     return ret;
94 }
95
96 double benchmark_verify_joinsplit(const JSDescription &joinsplit)
97 {
98     struct timeval tv_start;
99     timer_start(tv_start);
100     uint256 pubKeyHash;
101     joinsplit.Verify(*pzcashParams, pubKeyHash);
102     return timer_stop(tv_start);
103 }
104
105 double benchmark_solve_equihash()
106 {
107     CBlock pblock;
108     CEquihashInput I{pblock};
109     CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
110     ss << I;
111
112     unsigned int n = Params(CBaseChainParams::MAIN).EquihashN();
113     unsigned int k = Params(CBaseChainParams::MAIN).EquihashK();
114     crypto_generichash_blake2b_state eh_state;
115     EhInitialiseState(n, k, eh_state);
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
124     struct timeval tv_start;
125     timer_start(tv_start);
126     std::set<std::vector<unsigned int>> solns;
127     EhOptimisedSolveUncancellable(n, k, eh_state,
128                                   [](std::vector<unsigned char> soln) { return false; });
129     return timer_stop(tv_start);
130 }
131
132 std::vector<double> benchmark_solve_equihash_threaded(int nThreads)
133 {
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;
151 }
152
153 double benchmark_verify_equihash()
154 {
155     CChainParams params = Params(CBaseChainParams::MAIN);
156     CBlock genesis = Params(CBaseChainParams::MAIN).GenesisBlock();
157     CBlockHeader genesis_header = genesis.GetBlockHeader();
158     struct timeval tv_start;
159     timer_start(tv_start);
160     CheckEquihashSolution(&genesis_header, params);
161     return timer_stop(tv_start);
162 }
163
164 double benchmark_large_tx()
165 {
166     // Number of inputs in the spending transaction that we will simulate
167     const size_t NUM_INPUTS = 555;
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;
187     auto input_hash = orig_tx.GetHash();
188     // Add NUM_INPUTS inputs
189     for (size_t i = 0; i < NUM_INPUTS; i++) {
190         spending_tx.vin.emplace_back(input_hash, 0);
191     }
192
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);
196     }
197
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;
203
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);
207     }
208
209     // Spending tx has all its inputs signed and does not need to be mutated anymore
210     CTransaction final_spending_tx(spending_tx);
211
212     // Benchmark signature verification costs:
213     struct timeval tv_start;
214     timer_start(tv_start);
215     for (size_t i = 0; i < NUM_INPUTS; i++) {
216         ScriptError serror = SCRIPT_ERR_OK;
217         assert(VerifyScript(final_spending_tx.vin[i].scriptSig,
218                             prevPubKey,
219                             STANDARD_SCRIPT_VERIFY_FLAGS,
220                             TransactionSignatureChecker(&final_spending_tx, i),
221                             &serror));
222     }
223     return timer_stop(tv_start);
224 }
225
This page took 0.036119 seconds and 4 git commands to generate.