]> Git Repo - VerusCoin.git/blame - src/zcbenchmarks.cpp
Remove debug outs
[VerusCoin.git] / src / zcbenchmarks.cpp
CommitLineData
c66c731a 1#include <cstdio>
9e52ca32 2#include <future>
c66c731a 3#include <map>
9e52ca32 4#include <thread>
6962bb3d
TH
5#include <unistd.h>
6#include <boost/filesystem.hpp>
9e52ca32 7
6962bb3d
TH
8#include "coins.h"
9#include "util.h"
10#include "init.h"
11#include "primitives/transaction.h"
f5edc37f 12#include "base58.h"
bf8def97 13#include "crypto/equihash.h"
c66c731a 14#include "chain.h"
bf8def97 15#include "chainparams.h"
be126699 16#include "consensus/upgrades.h"
f5edc37f
JG
17#include "consensus/validation.h"
18#include "main.h"
19#include "miner.h"
a1cd1a27 20#include "pow.h"
4519a766 21#include "rpc/server.h"
f5edc37f 22#include "script/sign.h"
722b0117
TH
23#include "sodium.h"
24#include "streams.h"
c66c731a 25#include "txdb.h"
0bb3d40f 26#include "utiltest.h"
f5edc37f 27#include "wallet/wallet.h"
6962bb3d
TH
28
29#include "zcbenchmarks.h"
30
2dc35992
SB
31#include "zcash/Zcash.h"
32#include "zcash/IncrementalMerkleTree.hpp"
67d2b797
S
33#include "zcash/Note.hpp"
34#include "librustzcash.h"
2dc35992
SB
35
36using namespace libzcash;
2e8aefdc
AG
37// This method is based on Shutdown from init.cpp
38void pre_wallet_load()
39{
40 LogPrintf("%s: In progress...\n", __func__);
41 if (ShutdownRequested())
42 throw new std::runtime_error("The node is shutting down");
43
44 if (pwalletMain)
45 pwalletMain->Flush(false);
46#ifdef ENABLE_MINING
88d014d0 47#ifdef ENABLE_WALLET
2e8aefdc 48 GenerateBitcoins(false, NULL, 0);
88d014d0 49#else
50 GenerateBitcoins(false, 0);
51#endif
2e8aefdc
AG
52#endif
53 UnregisterNodeSignals(GetNodeSignals());
54 if (pwalletMain)
55 pwalletMain->Flush(true);
56
57 UnregisterValidationInterface(pwalletMain);
58 delete pwalletMain;
59 pwalletMain = NULL;
60 bitdb.Reset();
61 RegisterNodeSignals(GetNodeSignals());
62 LogPrintf("%s: done\n", __func__);
63}
64
65void post_wallet_load(){
66 RegisterValidationInterface(pwalletMain);
67#ifdef ENABLE_MINING
68 // Generate coins in the background
69 if (pwalletMain || !GetArg("-mineraddress", "").empty())
88d014d0 70 {
71 #ifdef ENABLE_WALLET
72 GenerateBitcoins(GetBoolArg("-gen",false), pwalletMain, GetArg("-genproclimit", 0));
73 #else
74 GenerateBitcoins(GetBoolArg("-gen",false), GetArg("-genproclimit", 0));
75 #endif
76 }
2e8aefdc
AG
77#endif
78}
79
2dc35992 80
9e52ca32 81void timer_start(timeval &tv_start)
6962bb3d
TH
82{
83 gettimeofday(&tv_start, 0);
84}
85
9e52ca32 86double timer_stop(timeval &tv_start)
6962bb3d
TH
87{
88 double elapsed;
89 struct timeval tv_end;
90 gettimeofday(&tv_end, 0);
91 elapsed = double(tv_end.tv_sec-tv_start.tv_sec) +
92 (tv_end.tv_usec-tv_start.tv_usec)/double(1000000);
93 return elapsed;
94}
95
96double benchmark_sleep()
97{
9e52ca32
JG
98 struct timeval tv_start;
99 timer_start(tv_start);
6962bb3d 100 sleep(1);
9e52ca32 101 return timer_stop(tv_start);
6962bb3d
TH
102}
103
104double benchmark_parameter_loading()
105{
106 // FIXME: this is duplicated with the actual loading code
27e3f362
SB
107 boost::filesystem::path pk_path = ZC_GetParamsDir() / "sprout-proving.key";
108 boost::filesystem::path vk_path = ZC_GetParamsDir() / "sprout-verifying.key";
6962bb3d 109
9e52ca32
JG
110 struct timeval tv_start;
111 timer_start(tv_start);
2dc35992 112
1a9543d0 113 auto newParams = ZCJoinSplit::Prepared(vk_path.string(), pk_path.string());
2dc35992 114
9e52ca32 115 double ret = timer_stop(tv_start);
2dc35992
SB
116
117 delete newParams;
118
119 return ret;
6962bb3d
TH
120}
121
122double benchmark_create_joinsplit()
123{
e1a3461c 124 uint256 joinSplitPubKey;
6962bb3d 125
6962bb3d 126 /* Get the anchor of an empty commitment tree. */
4fc309f0 127 uint256 anchor = SproutMerkleTree().root();
6962bb3d 128
9e52ca32
JG
129 struct timeval tv_start;
130 timer_start(tv_start);
34f6ea95 131 JSDescription jsdesc(true,
b7a6c321 132 *pzcashParams,
e1a3461c 133 joinSplitPubKey,
22de1602
SB
134 anchor,
135 {JSInput(), JSInput()},
136 {JSOutput(), JSOutput()},
137 0,
138 0);
9e52ca32 139 double ret = timer_stop(tv_start);
21406393 140
bc59f537 141 auto verifier = libzcash::ProofVerifier::Strict();
e1a3461c 142 assert(jsdesc.Verify(*pzcashParams, verifier, joinSplitPubKey));
6962bb3d
TH
143 return ret;
144}
bf8def97 145
4082dcb1
JG
146std::vector<double> benchmark_create_joinsplit_threaded(int nThreads)
147{
148 std::vector<double> ret;
149 std::vector<std::future<double>> tasks;
150 std::vector<std::thread> threads;
151 for (int i = 0; i < nThreads; i++) {
152 std::packaged_task<double(void)> task(&benchmark_create_joinsplit);
153 tasks.emplace_back(task.get_future());
154 threads.emplace_back(std::move(task));
155 }
156 std::future_status status;
157 for (auto it = tasks.begin(); it != tasks.end(); it++) {
158 it->wait();
159 ret.push_back(it->get());
160 }
161 for (auto it = threads.begin(); it != threads.end(); it++) {
162 it->join();
163 }
164 return ret;
165}
166
a8c68ffe 167double benchmark_verify_joinsplit(const JSDescription &joinsplit)
a1cd1a27 168{
9e52ca32
JG
169 struct timeval tv_start;
170 timer_start(tv_start);
e1a3461c 171 uint256 joinSplitPubKey;
bc59f537 172 auto verifier = libzcash::ProofVerifier::Strict();
e1a3461c 173 joinsplit.Verify(*pzcashParams, verifier, joinSplitPubKey);
9e52ca32 174 return timer_stop(tv_start);
a1cd1a27
TH
175}
176
2cc0a252 177#ifdef ENABLE_MINING
9e52ca32 178double benchmark_solve_equihash()
bf8def97 179{
722b0117
TH
180 CBlock pblock;
181 CEquihashInput I{pblock};
182 CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
183 ss << I;
184
cea06a4f
JG
185 auto params = Params(CBaseChainParams::MAIN).GetConsensus();
186 unsigned int n = params.nEquihashN;
187 unsigned int k = params.nEquihashK;
bf8def97 188 crypto_generichash_blake2b_state eh_state;
e9574728 189 EhInitialiseState(n, k, eh_state);
722b0117
TH
190 crypto_generichash_blake2b_update(&eh_state, (unsigned char*)&ss[0], ss.size());
191
192 uint256 nonce;
193 randombytes_buf(nonce.begin(), 32);
194 crypto_generichash_blake2b_update(&eh_state,
195 nonce.begin(),
196 nonce.size());
197
9e52ca32
JG
198 struct timeval tv_start;
199 timer_start(tv_start);
e9574728 200 std::set<std::vector<unsigned int>> solns;
51eb5273 201 EhOptimisedSolveUncancellable(n, k, eh_state,
5be6abbf 202 [](std::vector<unsigned char> soln) { return false; });
9e52ca32 203 return timer_stop(tv_start);
f7478de6
JG
204}
205
9e52ca32 206std::vector<double> benchmark_solve_equihash_threaded(int nThreads)
f7478de6 207{
9e52ca32
JG
208 std::vector<double> ret;
209 std::vector<std::future<double>> tasks;
210 std::vector<std::thread> threads;
211 for (int i = 0; i < nThreads; i++) {
212 std::packaged_task<double(void)> task(&benchmark_solve_equihash);
213 tasks.emplace_back(task.get_future());
214 threads.emplace_back(std::move(task));
215 }
216 std::future_status status;
217 for (auto it = tasks.begin(); it != tasks.end(); it++) {
218 it->wait();
219 ret.push_back(it->get());
220 }
221 for (auto it = threads.begin(); it != threads.end(); it++) {
222 it->join();
223 }
224 return ret;
bf8def97 225}
2cc0a252 226#endif // ENABLE_MINING
d44feea4 227
a1cd1a27 228double benchmark_verify_equihash()
d44feea4 229{
a1cd1a27 230 CChainParams params = Params(CBaseChainParams::MAIN);
cea06a4f 231 CBlock genesis = params.GenesisBlock();
a1cd1a27 232 CBlockHeader genesis_header = genesis.GetBlockHeader();
9e52ca32
JG
233 struct timeval tv_start;
234 timer_start(tv_start);
cea06a4f 235 CheckEquihashSolution(&genesis_header, params.GetConsensus());
9e52ca32 236 return timer_stop(tv_start);
d44feea4 237}
a1cd1a27 238
818b94f9 239double benchmark_large_tx(size_t nInputs)
f5edc37f 240{
9c45b501
SB
241 // Create priv/pub key
242 CKey priv;
243 priv.MakeNewKey(false);
244 auto pub = priv.GetPubKey();
245 CBasicKeyStore tempKeystore;
246 tempKeystore.AddKey(priv);
247
248 // The "original" transaction that the spending transaction will spend
249 // from.
250 CMutableTransaction m_orig_tx;
251 m_orig_tx.vout.resize(1);
252 m_orig_tx.vout[0].nValue = 1000000;
253 CScript prevPubKey = GetScriptForDestination(pub.GetID());
254 m_orig_tx.vout[0].scriptPubKey = prevPubKey;
255
256 auto orig_tx = CTransaction(m_orig_tx);
257
258 CMutableTransaction spending_tx;
45539018 259 spending_tx.fOverwintered = true;
ddcee7e1
JG
260 spending_tx.nVersionGroupId = SAPLING_VERSION_GROUP_ID;
261 spending_tx.nVersion = SAPLING_TX_VERSION;
45539018 262
805344dc 263 auto input_hash = orig_tx.GetHash();
818b94f9
JG
264 // Add nInputs inputs
265 for (size_t i = 0; i < nInputs; i++) {
9c45b501 266 spending_tx.vin.emplace_back(input_hash, 0);
f5edc37f
JG
267 }
268
9c45b501 269 // Sign for all the inputs
ddcee7e1 270 auto consensusBranchId = NetworkUpgradeInfo[Consensus::UPGRADE_SAPLING].nBranchId;
818b94f9 271 for (size_t i = 0; i < nInputs; i++) {
be126699 272 SignSignature(tempKeystore, prevPubKey, spending_tx, i, 1000000, SIGHASH_ALL, consensusBranchId);
f5edc37f 273 }
f5edc37f 274
822b84b6
S
275 // Spending tx has all its inputs signed and does not need to be mutated anymore
276 CTransaction final_spending_tx(spending_tx);
277
9c45b501 278 // Benchmark signature verification costs:
9e52ca32
JG
279 struct timeval tv_start;
280 timer_start(tv_start);
45539018 281 PrecomputedTransactionData txdata(final_spending_tx);
818b94f9 282 for (size_t i = 0; i < nInputs; i++) {
9c45b501 283 ScriptError serror = SCRIPT_ERR_OK;
75c2f268 284 assert(VerifyScript(final_spending_tx.vin[i].scriptSig,
9c45b501
SB
285 prevPubKey,
286 STANDARD_SCRIPT_VERIFY_FLAGS,
45539018 287 TransactionSignatureChecker(&final_spending_tx, i, 1000000, txdata),
be126699 288 consensusBranchId,
9c45b501
SB
289 &serror));
290 }
9e52ca32 291 return timer_stop(tv_start);
f5edc37f
JG
292}
293
3e5cc59c 294// The two benchmarks, try_decrypt_sprout_notes and try_decrypt_sapling_notes,
8a1d1930 295// are checking worst-case scenarios. In both we add n keys to a wallet,
3e5cc59c
EOW
296// create a transaction using a key not in our original list of n, and then
297// check that the transaction is not associated with any of the keys in our
298// wallet. We call assert(...) to ensure that this is true.
299double benchmark_try_decrypt_sprout_notes(size_t nKeys)
0fbab55b 300{
0fbab55b 301 CWallet wallet;
3e5cc59c 302 for (int i = 0; i < nKeys; i++) {
e5eab182 303 auto sk = libzcash::SproutSpendingKey::random();
25d5e80c 304 wallet.AddSproutSpendingKey(sk);
0fbab55b
JG
305 }
306
e5eab182 307 auto sk = libzcash::SproutSpendingKey::random();
8f410367 308 auto tx = GetValidSproutReceive(*pzcashParams, sk, 10, true);
0fbab55b
JG
309
310 struct timeval tv_start;
311 timer_start(tv_start);
3e5cc59c
EOW
312 auto noteDataMap = wallet.FindMySproutNotes(tx);
313
314 assert(noteDataMap.empty());
0fbab55b
JG
315 return timer_stop(tv_start);
316}
317
3e5cc59c 318double benchmark_try_decrypt_sapling_notes(size_t nKeys)
89e75c8c
EOW
319{
320 // Set params
a6a17c45 321 auto consensusParams = Params().GetConsensus();
89e75c8c 322
8a1d1930 323 auto masterKey = GetTestMasterSaplingSpendingKey();
89e75c8c
EOW
324
325 CWallet wallet;
89e75c8c 326
8a1d1930 327 for (int i = 0; i < nKeys; i++) {
89e75c8c
EOW
328 auto sk = masterKey.Derive(i);
329 wallet.AddSaplingSpendingKey(sk, sk.DefaultAddress());
330 }
331
8a1d1930
EOW
332 // Generate a key that has not been added to the wallet
333 auto sk = masterKey.Derive(nKeys);
3e5cc59c 334 auto tx = GetValidSaplingReceive(consensusParams, wallet, sk, 10);
0fbab55b
JG
335
336 struct timeval tv_start;
337 timer_start(tv_start);
3e5cc59c
EOW
338 auto noteDataMapAndAddressesToAdd = wallet.FindMySaplingNotes(tx);
339 assert(noteDataMapAndAddressesToAdd.first.empty());
0fbab55b
JG
340 return timer_stop(tv_start);
341}
342
edac39b8
EOW
343CWalletTx CreateSproutTxWithNoteData(const libzcash::SproutSpendingKey& sk) {
344 auto wtx = GetValidSproutReceive(*pzcashParams, sk, 10, true);
345 auto note = GetSproutNote(*pzcashParams, sk, wtx, 0, 1);
346 auto nullifier = note.nullifier(sk);
347
348 mapSproutNoteData_t noteDataMap;
349 JSOutPoint jsoutpt {wtx.GetHash(), 0, 1};
350 SproutNoteData nd {sk.address(), nullifier};
351 noteDataMap[jsoutpt] = nd;
352
353 wtx.SetSproutNoteData(noteDataMap);
354
355 return wtx;
356}
357
8a1d1930 358double benchmark_increment_sprout_note_witnesses(size_t nTxs)
0bb3d40f 359{
3e5cc59c
EOW
360 auto consensusParams = Params().GetConsensus();
361
0bb3d40f 362 CWallet wallet;
4fc309f0
EOW
363 SproutMerkleTree sproutTree;
364 SaplingMerkleTree saplingTree;
0bb3d40f 365
3e5cc59c
EOW
366 auto sproutSpendingKey = libzcash::SproutSpendingKey::random();
367 wallet.AddSproutSpendingKey(sproutSpendingKey);
0bb3d40f
JG
368
369 // First block
370 CBlock block1;
3e5cc59c
EOW
371 for (int i = 0; i < nTxs; ++i) {
372 auto wtx = CreateSproutTxWithNoteData(sproutSpendingKey);
0bb3d40f
JG
373 wallet.AddToWallet(wtx, true, NULL);
374 block1.vtx.push_back(wtx);
375 }
3e5cc59c 376
0bb3d40f 377 CBlockIndex index1(block1);
4b729ec5 378 index1.SetHeight(1);
0bb3d40f
JG
379
380 // Increment to get transactions witnessed
f86ee1c2 381 wallet.ChainTip(&index1, &block1, sproutTree, saplingTree, true);
0bb3d40f
JG
382
383 // Second block
384 CBlock block2;
385 block2.hashPrevBlock = block1.GetHash();
9755eb82 386 {
3e5cc59c
EOW
387 auto sproutTx = CreateSproutTxWithNoteData(sproutSpendingKey);
388 wallet.AddToWallet(sproutTx, true, NULL);
389 block2.vtx.push_back(sproutTx);
390 }
391
392 CBlockIndex index2(block2);
88d014d0 393 index2.SetHeight(2);
3e5cc59c
EOW
394
395 struct timeval tv_start;
396 timer_start(tv_start);
397 wallet.ChainTip(&index2, &block2, sproutTree, saplingTree, true);
398 return timer_stop(tv_start);
399}
400
edac39b8 401CWalletTx CreateSaplingTxWithNoteData(const Consensus::Params& consensusParams,
3e5cc59c 402 CBasicKeyStore& keyStore,
edac39b8 403 const libzcash::SaplingExtendedSpendingKey &sk) {
3e5cc59c 404 auto wtx = GetValidSaplingReceive(consensusParams, keyStore, sk, 10);
edac39b8
EOW
405 auto testNote = GetTestSaplingNote(sk.DefaultAddress(), 10);
406 auto fvk = sk.expsk.full_viewing_key();
407 auto nullifier = testNote.note.nullifier(fvk, testNote.tree.witness().position()).get();
408
409 mapSaplingNoteData_t noteDataMap;
410 SaplingOutPoint outPoint {wtx.GetHash(), 0};
411 auto ivk = fvk.in_viewing_key();
412 SaplingNoteData noteData {ivk, nullifier};
413 noteDataMap[outPoint] = noteData;
414
415 wtx.SetSaplingNoteData(noteDataMap);
9755eb82 416
edac39b8
EOW
417 return wtx;
418}
419
8a1d1930 420double benchmark_increment_sapling_note_witnesses(size_t nTxs)
0bb3d40f 421{
a6a17c45 422 auto consensusParams = Params().GetConsensus();
edac39b8 423
0bb3d40f 424 CWallet wallet;
4fc309f0
EOW
425 SproutMerkleTree sproutTree;
426 SaplingMerkleTree saplingTree;
0bb3d40f 427
8a1d1930 428 auto saplingSpendingKey = GetTestMasterSaplingSpendingKey();
edac39b8 429 wallet.AddSaplingSpendingKey(saplingSpendingKey, saplingSpendingKey.DefaultAddress());
9755eb82 430
edac39b8
EOW
431 // First block
432 CBlock block1;
3e5cc59c
EOW
433 for (int i = 0; i < nTxs; ++i) {
434 auto wtx = CreateSaplingTxWithNoteData(consensusParams, wallet, saplingSpendingKey);
9755eb82 435 wallet.AddToWallet(wtx, true, NULL);
0bb3d40f
JG
436 block1.vtx.push_back(wtx);
437 }
edac39b8 438
0bb3d40f 439 CBlockIndex index1(block1);
88d014d0 440 index1.SetHeight(1);
0bb3d40f
JG
441
442 // Increment to get transactions witnessed
f86ee1c2 443 wallet.ChainTip(&index1, &block1, sproutTree, saplingTree, true);
0bb3d40f
JG
444
445 // Second block
446 CBlock block2;
447 block2.hashPrevBlock = block1.GetHash();
9755eb82 448 {
3e5cc59c 449 auto saplingTx = CreateSaplingTxWithNoteData(consensusParams, wallet, saplingSpendingKey);
edac39b8
EOW
450 wallet.AddToWallet(saplingTx, true, NULL);
451 block1.vtx.push_back(saplingTx);
9755eb82 452 }
edac39b8 453
0bb3d40f 454 CBlockIndex index2(block2);
4b729ec5 455 index2.SetHeight(2);
0bb3d40f
JG
456
457 struct timeval tv_start;
458 timer_start(tv_start);
f86ee1c2 459 wallet.ChainTip(&index2, &block2, sproutTree, saplingTree, true);
0bb3d40f
JG
460 return timer_stop(tv_start);
461}
462
c66c731a 463// Fake the input of a given block
010481c7
EOW
464// This class is based on the class CCoinsViewDB, but with limited functionality.
465// The construtor and the functions `GetCoins` and `HaveCoins` come directly from
466// CCoinsViewDB, but the rest are either mocks and/or don't really do anything.
e1df250a
LR
467
468// The following constant is a duplicate of the one found in txdb.cpp
469static const char DB_COINS = 'c';
470
010481c7 471class FakeCoinsViewDB : public CCoinsView {
010481c7
EOW
472
473 CDBWrapper db;
474
c66c731a 475 uint256 hash;
010481c7
EOW
476 SproutMerkleTree sproutTree;
477 SaplingMerkleTree saplingTree;
c66c731a
JG
478
479public:
010481c7 480 FakeCoinsViewDB(std::string dbName, uint256& hash) : db(GetDataDir() / dbName, 100, false, false), hash(hash) {}
c66c731a 481
010481c7
EOW
482 bool GetSproutAnchorAt(const uint256 &rt, SproutMerkleTree &tree) const {
483 if (rt == sproutTree.root()) {
484 tree = sproutTree;
485 return true;
486 }
487 return false;
488 }
c66c731a 489
010481c7
EOW
490 bool GetSaplingAnchorAt(const uint256 &rt, SaplingMerkleTree &tree) const {
491 if (rt == saplingTree.root()) {
492 tree = saplingTree;
c66c731a
JG
493 return true;
494 }
495 return false;
496 }
497
28d20bdb 498 bool GetNullifier(const uint256 &nf, ShieldedType type) const {
c66c731a
JG
499 return false;
500 }
501
010481c7
EOW
502 bool GetCoins(const uint256 &txid, CCoins &coins) const {
503 return db.Read(std::make_pair(DB_COINS, txid), coins);
504 }
505
506 bool HaveCoins(const uint256 &txid) const {
507 return db.Exists(std::make_pair(DB_COINS, txid));
508 }
509
c66c731a
JG
510 uint256 GetBestBlock() const {
511 return hash;
512 }
513
010481c7
EOW
514 uint256 GetBestAnchor(ShieldedType type) const {
515 switch (type) {
516 case SPROUT:
517 return sproutTree.root();
518 case SAPLING:
519 return saplingTree.root();
520 default:
521 throw new std::runtime_error("Unknown shielded type");
522 }
c66c731a
JG
523 }
524
525 bool BatchWrite(CCoinsMap &mapCoins,
526 const uint256 &hashBlock,
010481c7
EOW
527 const uint256 &hashSproutAnchor,
528 const uint256 &hashSaplingAnchor,
d455828f 529 CAnchorsSproutMap &mapSproutAnchors,
010481c7 530 CAnchorsSaplingMap &mapSaplingAnchors,
9669920f 531 CNullifiersMap &mapSproutNullifiers,
010481c7 532 CNullifiersMap &mapSaplingNullifiers) {
c66c731a
JG
533 return false;
534 }
535
536 bool GetStats(CCoinsStats &stats) const {
537 return false;
538 }
539};
540
541double benchmark_connectblock_slow()
542{
543 // Test for issue 2017-05-01.a
544 SelectParams(CBaseChainParams::MAIN);
545 CBlock block;
546 FILE* fp = fopen((GetDataDir() / "benchmark/block-107134.dat").string().c_str(), "rb");
547 if (!fp) throw new std::runtime_error("Failed to open block data file");
548 CAutoFile blkFile(fp, SER_DISK, CLIENT_VERSION);
549 blkFile >> block;
550 blkFile.fclose();
551
552 // Fake its inputs
553 auto hashPrev = uint256S("00000000159a41f468e22135942a567781c3f3dc7ad62257993eb3c69c3f95ef");
554 FakeCoinsViewDB fakeDB("benchmark/block-107134-inputs", hashPrev);
555 CCoinsViewCache view(&fakeDB);
556
557 // Fake the chain
558 CBlockIndex index(block);
4b729ec5 559 index.SetHeight(107134);
c66c731a
JG
560 CBlockIndex indexPrev;
561 indexPrev.phashBlock = &hashPrev;
4b729ec5 562 indexPrev.SetHeight(index.GetHeight() - 1);
c66c731a
JG
563 index.pprev = &indexPrev;
564 mapBlockIndex.insert(std::make_pair(hashPrev, &indexPrev));
565
566 CValidationState state;
567 struct timeval tv_start;
568 timer_start(tv_start);
e9128c4a 569 assert(ConnectBlock(block, state, &index, view, Params(), true));
c66c731a
JG
570 auto duration = timer_stop(tv_start);
571
572 // Undo alterations to global state
573 mapBlockIndex.erase(hashPrev);
574 SelectParamsFromCommandLine();
575
576 return duration;
577}
578
34aca1b0
JS
579extern UniValue getnewaddress(const UniValue& params, bool fHelp); // in rpcwallet.cpp
580extern UniValue sendtoaddress(const UniValue& params, bool fHelp);
581
a76174b7
JG
582double benchmark_sendtoaddress(CAmount amount)
583{
584 UniValue params(UniValue::VARR);
585 auto addr = getnewaddress(params, false);
586
587 params.push_back(addr);
588 params.push_back(ValueFromAmount(amount));
589
590 struct timeval tv_start;
591 timer_start(tv_start);
592 auto txid = sendtoaddress(params, false);
593 return timer_stop(tv_start);
594}
595
2e8aefdc
AG
596double benchmark_loadwallet()
597{
598 pre_wallet_load();
599 struct timeval tv_start;
600 bool fFirstRunRet=true;
601 timer_start(tv_start);
602 pwalletMain = new CWallet("wallet.dat");
603 DBErrors nLoadWalletRet = pwalletMain->LoadWallet(fFirstRunRet);
604 auto res = timer_stop(tv_start);
605 post_wallet_load();
606 return res;
607}
99dd50c3 608
a9496b08
WL
609extern UniValue listunspent(const UniValue& params, bool fHelp);
610
99dd50c3
JG
611double benchmark_listunspent()
612{
613 UniValue params(UniValue::VARR);
614 struct timeval tv_start;
615 timer_start(tv_start);
616 auto unspent = listunspent(params, false);
617 return timer_stop(tv_start);
618}
67d2b797
S
619
620double benchmark_create_sapling_spend()
621{
622 auto sk = libzcash::SaplingSpendingKey::random();
623 auto expsk = sk.expanded_spending_key();
624 auto address = sk.default_address();
625 SaplingNote note(address, GetRand(MAX_MONEY));
626 SaplingMerkleTree tree;
627 auto maybe_cm = note.cm();
628 tree.append(maybe_cm.get());
629 auto anchor = tree.root();
630 auto witness = tree.witness();
631 auto maybe_nf = note.nullifier(expsk.full_viewing_key(), witness.position());
632 if (!(maybe_cm && maybe_nf)) {
633 throw JSONRPCError(RPC_INTERNAL_ERROR, "Could not create note commitment and nullifier");
634 }
635
636 CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
637 ss << witness.path();
638 std::vector<unsigned char> witnessChars(ss.begin(), ss.end());
639
640 uint256 alpha;
641 librustzcash_sapling_generate_r(alpha.begin());
642
643 auto ctx = librustzcash_sapling_proving_ctx_init();
644
645 struct timeval tv_start;
646 timer_start(tv_start);
647
648 SpendDescription sdesc;
649 bool result = librustzcash_sapling_spend_proof(
650 ctx,
651 expsk.full_viewing_key().ak.begin(),
652 expsk.nsk.begin(),
653 note.d.data(),
654 note.r.begin(),
655 alpha.begin(),
656 note.value(),
657 anchor.begin(),
658 witnessChars.data(),
659 sdesc.cv.begin(),
660 sdesc.rk.begin(),
661 sdesc.zkproof.data());
662
663 double t = timer_stop(tv_start);
664 librustzcash_sapling_proving_ctx_free(ctx);
665 if (!result) {
666 throw JSONRPCError(RPC_INTERNAL_ERROR, "librustzcash_sapling_spend_proof() should return true");
667 }
668 return t;
669}
670
671double benchmark_create_sapling_output()
672{
673 auto sk = libzcash::SaplingSpendingKey::random();
674 auto address = sk.default_address();
675
676 std::array<unsigned char, ZC_MEMO_SIZE> memo;
677 SaplingNote note(address, GetRand(MAX_MONEY));
678
679 libzcash::SaplingNotePlaintext notePlaintext(note, memo);
680 auto res = notePlaintext.encrypt(note.pk_d);
681 if (!res) {
682 throw JSONRPCError(RPC_INTERNAL_ERROR, "SaplingNotePlaintext::encrypt() failed");
683 }
684
685 auto enc = res.get();
686 auto encryptor = enc.second;
687
688 auto ctx = librustzcash_sapling_proving_ctx_init();
689
690 struct timeval tv_start;
691 timer_start(tv_start);
692
693 OutputDescription odesc;
694 bool result = librustzcash_sapling_output_proof(
695 ctx,
696 encryptor.get_esk().begin(),
697 note.d.data(),
698 note.pk_d.begin(),
699 note.r.begin(),
700 note.value(),
701 odesc.cv.begin(),
702 odesc.zkproof.begin());
703
704 double t = timer_stop(tv_start);
705 librustzcash_sapling_proving_ctx_free(ctx);
706 if (!result) {
707 throw JSONRPCError(RPC_INTERNAL_ERROR, "librustzcash_sapling_output_proof() should return true");
708 }
709 return t;
710}
711
712// Verify Sapling spend from testnet
713// txid: abbd823cbd3d4e3b52023599d81a96b74817e95ce5bb58354f979156bd22ecc8
714// position: 0
715double benchmark_verify_sapling_spend()
716{
717 SpendDescription spend;
718 CDataStream ss(ParseHex("8c6cf86bbb83bf0d075e5bd9bb4b5cd56141577be69f032880b11e26aa32aa5ef09fd00899e4b469fb11f38e9d09dc0379f0b11c23b5fe541765f76695120a03f0261d32af5d2a2b1e5c9a04200cd87d574dc42349de9790012ce560406a8a876a1e54cfcdc0eb74998abec2a9778330eeb2a0ac0e41d0c9ed5824fbd0dbf7da930ab299966ce333fd7bc1321dada0817aac5444e02c754069e218746bf879d5f2a20a8b028324fb2c73171e63336686aa5ec2e6e9a08eb18b87c14758c572f4531ccf6b55d09f44beb8b47563be4eff7a52598d80959dd9c9fee5ac4783d8370cb7d55d460053d3e067b5f9fe75ff2722623fb1825fcba5e9593d4205b38d1f502ff03035463043bd393a5ee039ce75a5d54f21b395255df6627ef96751566326f7d4a77d828aa21b1827282829fcbc42aad59cdb521e1a3aaa08b99ea8fe7fff0a04da31a52260fc6daeccd79bb877bdd8506614282258e15b3fe74bf71a93f4be3b770119edf99a317b205eea7d5ab800362b97384273888106c77d633600"), SER_NETWORK, PROTOCOL_VERSION);
719 ss >> spend;
720 uint256 dataToBeSigned = uint256S("0x2dbf83fe7b88a7cbd80fac0c719483906bb9a0c4fc69071e4780d5f2c76e592c");
721
722 auto ctx = librustzcash_sapling_verification_ctx_init();
723
724 struct timeval tv_start;
725 timer_start(tv_start);
726
727 bool result = librustzcash_sapling_check_spend(
728 ctx,
729 spend.cv.begin(),
730 spend.anchor.begin(),
731 spend.nullifier.begin(),
732 spend.rk.begin(),
733 spend.zkproof.begin(),
734 spend.spendAuthSig.begin(),
735 dataToBeSigned.begin()
736 );
737
738 double t = timer_stop(tv_start);
739 librustzcash_sapling_verification_ctx_free(ctx);
740 if (!result) {
741 throw JSONRPCError(RPC_INTERNAL_ERROR, "librustzcash_sapling_check_spend() should return true");
742 }
743 return t;
744}
745
746// Verify Sapling output from testnet
747// txid: abbd823cbd3d4e3b52023599d81a96b74817e95ce5bb58354f979156bd22ecc8
748// position: 0
749double benchmark_verify_sapling_output()
750{
751 OutputDescription output;
752 CDataStream ss(ParseHex("edd742af18857e5ec2d71d346a7fe2ac97c137339bd5268eea86d32e0ff4f38f76213fa8cfed3347ac4e8572dd88aff395c0c10a59f8b3f49d2bc539ed6c726667e29d4763f914ddd0abf1cdfa84e44de87c233434c7e69b8b5b8f4623c8aa444163425bae5cef842972fed66046c1c6ce65c866ad894d02e6e6dcaae7a962d9f2ef95757a09c486928e61f0f7aed90ad0a542b0d3dc5fe140dfa7626b9315c77e03b055f19cbacd21a866e46f06c00e0c7792b2a590a611439b510a9aaffcf1073bad23e712a9268b36888e3727033eee2ab4d869f54a843f93b36ef489fb177bf74b41a9644e5d2a0a417c6ac1c8869bc9b83273d453f878ed6fd96b82a5939903f7b64ecaf68ea16e255a7fb7cc0b6d8b5608a1c6b0ed3024cc62c2f0f9c5cfc7b431ae6e9d40815557aa1d010523f9e1960de77b2274cb6710d229d475c87ae900183206ba90cb5bbc8ec0df98341b82726c705e0308ca5dc08db4db609993a1046dfb43dfd8c760be506c0bed799bb2205fc29dc2e654dce731034a23b0aaf6da0199248702ee0523c159f41f4cbfff6c35ace4dd9ae834e44e09c76a0cbdda1d3f6a2c75ad71212daf9575ab5f09ca148718e667f29ddf18c8a330a86ace18a86e89454653902aa393c84c6b694f27d0d42e24e7ac9fe34733de5ec15f5066081ce912c62c1a804a2bb4dedcef7cc80274f6bb9e89e2fce91dc50d6a73c8aefb9872f1cf3524a92626a0b8f39bbf7bf7d96ca2f770fc04d7f457021c536a506a187a93b2245471ddbfb254a71bc4a0d72c8d639a31c7b1920087ffca05c24214157e2e7b28184e91989ef0b14f9b34c3dc3cc0ac64226b9e337095870cb0885737992e120346e630a416a9b217679ce5a778fb15779c136bcecca5efe79012013d77d90b4e99dd22c8f35bc77121716e160d05bd30d288ee8886390ee436f85bdc9029df888a3a3326d9d4ddba5cb5318b3274928829d662e96fea1d601f7a306251ed8c6cc4e5a3a7a98c35a3650482a0eee08f3b4c2da9b22947c96138f1505c2f081f8972d429f3871f32bef4aaa51aa6945df8e9c9760531ac6f627d17c1518202818a91ca304fb4037875c666060597976144fcbbc48a776a2c61beb9515fa8f3ae6d3a041d320a38a8ac75cb47bb9c866ee497fc3cd13299970c4b369c1c2ceb4220af082fbecdd8114492a8e4d713b5a73396fd224b36c1185bd5e20d683e6c8db35346c47ae7401988255da7cfffdced5801067d4d296688ee8fe424b4a8a69309ce257eefb9345ebfda3f6de46bb11ec94133e1f72cd7ac54934d6cf17b3440800e70b80ebc7c7bfc6fb0fc2c"), SER_NETWORK, PROTOCOL_VERSION);
753 ss >> output;
754
755 auto ctx = librustzcash_sapling_verification_ctx_init();
756
757 struct timeval tv_start;
758 timer_start(tv_start);
759
760 bool result = librustzcash_sapling_check_output(
761 ctx,
762 output.cv.begin(),
763 output.cm.begin(),
764 output.ephemeralKey.begin(),
765 output.zkproof.begin()
766 );
767
768 double t = timer_stop(tv_start);
769 librustzcash_sapling_verification_ctx_free(ctx);
770 if (!result) {
771 throw JSONRPCError(RPC_INTERNAL_ERROR, "librustzcash_sapling_check_output() should return true");
772 }
773 return timer_stop(tv_start);
774}
This page took 0.391198 seconds and 4 git commands to generate.