diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 64b905d70..4107ad6f8 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -1,5 +1,6 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers +// Copyright (c) 2019-2020 The Hush developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -130,12 +131,6 @@ static const CRPCConvertParam vRPCConvertParams[] = { "getaddressdeltas", 0}, { "getaddressutxos", 0}, { "getaddressmempool", 0}, - { "zcrawjoinsplit", 1 }, - { "zcrawjoinsplit", 2 }, - { "zcrawjoinsplit", 3 }, - { "zcrawjoinsplit", 4 }, - { "zcbenchmark", 1 }, - { "zcbenchmark", 2 }, { "getblocksubsidy", 0}, { "z_listaddresses", 0}, { "z_listreceivedbyaddress", 1}, diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index c052395a6..181de29bb 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -651,11 +651,6 @@ static const CRPCCommand vRPCCommands[] = { "wallet", "walletlock", &walletlock, true }, { "wallet", "walletpassphrasechange", &walletpassphrasechange, true }, { "wallet", "walletpassphrase", &walletpassphrase, true }, - { "wallet", "zcbenchmark", &zc_benchmark, true }, - { "wallet", "zcrawkeygen", &zc_raw_keygen, true }, - { "wallet", "zcrawjoinsplit", &zc_raw_joinsplit, true }, - { "wallet", "zcrawreceive", &zc_raw_receive, true }, - { "wallet", "zcsamplejoinsplit", &zc_sample_joinsplit, true }, { "wallet", "z_listreceivedbyaddress",&z_listreceivedbyaddress,false }, { "wallet", "z_getbalance", &z_getbalance, false }, { "wallet", "z_gettotalbalance", &z_gettotalbalance, false }, diff --git a/src/rpc/server.h b/src/rpc/server.h index 6ce27894a..1cd4e993d 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -1,6 +1,6 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers -// Copyright (c) 2019 The Hush Developers +// Copyright (c) 2019-2020 The Hush Developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -402,11 +402,6 @@ extern UniValue getnetworkinfo(const UniValue& params, bool fHelp, const CPubKey extern UniValue getdeprecationinfo(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue setmocktime(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue resendwallettransactions(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue zc_benchmark(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue zc_raw_keygen(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue zc_raw_receive(const UniValue& params, bool fHelp, const CPubKey& mypk); -extern UniValue zc_sample_joinsplit(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue jumblr_deposit(const UniValue& params, bool fHelp, const CPubKey& mypk); extern UniValue jumblr_secret(const UniValue& params, bool fHelp, const CPubKey& mypk); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 1fb365c34..79dab0c5b 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3840,475 +3840,6 @@ UniValue fundrawtransaction(const UniValue& params, bool fHelp, const CPubKey& m return result; } -UniValue zc_sample_joinsplit(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - if (fHelp) { - throw runtime_error( - "zcsamplejoinsplit\n" - "\n" - "Perform a joinsplit and return the JSDescription.\n" - ); - } - - LOCK(cs_main); - - uint256 joinSplitPubKey; - uint256 anchor = SproutMerkleTree().root(); - JSDescription samplejoinsplit(*pzcashParams, - joinSplitPubKey, - anchor, - {JSInput(), JSInput()}, - {JSOutput(), JSOutput()}, - 0, - 0); - - CDataStream ss(SER_NETWORK, SAPLING_TX_VERSION | (1 << 31)); - ss << samplejoinsplit; - - return HexStr(ss.begin(), ss.end()); -} - -UniValue zc_benchmark(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - if (!EnsureWalletIsAvailable(fHelp)) { - return NullUniValue; - } - - if (fHelp || params.size() < 2) { - throw runtime_error( - "zcbenchmark benchmarktype samplecount\n" - "\n" - "Runs a benchmark of the selected type samplecount times,\n" - "returning the running times of each sample.\n" - "\n" - "Output: [\n" - " {\n" - " \"runningtime\": runningtime\n" - " },\n" - " {\n" - " \"runningtime\": runningtime\n" - " }\n" - " ...\n" - "]\n" - ); - } - - LOCK(cs_main); - - std::string benchmarktype = params[0].get_str(); - int samplecount = params[1].get_int(); - - if (samplecount <= 0) { - throw JSONRPCError(RPC_TYPE_ERROR, "Invalid samplecount"); - } - - std::vector sample_times; - - JSDescription samplejoinsplit; - - if (benchmarktype == "verifyjoinsplit") { - CDataStream ss(ParseHexV(params[2].get_str(), "js"), SER_NETWORK, SAPLING_TX_VERSION | (1 << 31)); - ss >> samplejoinsplit; - } - - for (int i = 0; i < samplecount; i++) { - if (benchmarktype == "sleep") { - sample_times.push_back(benchmark_sleep()); - } else if (benchmarktype == "createjoinsplit") { - if (params.size() < 3) { - sample_times.push_back(benchmark_create_joinsplit()); - } else { - int nThreads = params[2].get_int(); - std::vector vals = benchmark_create_joinsplit_threaded(nThreads); - // Divide by nThreads^2 to get average seconds per JoinSplit because - // we are running one JoinSplit per thread. - sample_times.push_back(std::accumulate(vals.begin(), vals.end(), 0.0) / (nThreads*nThreads)); - } - } else if (benchmarktype == "verifyjoinsplit") { - sample_times.push_back(benchmark_verify_joinsplit(samplejoinsplit)); -#ifdef ENABLE_MINING - } else if (benchmarktype == "solveequihash") { - if (params.size() < 3) { - sample_times.push_back(benchmark_solve_equihash()); - } else { - int nThreads = params[2].get_int(); - std::vector vals = benchmark_solve_equihash_threaded(nThreads); - sample_times.insert(sample_times.end(), vals.begin(), vals.end()); - } -#endif - } else if (benchmarktype == "verifyequihash") { - sample_times.push_back(benchmark_verify_equihash()); - } else if (benchmarktype == "validatelargetx") { - // Number of inputs in the spending transaction that we will simulate - int nInputs = 11130; - if (params.size() >= 3) { - nInputs = params[2].get_int(); - } - sample_times.push_back(benchmark_large_tx(nInputs)); - } else if (benchmarktype == "trydecryptnotes") { - int nAddrs = params[2].get_int(); - sample_times.push_back(benchmark_try_decrypt_notes(nAddrs)); - } else if (benchmarktype == "incnotewitnesses") { - int nTxs = params[2].get_int(); - sample_times.push_back(benchmark_increment_note_witnesses(nTxs)); - } else if (benchmarktype == "connectblockslow") { - if (Params().NetworkIDString() != "regtest") { - throw JSONRPCError(RPC_TYPE_ERROR, "Benchmark must be run in regtest mode"); - } - sample_times.push_back(benchmark_connectblock_slow()); - } else if (benchmarktype == "sendtoaddress") { - if (Params().NetworkIDString() != "regtest") { - throw JSONRPCError(RPC_TYPE_ERROR, "Benchmark must be run in regtest mode"); - } - auto amount = AmountFromValue(params[2]); - sample_times.push_back(benchmark_sendtoaddress(amount)); - } else if (benchmarktype == "loadwallet") { - if (Params().NetworkIDString() != "regtest") { - throw JSONRPCError(RPC_TYPE_ERROR, "Benchmark must be run in regtest mode"); - } - sample_times.push_back(benchmark_loadwallet()); - } else if (benchmarktype == "listunspent") { - sample_times.push_back(benchmark_listunspent()); - } else if (benchmarktype == "createsaplingspend") { - sample_times.push_back(benchmark_create_sapling_spend()); - } else if (benchmarktype == "createsaplingoutput") { - sample_times.push_back(benchmark_create_sapling_output()); - } else if (benchmarktype == "verifysaplingspend") { - sample_times.push_back(benchmark_verify_sapling_spend()); - } else if (benchmarktype == "verifysaplingoutput") { - sample_times.push_back(benchmark_verify_sapling_output()); - } else { - throw JSONRPCError(RPC_TYPE_ERROR, "Invalid benchmarktype"); - } - } - - UniValue results(UniValue::VARR); - for (auto time : sample_times) { - UniValue result(UniValue::VOBJ); - result.push_back(Pair("runningtime", time)); - results.push_back(result); - } - - return results; -} - -UniValue zc_raw_receive(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - if (!EnsureWalletIsAvailable(fHelp)) { - return NullUniValue; - } - - if (fHelp || params.size() != 2) { - throw runtime_error( - "zcrawreceive zcsecretkey encryptednote\n" - "\n" - "DEPRECATED. Decrypts encryptednote and checks if the coin commitments\n" - "are in the blockchain as indicated by the \"exists\" result.\n" - "\n" - "Output: {\n" - " \"amount\": value,\n" - " \"note\": noteplaintext,\n" - " \"exists\": exists\n" - "}\n" - ); - } - - RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VSTR)); - - LOCK(cs_main); - - auto spendingkey = DecodeSpendingKey(params[0].get_str()); - if (!IsValidSpendingKey(spendingkey)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid spending key"); - } - if (boost::get(&spendingkey) == nullptr) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Only works with Sprout spending keys"); - } - SproutSpendingKey k = boost::get(spendingkey); - - uint256 epk; - unsigned char nonce; - ZCNoteEncryption::Ciphertext ct; - uint256 h_sig; - - { - CDataStream ssData(ParseHexV(params[1], "encrypted_note"), SER_NETWORK, PROTOCOL_VERSION); - try { - ssData >> nonce; - ssData >> epk; - ssData >> ct; - ssData >> h_sig; - } catch(const std::exception &) { - throw runtime_error( - "encrypted_note could not be decoded" - ); - } - } - - ZCNoteDecryption decryptor(k.receiving_key()); - - SproutNotePlaintext npt = SproutNotePlaintext::decrypt( - decryptor, - ct, - epk, - h_sig, - nonce - ); - SproutPaymentAddress payment_addr = k.address(); - SproutNote decrypted_note = npt.note(payment_addr); - - assert(pwalletMain != NULL); - std::vector> witnesses; - uint256 anchor; - uint256 commitment = decrypted_note.cm(); - pwalletMain->WitnessNoteCommitment( - {commitment}, - witnesses, - anchor - ); - - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << npt; - - UniValue result(UniValue::VOBJ); - result.push_back(Pair("amount", ValueFromAmount(decrypted_note.value()))); - result.push_back(Pair("note", HexStr(ss.begin(), ss.end()))); - result.push_back(Pair("exists", (bool) witnesses[0])); - return result; -} - - - -UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - if (!EnsureWalletIsAvailable(fHelp)) { - return NullUniValue; - } - - if (fHelp || params.size() != 5) { - throw runtime_error( - "zcrawjoinsplit rawtx inputs outputs vpub_old vpub_new\n" - " inputs: a JSON object mapping {note: zcsecretkey, ...}\n" - " outputs: a JSON object mapping {zcaddr: value, ...}\n" - "\n" - "DEPRECATED. Splices a joinsplit into rawtx. Inputs are unilaterally confidential.\n" - "Outputs are confidential between sender/receiver. The vpub_old and\n" - "vpub_new values are globally public and move transparent value into\n" - "or out of the confidential value store, respectively.\n" - "\n" - "Note: The caller is responsible for delivering the output enc1 and\n" - "enc2 to the appropriate recipients, as well as signing rawtxout and\n" - "ensuring it is mined. (A future RPC call will deliver the confidential\n" - "payments in-band on the blockchain.)\n" - "\n" - "Output: {\n" - " \"encryptednote1\": enc1,\n" - " \"encryptednote2\": enc2,\n" - " \"rawtxn\": rawtxout\n" - "}\n" - ); - } - - LOCK(cs_main); - - CTransaction tx; - if (!DecodeHexTx(tx, params[0].get_str())) - throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); - - UniValue inputs = params[1].get_obj(); - UniValue outputs = params[2].get_obj(); - - CAmount vpub_old(0); - CAmount vpub_new(0); - - if (params[3].get_real() != 0.0) - vpub_old = AmountFromValue(params[3]); - - if (params[4].get_real() != 0.0) - vpub_new = AmountFromValue(params[4]); - - std::vector vjsin; - std::vector vjsout; - std::vector notes; - std::vector keys; - std::vector commitments; - - for (const string& name_ : inputs.getKeys()) { - auto spendingkey = DecodeSpendingKey(inputs[name_].get_str()); - if (!IsValidSpendingKey(spendingkey)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid spending key"); - } - if (boost::get(&spendingkey) == nullptr) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Only works with Sprout spending keys"); - } - SproutSpendingKey k = boost::get(spendingkey); - - keys.push_back(k); - - SproutNotePlaintext npt; - - { - CDataStream ssData(ParseHexV(name_, "note"), SER_NETWORK, PROTOCOL_VERSION); - ssData >> npt; - } - - SproutPaymentAddress addr = k.address(); - SproutNote note = npt.note(addr); - notes.push_back(note); - commitments.push_back(note.cm()); - } - - uint256 anchor; - std::vector> witnesses; - pwalletMain->WitnessNoteCommitment(commitments, witnesses, anchor); - - assert(witnesses.size() == notes.size()); - assert(notes.size() == keys.size()); - - { - for (size_t i = 0; i < witnesses.size(); i++) { - if (!witnesses[i]) { - throw runtime_error( - "joinsplit input could not be found in tree" - ); - } - - vjsin.push_back(JSInput(*witnesses[i], notes[i], keys[i])); - } - } - - while (vjsin.size() < ZC_NUM_JS_INPUTS) { - vjsin.push_back(JSInput()); - } - - for (const string& name_ : outputs.getKeys()) { - auto addrTo = DecodePaymentAddress(name_); - if (!IsValidPaymentAddress(addrTo)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid recipient address."); - } - if (boost::get(&addrTo) == nullptr) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Only works with Sprout payment addresses"); - } - CAmount nAmount = AmountFromValue(outputs[name_]); - - vjsout.push_back(JSOutput(boost::get(addrTo), nAmount)); - } - - while (vjsout.size() < ZC_NUM_JS_OUTPUTS) { - vjsout.push_back(JSOutput()); - } - - // TODO - if (vjsout.size() != ZC_NUM_JS_INPUTS || vjsin.size() != ZC_NUM_JS_OUTPUTS) { - throw runtime_error("unsupported joinsplit input/output counts"); - } - - uint256 joinSplitPubKey; - unsigned char joinSplitPrivKey[crypto_sign_SECRETKEYBYTES]; - crypto_sign_keypair(joinSplitPubKey.begin(), joinSplitPrivKey); - - CMutableTransaction mtx(tx); - mtx.nVersion = 2; - mtx.joinSplitPubKey = joinSplitPubKey; - - JSDescription jsdesc(*pzcashParams, - joinSplitPubKey, - anchor, - {vjsin[0], vjsin[1]}, - {vjsout[0], vjsout[1]}, - vpub_old, - vpub_new); - - { - auto verifier = libzcash::ProofVerifier::Strict(); - assert(jsdesc.Verify(*pzcashParams, verifier, joinSplitPubKey)); - } - - mtx.vjoinsplit.push_back(jsdesc); - - // Empty output script. - CScript scriptCode; - CTransaction signTx(mtx); - auto consensusBranchId = CurrentEpochBranchId(chainActive.Height() + 1, Params().GetConsensus()); - uint256 dataToBeSigned = SignatureHash(scriptCode, signTx, NOT_AN_INPUT, SIGHASH_ALL, 0, consensusBranchId); - - // Add the signature - assert(crypto_sign_detached(&mtx.joinSplitSig[0], NULL, - dataToBeSigned.begin(), 32, - joinSplitPrivKey - ) == 0); - - // Sanity check - assert(crypto_sign_verify_detached(&mtx.joinSplitSig[0], - dataToBeSigned.begin(), 32, - mtx.joinSplitPubKey.begin() - ) == 0); - - CTransaction rawTx(mtx); - - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << rawTx; - - std::string encryptedNote1; - std::string encryptedNote2; - { - CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION); - ss2 << ((unsigned char) 0x00); - ss2 << jsdesc.ephemeralKey; - ss2 << jsdesc.ciphertexts[0]; - ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey); - - encryptedNote1 = HexStr(ss2.begin(), ss2.end()); - } - { - CDataStream ss2(SER_NETWORK, PROTOCOL_VERSION); - ss2 << ((unsigned char) 0x01); - ss2 << jsdesc.ephemeralKey; - ss2 << jsdesc.ciphertexts[1]; - ss2 << jsdesc.h_sig(*pzcashParams, joinSplitPubKey); - - encryptedNote2 = HexStr(ss2.begin(), ss2.end()); - } - - UniValue result(UniValue::VOBJ); - result.push_back(Pair("encryptednote1", encryptedNote1)); - result.push_back(Pair("encryptednote2", encryptedNote2)); - result.push_back(Pair("rawtxn", HexStr(ss.begin(), ss.end()))); - return result; -} - -UniValue zc_raw_keygen(const UniValue& params, bool fHelp, const CPubKey& mypk) -{ - if (!EnsureWalletIsAvailable(fHelp)) { - return NullUniValue; - } - - if (fHelp || params.size() != 0) { - throw runtime_error( - "zcrawkeygen\n" - "\n" - "DEPRECATED. Generate a zcaddr which can send and receive confidential values.\n" - "\n" - "Output: {\n" - " \"zcaddress\": zcaddr,\n" - " \"zcsecretkey\": zcsecretkey,\n" - " \"zcviewingkey\": zcviewingkey,\n" - "}\n" - ); - } - - auto k = SproutSpendingKey::random(); - auto addr = k.address(); - auto viewing_key = k.viewing_key(); - - UniValue result(UniValue::VOBJ); - result.push_back(Pair("zcaddress", EncodePaymentAddress(addr))); - result.push_back(Pair("zcsecretkey", EncodeSpendingKey(k))); - result.push_back(Pair("zcviewingkey", EncodeViewingKey(viewing_key))); - return result; -} - - UniValue z_getnewaddress(const UniValue& params, bool fHelp, const CPubKey& mypk) { if (!EnsureWalletIsAvailable(fHelp)) @@ -8776,11 +8307,6 @@ static const CRPCCommand commands[] = { "wallet", "walletlock", &walletlock, true }, { "wallet", "walletpassphrasechange", &walletpassphrasechange, true }, { "wallet", "walletpassphrase", &walletpassphrase, true }, - { "wallet", "zcbenchmark", &zc_benchmark, true }, - { "wallet", "zcrawkeygen", &zc_raw_keygen, true }, - { "wallet", "zcrawjoinsplit", &zc_raw_joinsplit, true }, - { "wallet", "zcrawreceive", &zc_raw_receive, true }, - { "wallet", "zcsamplejoinsplit", &zc_sample_joinsplit, true }, { "wallet", "z_listreceivedbyaddress", &z_listreceivedbyaddress, false }, { "wallet", "z_listunspent", &z_listunspent, false }, { "wallet", "z_getbalance", &z_getbalance, false },