From bef33bbc73bc64427ce9d084ffb2303dbcacf94c Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 24 Apr 2018 17:13:13 -0700 Subject: [PATCH 1/8] Refactoring: libzcash::Note is now a subclass of libzcash::BaseNote. --- src/zcash/Note.hpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/zcash/Note.hpp b/src/zcash/Note.hpp index 9b2676931..6261937d2 100644 --- a/src/zcash/Note.hpp +++ b/src/zcash/Note.hpp @@ -8,7 +8,12 @@ namespace libzcash { -class Note { +class BaseNote { +public: + virtual uint256 cm() const {}; +}; + +class Note : public BaseNote { public: uint256 a_pk; uint64_t value; @@ -20,7 +25,8 @@ public: Note(); - uint256 cm() const; + virtual uint256 cm() const override; + uint256 nullifier(const SpendingKey& a_sk) const; }; From b230fe68361fbafae518073aaf6ba45ca6b443bb Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 24 Apr 2018 21:20:01 -0700 Subject: [PATCH 2/8] Refactoring: Rename class libzcash::Note to libzcash::SproutNote. --- src/gtest/test_joinsplit.cpp | 18 +++++++++--------- src/gtest/test_transaction.cpp | 2 +- src/primitives/transaction.cpp | 2 +- src/test/coins_tests.cpp | 2 +- src/test/rpc_wallet_tests.cpp | 4 ++-- src/test/transaction_tests.cpp | 2 +- src/utiltest.cpp | 10 +++++----- src/utiltest.h | 4 ++-- .../asyncrpcoperation_mergetoaddress.cpp | 6 +++--- src/wallet/asyncrpcoperation_mergetoaddress.h | 4 ++-- src/wallet/asyncrpcoperation_sendmany.cpp | 6 +++--- src/wallet/asyncrpcoperation_sendmany.h | 4 ++-- src/wallet/gtest/test_wallet.cpp | 4 ++-- src/wallet/rpcdisclosure.cpp | 2 +- src/wallet/rpcwallet.cpp | 6 +++--- src/zcash/JoinSplit.cpp | 8 ++++---- src/zcash/JoinSplit.hpp | 8 ++++---- src/zcash/Note.cpp | 12 ++++++------ src/zcash/Note.hpp | 10 +++++----- src/zcash/circuit/gadget.tcc | 2 +- src/zcash/circuit/note.tcc | 6 +++--- 21 files changed, 61 insertions(+), 61 deletions(-) diff --git a/src/gtest/test_joinsplit.cpp b/src/gtest/test_joinsplit.cpp index 979d0d518..a9814e4ab 100644 --- a/src/gtest/test_joinsplit.cpp +++ b/src/gtest/test_joinsplit.cpp @@ -52,7 +52,7 @@ void test_full_api(ZCJoinSplit* js) JSOutput() // dummy output }; - boost::array output_notes; + boost::array output_notes; // Perform the proof proof = js->prove( @@ -127,7 +127,7 @@ void test_full_api(ZCJoinSplit* js) JSOutput() // dummy output }; - boost::array output_notes; + boost::array output_notes; // Perform the proof proof = js->prove( @@ -180,7 +180,7 @@ void invokeAPI( boost::array commitments; boost::array ciphertexts; - boost::array output_notes; + boost::array output_notes; ZCProof proof = js->prove( inputs, @@ -316,15 +316,15 @@ TEST(joinsplit, full_api_test) increment_note_witnesses(uint256(), witnesses, tree); SpendingKey sk = SpendingKey::random(); PaymentAddress addr = sk.address(); - Note note1(addr.a_pk, 100, random_uint256(), random_uint256()); + SproutNote note1(addr.a_pk, 100, random_uint256(), random_uint256()); increment_note_witnesses(note1.cm(), witnesses, tree); - Note note2(addr.a_pk, 100, random_uint256(), random_uint256()); + SproutNote note2(addr.a_pk, 100, random_uint256(), random_uint256()); increment_note_witnesses(note2.cm(), witnesses, tree); - Note note3(addr.a_pk, 2100000000000001, random_uint256(), random_uint256()); + SproutNote note3(addr.a_pk, 2100000000000001, random_uint256(), random_uint256()); increment_note_witnesses(note3.cm(), witnesses, tree); - Note note4(addr.a_pk, 1900000000000000, random_uint256(), random_uint256()); + SproutNote note4(addr.a_pk, 1900000000000000, random_uint256(), random_uint256()); increment_note_witnesses(note4.cm(), witnesses, tree); - Note note5(addr.a_pk, 1900000000000000, random_uint256(), random_uint256()); + SproutNote note5(addr.a_pk, 1900000000000000, random_uint256(), random_uint256()); increment_note_witnesses(note5.cm(), witnesses, tree); // Should work @@ -523,7 +523,7 @@ TEST(joinsplit, note_plaintexts) ZCNoteEncryption encryptor(h_sig); uint256 epk = encryptor.get_epk(); - Note note(a_pk, + SproutNote note(a_pk, 1945813, random_uint256(), random_uint256() diff --git a/src/gtest/test_transaction.cpp b/src/gtest/test_transaction.cpp index fb68fd35c..0f78fcb39 100644 --- a/src/gtest/test_transaction.cpp +++ b/src/gtest/test_transaction.cpp @@ -15,7 +15,7 @@ TEST(Transaction, JSDescriptionRandomized) { libzcash::SpendingKey k = libzcash::SpendingKey::random(); libzcash::PaymentAddress addr = k.address(); - libzcash::Note note(addr.a_pk, 100, uint256(), uint256()); + libzcash::SproutNote note(addr.a_pk, 100, uint256(), uint256()); // commitment from coin uint256 commitment = note.cm(); diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index 4f61b24ea..87b5600e5 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -20,7 +20,7 @@ JSDescription::JSDescription(ZCJoinSplit& params, uint256 *esk // payment disclosure ) : vpub_old(vpub_old), vpub_new(vpub_new), anchor(anchor) { - boost::array notes; + boost::array notes; proof = params.prove( inputs, diff --git a/src/test/coins_tests.cpp b/src/test/coins_tests.cpp index 383616ae0..125a2b03e 100644 --- a/src/test/coins_tests.cpp +++ b/src/test/coins_tests.cpp @@ -157,7 +157,7 @@ uint256 appendRandomCommitment(ZCIncrementalMerkleTree &tree) libzcash::SpendingKey k = libzcash::SpendingKey::random(); libzcash::PaymentAddress addr = k.address(); - libzcash::Note note(addr.a_pk, 0, uint256(), uint256()); + libzcash::SproutNote note(addr.a_pk, 0, uint256(), uint256()); auto cm = note.cm(); tree.append(cm); diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index ce2da60c1..d09764908 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -1178,7 +1178,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals) BOOST_CHECK( string(e.what()).find("anchor is null")!= string::npos); } - info.notes.push_back(Note()); + info.notes.push_back(SproutNote()); try { proxy.perform_joinsplit(info); } catch (const std::runtime_error & e) { @@ -1716,7 +1716,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_mergetoaddress_internals) BOOST_CHECK( string(e.what()).find("anchor is null")!= string::npos); } - info.notes.push_back(Note()); + info.notes.push_back(SproutNote()); try { proxy.perform_joinsplit(info); BOOST_FAIL("Should have caused an error"); diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 1b0b26ee7..af15adcce 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -345,7 +345,7 @@ BOOST_AUTO_TEST_CASE(test_basic_joinsplit_verification) libzcash::SpendingKey k = libzcash::SpendingKey::random(); libzcash::PaymentAddress addr = k.address(); - libzcash::Note note(addr.a_pk, 100, uint256(), uint256()); + libzcash::SproutNote note(addr.a_pk, 100, uint256(), uint256()); // commitment from coin uint256 commitment = note.cm(); diff --git a/src/utiltest.cpp b/src/utiltest.cpp index 4599cec3c..8245adf8e 100644 --- a/src/utiltest.cpp +++ b/src/utiltest.cpp @@ -38,7 +38,7 @@ CWalletTx GetValidReceive(ZCJoinSplit& params, libzcash::JSOutput(sk.address(), value) }; - boost::array output_notes; + boost::array output_notes; // Prepare JoinSplits uint256 rt; @@ -63,7 +63,7 @@ CWalletTx GetValidReceive(ZCJoinSplit& params, return wtx; } -libzcash::Note GetNote(ZCJoinSplit& params, +libzcash::SproutNote GetNote(ZCJoinSplit& params, const libzcash::SpendingKey& sk, const CTransaction& tx, size_t js, size_t n) { ZCNoteDecryption decryptor {sk.receiving_key()}; @@ -79,7 +79,7 @@ libzcash::Note GetNote(ZCJoinSplit& params, CWalletTx GetValidSpend(ZCJoinSplit& params, const libzcash::SpendingKey& sk, - const libzcash::Note& note, CAmount value) { + const libzcash::SproutNote& note, CAmount value) { CMutableTransaction mtx; mtx.vout.resize(2); mtx.vout[0].nValue = value; @@ -105,7 +105,7 @@ CWalletTx GetValidSpend(ZCJoinSplit& params, } else if (note.value < value) { libzcash::SpendingKey dummykey = libzcash::SpendingKey::random(); libzcash::PaymentAddress dummyaddr = dummykey.address(); - libzcash::Note dummynote(dummyaddr.a_pk, (value - note.value), uint256(), uint256()); + libzcash::SproutNote dummynote(dummyaddr.a_pk, (value - note.value), uint256(), uint256()); tree.append(dummynote.cm()); dummyin = libzcash::JSInput(tree.witness(), dummynote, dummykey); } @@ -123,7 +123,7 @@ CWalletTx GetValidSpend(ZCJoinSplit& params, libzcash::JSOutput() // dummy output }; - boost::array output_notes; + boost::array output_notes; // Prepare JoinSplits uint256 rt = tree.root(); diff --git a/src/utiltest.h b/src/utiltest.h index 8cfa60d06..d9da2a1de 100644 --- a/src/utiltest.h +++ b/src/utiltest.h @@ -10,9 +10,9 @@ CWalletTx GetValidReceive(ZCJoinSplit& params, const libzcash::SpendingKey& sk, CAmount value, bool randomInputs); -libzcash::Note GetNote(ZCJoinSplit& params, +libzcash::SproutNote GetNote(ZCJoinSplit& params, const libzcash::SpendingKey& sk, const CTransaction& tx, size_t js, size_t n); CWalletTx GetValidSpend(ZCJoinSplit& params, const libzcash::SpendingKey& sk, - const libzcash::Note& note, CAmount value); + const libzcash::SproutNote& note, CAmount value); diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.cpp b/src/wallet/asyncrpcoperation_mergetoaddress.cpp index d029c79c5..6e6d3c7d0 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.cpp +++ b/src/wallet/asyncrpcoperation_mergetoaddress.cpp @@ -462,7 +462,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() hSig, (unsigned char)changeOutputIndex); - Note note = plaintext.note(changeAddress); + SproutNote note = plaintext.note(changeAddress); info.notes.push_back(note); info.zkeys.push_back(changeKey); @@ -481,7 +481,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() // // Consume spendable non-change notes // - std::vector vInputNotes; + std::vector vInputNotes; std::vector vInputZKeys; std::vector vOutPoints; std::vector> vInputWitnesses; @@ -490,7 +490,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() while (numInputsNeeded++ < ZC_NUM_JS_INPUTS && zInputsDeque.size() > 0) { MergeToAddressInputNote t = zInputsDeque.front(); JSOutPoint jso = std::get<0>(t); - Note note = std::get<1>(t); + SproutNote note = std::get<1>(t); CAmount noteFunds = std::get<2>(t); SpendingKey zkey = std::get<3>(t); zInputsDeque.pop_front(); diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.h b/src/wallet/asyncrpcoperation_mergetoaddress.h index 34548a5ba..9b291cdf6 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.h +++ b/src/wallet/asyncrpcoperation_mergetoaddress.h @@ -28,7 +28,7 @@ using namespace libzcash; typedef std::tuple MergeToAddressInputUTXO; // Input JSOP is a tuple of JSOutpoint, note, amount, spending key -typedef std::tuple MergeToAddressInputNote; +typedef std::tuple MergeToAddressInputNote; // A recipient is a tuple of address, memo (optional if zaddr) typedef std::tuple MergeToAddressRecipient; @@ -37,7 +37,7 @@ typedef std::tuple MergeToAddressRecipient; struct MergeToAddressJSInfo { std::vector vjsin; std::vector vjsout; - std::vector notes; + std::vector notes; std::vector zkeys; CAmount vpub_old = 0; CAmount vpub_new = 0; diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index 35c5fcfcb..de6da102f 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -578,7 +578,7 @@ bool AsyncRPCOperation_sendmany::main_impl() { hSig, (unsigned char) changeOutputIndex); - Note note = plaintext.note(frompaymentaddress_); + SproutNote note = plaintext.note(frompaymentaddress_); info.notes.push_back(note); jsInputValue += plaintext.value; @@ -597,7 +597,7 @@ bool AsyncRPCOperation_sendmany::main_impl() { // // Consume spendable non-change notes // - std::vector vInputNotes; + std::vector vInputNotes; std::vector vOutPoints; std::vector> vInputWitnesses; uint256 inputAnchor; @@ -605,7 +605,7 @@ bool AsyncRPCOperation_sendmany::main_impl() { while (numInputsNeeded++ < ZC_NUM_JS_INPUTS && zInputsDeque.size() > 0) { SendManyInputJSOP t = zInputsDeque.front(); JSOutPoint jso = std::get<0>(t); - Note note = std::get<1>(t); + SproutNote note = std::get<1>(t); CAmount noteFunds = std::get<2>(t); zInputsDeque.pop_front(); diff --git a/src/wallet/asyncrpcoperation_sendmany.h b/src/wallet/asyncrpcoperation_sendmany.h index 113f11f49..97c4533f1 100644 --- a/src/wallet/asyncrpcoperation_sendmany.h +++ b/src/wallet/asyncrpcoperation_sendmany.h @@ -31,14 +31,14 @@ typedef std::tuple SendManyRecipient; typedef std::tuple SendManyInputUTXO; // Input JSOP is a tuple of JSOutpoint, note and amount -typedef std::tuple SendManyInputJSOP; +typedef std::tuple SendManyInputJSOP; // Package of info which is passed to perform_joinsplit methods. struct AsyncJoinSplitInfo { std::vector vjsin; std::vector vjsout; - std::vector notes; + std::vector notes; CAmount vpub_old = 0; CAmount vpub_new = 0; }; diff --git a/src/wallet/gtest/test_wallet.cpp b/src/wallet/gtest/test_wallet.cpp index e976e4ae4..78984abed 100644 --- a/src/wallet/gtest/test_wallet.cpp +++ b/src/wallet/gtest/test_wallet.cpp @@ -72,13 +72,13 @@ CWalletTx GetValidReceive(const libzcash::SpendingKey& sk, CAmount value, bool r return GetValidReceive(*params, sk, value, randomInputs); } -libzcash::Note GetNote(const libzcash::SpendingKey& sk, +libzcash::SproutNote GetNote(const libzcash::SpendingKey& sk, const CTransaction& tx, size_t js, size_t n) { return GetNote(*params, sk, tx, js, n); } CWalletTx GetValidSpend(const libzcash::SpendingKey& sk, - const libzcash::Note& note, CAmount value) { + const libzcash::SproutNote& note, CAmount value) { return GetValidSpend(*params, sk, note, value); } diff --git a/src/wallet/rpcdisclosure.cpp b/src/wallet/rpcdisclosure.cpp index 539cf4b2a..e1c20ab0b 100644 --- a/src/wallet/rpcdisclosure.cpp +++ b/src/wallet/rpcdisclosure.cpp @@ -283,7 +283,7 @@ UniValue z_validatepaymentdisclosure(const UniValue& params, bool fHelp) // Check the blockchain commitment matches decrypted note commitment uint256 cm_blockchain = jsdesc.commitments[pd.payload.n]; - Note note = npt.note(zaddr); + SproutNote note = npt.note(zaddr); uint256 cm_decrypted = note.cm(); bool cm_match = (cm_decrypted == cm_blockchain); o.push_back(Pair("commitmentMatch", cm_match)); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index e86f0e2de..3b237a7ce 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2817,7 +2817,7 @@ UniValue zc_raw_receive(const UniValue& params, bool fHelp) nonce ); PaymentAddress payment_addr = k.address(); - Note decrypted_note = npt.note(payment_addr); + SproutNote decrypted_note = npt.note(payment_addr); assert(pwalletMain != NULL); std::vector> witnesses; @@ -2891,7 +2891,7 @@ UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp) std::vector vjsin; std::vector vjsout; - std::vector notes; + std::vector notes; std::vector keys; std::vector commitments; @@ -2909,7 +2909,7 @@ UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp) } PaymentAddress addr = k.address(); - Note note = npt.note(addr); + SproutNote note = npt.note(addr); notes.push_back(note); commitments.push_back(note.cm()); } diff --git a/src/zcash/JoinSplit.cpp b/src/zcash/JoinSplit.cpp index 2685569d3..2d7ed1153 100644 --- a/src/zcash/JoinSplit.cpp +++ b/src/zcash/JoinSplit.cpp @@ -139,7 +139,7 @@ public: ZCProof prove( const boost::array& inputs, const boost::array& outputs, - boost::array& out_notes, + boost::array& out_notes, boost::array& out_ciphertexts, uint256& out_ephemeralKey, const uint256& pubKeyHash, @@ -364,10 +364,10 @@ uint256 JoinSplit::h_sig( return output; } -Note JSOutput::note(const uint252& phi, const uint256& r, size_t i, const uint256& h_sig) const { +SproutNote JSOutput::note(const uint252& phi, const uint256& r, size_t i, const uint256& h_sig) const { uint256 rho = PRF_rho(phi, i, h_sig); - return Note(addr.a_pk, value, rho, r); + return SproutNote(addr.a_pk, value, rho, r); } JSOutput::JSOutput() : addr(uint256(), uint256()), value(0) { @@ -377,7 +377,7 @@ JSOutput::JSOutput() : addr(uint256(), uint256()), value(0) { JSInput::JSInput() : witness(ZCIncrementalMerkleTree().witness()), key(SpendingKey::random()) { - note = Note(key.address().a_pk, 0, random_uint256(), random_uint256()); + note = SproutNote(key.address().a_pk, 0, random_uint256(), random_uint256()); ZCIncrementalMerkleTree dummy_tree; dummy_tree.append(note.cm()); witness = dummy_tree.witness(); diff --git a/src/zcash/JoinSplit.hpp b/src/zcash/JoinSplit.hpp index 6a2d4e1f2..28ca98e97 100644 --- a/src/zcash/JoinSplit.hpp +++ b/src/zcash/JoinSplit.hpp @@ -18,12 +18,12 @@ namespace libzcash { class JSInput { public: ZCIncrementalWitness witness; - Note note; + SproutNote note; SpendingKey key; JSInput(); JSInput(ZCIncrementalWitness witness, - Note note, + SproutNote note, SpendingKey key) : witness(witness), note(note), key(key) { } uint256 nullifier() const { @@ -40,7 +40,7 @@ public: JSOutput(); JSOutput(PaymentAddress addr, uint64_t value) : addr(addr), value(value) { } - Note note(const uint252& phi, const uint256& r, size_t i, const uint256& h_sig) const; + SproutNote note(const uint252& phi, const uint256& r, size_t i, const uint256& h_sig) const; }; template @@ -62,7 +62,7 @@ public: virtual ZCProof prove( const boost::array& inputs, const boost::array& outputs, - boost::array& out_notes, + boost::array& out_notes, boost::array& out_ciphertexts, uint256& out_ephemeralKey, const uint256& pubKeyHash, diff --git a/src/zcash/Note.cpp b/src/zcash/Note.cpp index afef81458..c16a225ff 100644 --- a/src/zcash/Note.cpp +++ b/src/zcash/Note.cpp @@ -9,14 +9,14 @@ namespace libzcash { -Note::Note() { +SproutNote::SproutNote() { a_pk = random_uint256(); rho = random_uint256(); r = random_uint256(); value = 0; } -uint256 Note::cm() const { +uint256 SproutNote::cm() const { unsigned char discriminant = 0xb0; CSHA256 hasher; @@ -35,12 +35,12 @@ uint256 Note::cm() const { return result; } -uint256 Note::nullifier(const SpendingKey& a_sk) const { +uint256 SproutNote::nullifier(const SpendingKey& a_sk) const { return PRF_nf(a_sk, rho); } NotePlaintext::NotePlaintext( - const Note& note, + const SproutNote& note, boost::array memo) : memo(memo) { value = note.value; @@ -48,9 +48,9 @@ NotePlaintext::NotePlaintext( r = note.r; } -Note NotePlaintext::note(const PaymentAddress& addr) const +SproutNote NotePlaintext::note(const PaymentAddress& addr) const { - return Note(addr.a_pk, value, rho, r); + return SproutNote(addr.a_pk, value, rho, r); } NotePlaintext NotePlaintext::decrypt(const ZCNoteDecryption& decryptor, diff --git a/src/zcash/Note.hpp b/src/zcash/Note.hpp index 6261937d2..623fdbb6c 100644 --- a/src/zcash/Note.hpp +++ b/src/zcash/Note.hpp @@ -13,17 +13,17 @@ public: virtual uint256 cm() const {}; }; -class Note : public BaseNote { +class SproutNote : public BaseNote { public: uint256 a_pk; uint64_t value; uint256 rho; uint256 r; - Note(uint256 a_pk, uint64_t value, uint256 rho, uint256 r) + SproutNote(uint256 a_pk, uint64_t value, uint256 rho, uint256 r) : a_pk(a_pk), value(value), rho(rho), r(r) {} - Note(); + SproutNote(); virtual uint256 cm() const override; @@ -39,9 +39,9 @@ public: NotePlaintext() {} - NotePlaintext(const Note& note, boost::array memo); + NotePlaintext(const SproutNote& note, boost::array memo); - Note note(const PaymentAddress& addr) const; + SproutNote note(const PaymentAddress& addr) const; ADD_SERIALIZE_METHODS; diff --git a/src/zcash/circuit/gadget.tcc b/src/zcash/circuit/gadget.tcc index 141ec834e..d13c05962 100644 --- a/src/zcash/circuit/gadget.tcc +++ b/src/zcash/circuit/gadget.tcc @@ -191,7 +191,7 @@ public: const uint256& rt, const uint256& h_sig, const boost::array& inputs, - const boost::array& outputs, + const boost::array& outputs, uint64_t vpub_old, uint64_t vpub_new ) { diff --git a/src/zcash/circuit/note.tcc b/src/zcash/circuit/note.tcc index f472cb151..69526ec71 100644 --- a/src/zcash/circuit/note.tcc +++ b/src/zcash/circuit/note.tcc @@ -21,7 +21,7 @@ public: r->generate_r1cs_constraints(); } - void generate_r1cs_witness(const Note& note) { + void generate_r1cs_witness(const SproutNote& note) { r->bits.fill_with_bits(this->pb, uint256_to_bool_vector(note.r)); value.fill_with_bits(this->pb, uint64_to_bool_vector(note.value)); } @@ -119,7 +119,7 @@ public: void generate_r1cs_witness( const MerklePath& path, const SpendingKey& key, - const Note& note + const SproutNote& note ) { note_gadget::generate_r1cs_witness(note); @@ -222,7 +222,7 @@ public: commit_to_outputs->generate_r1cs_constraints(); } - void generate_r1cs_witness(const Note& note) { + void generate_r1cs_witness(const SproutNote& note) { note_gadget::generate_r1cs_witness(note); prevent_faerie_gold->generate_r1cs_witness(); From 5d99e3e92f8c54b5e2d8c428fdc6d528fdadbf05 Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 25 Apr 2018 13:32:13 -0700 Subject: [PATCH 3/8] Refactoring: SproutNote member variable value moved to BaseNote. All notes have a value, so the member variable has been moved to the base class, and direct member access has been replaced with a getter. --- src/gtest/test_joinsplit.cpp | 4 ++-- src/utiltest.cpp | 8 ++++---- src/wallet/asyncrpcoperation_mergetoaddress.cpp | 2 +- src/wallet/asyncrpcoperation_sendmany.cpp | 2 +- src/wallet/asyncrpcoperation_shieldcoinbase.cpp | 2 +- src/wallet/rpcwallet.cpp | 2 +- src/zcash/JoinSplit.cpp | 6 +++--- src/zcash/Note.cpp | 5 ++--- src/zcash/Note.hpp | 8 ++++++-- src/zcash/circuit/gadget.tcc | 2 +- src/zcash/circuit/note.tcc | 4 ++-- 11 files changed, 24 insertions(+), 21 deletions(-) diff --git a/src/gtest/test_joinsplit.cpp b/src/gtest/test_joinsplit.cpp index a9814e4ab..d238e4b94 100644 --- a/src/gtest/test_joinsplit.cpp +++ b/src/gtest/test_joinsplit.cpp @@ -101,7 +101,7 @@ void test_full_api(ZCJoinSplit* js) auto decrypted_note = note_pt.note(recipient_addr); - ASSERT_TRUE(decrypted_note.value == 10); + ASSERT_TRUE(decrypted_note.value() == 10); // Insert the commitments from the last tx into the tree tree.append(commitments[0]); @@ -543,7 +543,7 @@ TEST(joinsplit, note_plaintexts) ASSERT_TRUE(decrypted_note.a_pk == note.a_pk); ASSERT_TRUE(decrypted_note.rho == note.rho); ASSERT_TRUE(decrypted_note.r == note.r); - ASSERT_TRUE(decrypted_note.value == note.value); + ASSERT_TRUE(decrypted_note.value() == note.value()); ASSERT_TRUE(decrypted.memo == note_pt.memo); } diff --git a/src/utiltest.cpp b/src/utiltest.cpp index 8245adf8e..60af4f7dd 100644 --- a/src/utiltest.cpp +++ b/src/utiltest.cpp @@ -98,14 +98,14 @@ CWalletTx GetValidSpend(ZCJoinSplit& params, libzcash::JSInput dummyin; { - if (note.value > value) { + if (note.value() > value) { libzcash::SpendingKey dummykey = libzcash::SpendingKey::random(); libzcash::PaymentAddress dummyaddr = dummykey.address(); - dummyout = libzcash::JSOutput(dummyaddr, note.value - value); - } else if (note.value < value) { + dummyout = libzcash::JSOutput(dummyaddr, note.value() - value); + } else if (note.value() < value) { libzcash::SpendingKey dummykey = libzcash::SpendingKey::random(); libzcash::PaymentAddress dummyaddr = dummykey.address(); - libzcash::SproutNote dummynote(dummyaddr.a_pk, (value - note.value), uint256(), uint256()); + libzcash::SproutNote dummynote(dummyaddr.a_pk, (value - note.value()), uint256(), uint256()); tree.append(dummynote.cm()); dummyin = libzcash::JSInput(tree.witness(), dummynote, dummykey); } diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.cpp b/src/wallet/asyncrpcoperation_mergetoaddress.cpp index 6e6d3c7d0..b2d9eb4ab 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.cpp +++ b/src/wallet/asyncrpcoperation_mergetoaddress.cpp @@ -753,7 +753,7 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit( getId(), tx_.vjoinsplit.size(), FormatMoney(info.vpub_old), FormatMoney(info.vpub_new), - FormatMoney(info.vjsin[0].note.value), FormatMoney(info.vjsin[1].note.value), + FormatMoney(info.vjsin[0].note.value()), FormatMoney(info.vjsin[1].note.value()), FormatMoney(info.vjsout[0].value), FormatMoney(info.vjsout[1].value)); // Generate the proof, this can take over a minute. diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index de6da102f..42805b5e6 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -968,7 +968,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit( getId(), tx_.vjoinsplit.size(), FormatMoney(info.vpub_old), FormatMoney(info.vpub_new), - FormatMoney(info.vjsin[0].note.value), FormatMoney(info.vjsin[1].note.value), + FormatMoney(info.vjsin[0].note.value()), FormatMoney(info.vjsin[1].note.value()), FormatMoney(info.vjsout[0].value), FormatMoney(info.vjsout[1].value) ); diff --git a/src/wallet/asyncrpcoperation_shieldcoinbase.cpp b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp index b7ace4dd5..dcadc6a78 100644 --- a/src/wallet/asyncrpcoperation_shieldcoinbase.cpp +++ b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp @@ -341,7 +341,7 @@ UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInf getId(), tx_.vjoinsplit.size(), FormatMoney(info.vpub_old), FormatMoney(info.vpub_new), - FormatMoney(info.vjsin[0].note.value), FormatMoney(info.vjsin[1].note.value), + FormatMoney(info.vjsin[0].note.value()), FormatMoney(info.vjsin[1].note.value()), FormatMoney(info.vjsout[0].value), FormatMoney(info.vjsout[1].value) ); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 3b237a7ce..0463c07e5 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2833,7 +2833,7 @@ UniValue zc_raw_receive(const UniValue& params, bool fHelp) ss << npt; UniValue result(UniValue::VOBJ); - result.push_back(Pair("amount", ValueFromAmount(decrypted_note.value))); + 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; diff --git a/src/zcash/JoinSplit.cpp b/src/zcash/JoinSplit.cpp index 2d7ed1153..5751d1c6d 100644 --- a/src/zcash/JoinSplit.cpp +++ b/src/zcash/JoinSplit.cpp @@ -168,7 +168,7 @@ public: // Sanity checks of input { // If note has nonzero value - if (inputs[i].note.value != 0) { + if (inputs[i].note.value() != 0) { // The witness root must equal the input root. if (inputs[i].witness.root() != rt) { throw std::invalid_argument("joinsplit not anchored to the correct root"); @@ -186,11 +186,11 @@ public: } // Balance must be sensical - if (inputs[i].note.value > MAX_MONEY) { + if (inputs[i].note.value() > MAX_MONEY) { throw std::invalid_argument("nonsensical input note value"); } - lhs_value += inputs[i].note.value; + lhs_value += inputs[i].note.value(); if (lhs_value > MAX_MONEY) { throw std::invalid_argument("nonsensical left hand size of joinsplit balance"); diff --git a/src/zcash/Note.cpp b/src/zcash/Note.cpp index c16a225ff..5b1ccf51d 100644 --- a/src/zcash/Note.cpp +++ b/src/zcash/Note.cpp @@ -13,7 +13,6 @@ SproutNote::SproutNote() { a_pk = random_uint256(); rho = random_uint256(); r = random_uint256(); - value = 0; } uint256 SproutNote::cm() const { @@ -23,7 +22,7 @@ uint256 SproutNote::cm() const { hasher.Write(&discriminant, 1); hasher.Write(a_pk.begin(), 32); - auto value_vec = convertIntToVectorLE(value); + auto value_vec = convertIntToVectorLE(value_); hasher.Write(&value_vec[0], value_vec.size()); hasher.Write(rho.begin(), 32); @@ -43,7 +42,7 @@ NotePlaintext::NotePlaintext( const SproutNote& note, boost::array memo) : memo(memo) { - value = note.value; + value = note.value(); rho = note.rho; r = note.r; } diff --git a/src/zcash/Note.hpp b/src/zcash/Note.hpp index 623fdbb6c..f4cd4e0f6 100644 --- a/src/zcash/Note.hpp +++ b/src/zcash/Note.hpp @@ -9,19 +9,23 @@ namespace libzcash { class BaseNote { +protected: + uint64_t value_ = 0; public: + BaseNote() {} + BaseNote(uint64_t value) : value_(value) {}; virtual uint256 cm() const {}; + inline uint64_t value() const { return value_; }; }; class SproutNote : public BaseNote { public: uint256 a_pk; - uint64_t value; uint256 rho; uint256 r; SproutNote(uint256 a_pk, uint64_t value, uint256 rho, uint256 r) - : a_pk(a_pk), value(value), rho(rho), r(r) {} + : BaseNote(value), a_pk(a_pk), rho(rho), r(r) {} SproutNote(); diff --git a/src/zcash/circuit/gadget.tcc b/src/zcash/circuit/gadget.tcc index d13c05962..6d057459f 100644 --- a/src/zcash/circuit/gadget.tcc +++ b/src/zcash/circuit/gadget.tcc @@ -222,7 +222,7 @@ public: // Witness total_uint64 bits uint64_t left_side_acc = vpub_old; for (size_t i = 0; i < NumInputs; i++) { - left_side_acc += inputs[i].note.value; + left_side_acc += inputs[i].note.value(); } zk_total_uint64.fill_with_bits( diff --git a/src/zcash/circuit/note.tcc b/src/zcash/circuit/note.tcc index 69526ec71..d1534ec4b 100644 --- a/src/zcash/circuit/note.tcc +++ b/src/zcash/circuit/note.tcc @@ -23,7 +23,7 @@ public: void generate_r1cs_witness(const SproutNote& note) { r->bits.fill_with_bits(this->pb, uint256_to_bool_vector(note.r)); - value.fill_with_bits(this->pb, uint64_to_bool_vector(note.value)); + value.fill_with_bits(this->pb, uint64_to_bool_vector(note.value())); } }; @@ -158,7 +158,7 @@ public: ); // Set enforce flag for nonzero input value - this->pb.val(value_enforce) = (note.value != 0) ? FieldT::one() : FieldT::zero(); + this->pb.val(value_enforce) = (note.value() != 0) ? FieldT::one() : FieldT::zero(); // Witness merkle tree authentication path witness_input->generate_r1cs_witness(path); From 5f4fa1a9540603262fcc0cff92c726446a500523 Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 25 Apr 2018 19:03:43 -0700 Subject: [PATCH 4/8] Add virtual destructor to SproutNote and BaseNote Also add test to make sure default copy constructors are okay. --- src/gtest/test_joinsplit.cpp | 22 ++++++++++++++++++++++ src/zcash/Note.hpp | 4 ++++ 2 files changed, 26 insertions(+) diff --git a/src/gtest/test_joinsplit.cpp b/src/gtest/test_joinsplit.cpp index d238e4b94..196c61e7f 100644 --- a/src/gtest/test_joinsplit.cpp +++ b/src/gtest/test_joinsplit.cpp @@ -547,3 +547,25 @@ TEST(joinsplit, note_plaintexts) ASSERT_TRUE(decrypted.memo == note_pt.memo); } + +TEST(joinsplit, note_class) +{ + uint252 a_sk = uint252(uint256S("f6da8716682d600f74fc16bd0187faad6a26b4aa4c24d5c055b216d94516840e")); + uint256 a_pk = PRF_addr_a_pk(a_sk); + uint256 sk_enc = ZCNoteEncryption::generate_privkey(a_sk); + uint256 pk_enc = ZCNoteEncryption::generate_pubkey(sk_enc); + PaymentAddress addr_pk(a_pk, pk_enc); + + SproutNote note(a_pk, + 1945813, + random_uint256(), + random_uint256()); + + SproutNote clone = note; + ASSERT_NE(¬e, &clone); + ASSERT_EQ(note.value(), clone.value()); + ASSERT_EQ(note.cm(), clone.cm()); + ASSERT_EQ(note.rho, clone.rho); + ASSERT_EQ(note.r, clone.r); + ASSERT_EQ(note.a_pk, clone.a_pk); +} diff --git a/src/zcash/Note.hpp b/src/zcash/Note.hpp index f4cd4e0f6..586b172b7 100644 --- a/src/zcash/Note.hpp +++ b/src/zcash/Note.hpp @@ -14,6 +14,8 @@ protected: public: BaseNote() {} BaseNote(uint64_t value) : value_(value) {}; + virtual ~BaseNote() {}; + virtual uint256 cm() const {}; inline uint64_t value() const { return value_; }; }; @@ -29,6 +31,8 @@ public: SproutNote(); + virtual ~SproutNote() {}; + virtual uint256 cm() const override; uint256 nullifier(const SpendingKey& a_sk) const; From 9354f8e568d2af0037a9fef4ca2b97ab77bd3ecb Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 25 Apr 2018 22:55:30 -0700 Subject: [PATCH 5/8] Remove unused SproutNote variables. --- src/utiltest.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/utiltest.cpp b/src/utiltest.cpp index 60af4f7dd..a980daea6 100644 --- a/src/utiltest.cpp +++ b/src/utiltest.cpp @@ -38,8 +38,6 @@ CWalletTx GetValidReceive(ZCJoinSplit& params, libzcash::JSOutput(sk.address(), value) }; - boost::array output_notes; - // Prepare JoinSplits uint256 rt; JSDescription jsdesc {params, mtx.joinSplitPubKey, rt, @@ -123,8 +121,6 @@ CWalletTx GetValidSpend(ZCJoinSplit& params, libzcash::JSOutput() // dummy output }; - boost::array output_notes; - // Prepare JoinSplits uint256 rt = tree.root(); JSDescription jsdesc {params, mtx.joinSplitPubKey, rt, From 5020a93631c719c9dccdfa15eed2f80876d4d413 Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 25 Apr 2018 23:08:36 -0700 Subject: [PATCH 6/8] Refactoring: rename NotePlaintext --> SproutNotePlaintext Also renames: CNotePlaintextEntry --> CSproutNotePlaintextEntry CUnspentNotePlaintextEntry --> CUnspentSproutNotePlaintextEntry --- src/gtest/test_joinsplit.cpp | 6 +++--- src/utiltest.cpp | 2 +- .../asyncrpcoperation_mergetoaddress.cpp | 2 +- src/wallet/asyncrpcoperation_sendmany.cpp | 6 +++--- src/wallet/gtest/test_wallet.cpp | 2 +- src/wallet/rpcdisclosure.cpp | 2 +- src/wallet/rpcwallet.cpp | 18 +++++++++--------- src/wallet/wallet.cpp | 16 ++++++++-------- src/wallet/wallet.h | 14 +++++++------- src/zcash/JoinSplit.cpp | 2 +- src/zcash/Note.cpp | 10 +++++----- src/zcash/Note.hpp | 10 +++++----- 12 files changed, 45 insertions(+), 45 deletions(-) diff --git a/src/gtest/test_joinsplit.cpp b/src/gtest/test_joinsplit.cpp index 196c61e7f..5730b988d 100644 --- a/src/gtest/test_joinsplit.cpp +++ b/src/gtest/test_joinsplit.cpp @@ -91,7 +91,7 @@ void test_full_api(ZCJoinSplit* js) auto h_sig = js->h_sig(randomSeed, nullifiers, pubKeyHash); ZCNoteDecryption decryptor(recipient_key.receiving_key()); - auto note_pt = NotePlaintext::decrypt( + auto note_pt = SproutNotePlaintext::decrypt( decryptor, ciphertexts[0], ephemeralKey, @@ -531,13 +531,13 @@ TEST(joinsplit, note_plaintexts) boost::array memo; - NotePlaintext note_pt(note, memo); + SproutNotePlaintext note_pt(note, memo); ZCNoteEncryption::Ciphertext ct = note_pt.encrypt(encryptor, pk_enc); ZCNoteDecryption decryptor(sk_enc); - auto decrypted = NotePlaintext::decrypt(decryptor, ct, epk, h_sig, 0); + auto decrypted = SproutNotePlaintext::decrypt(decryptor, ct, epk, h_sig, 0); auto decrypted_note = decrypted.note(addr_pk); ASSERT_TRUE(decrypted_note.a_pk == note.a_pk); diff --git a/src/utiltest.cpp b/src/utiltest.cpp index a980daea6..e1b7b8275 100644 --- a/src/utiltest.cpp +++ b/src/utiltest.cpp @@ -66,7 +66,7 @@ libzcash::SproutNote GetNote(ZCJoinSplit& params, const CTransaction& tx, size_t js, size_t n) { ZCNoteDecryption decryptor {sk.receiving_key()}; auto hSig = tx.vjoinsplit[js].h_sig(params, tx.joinSplitPubKey); - auto note_pt = libzcash::NotePlaintext::decrypt( + auto note_pt = libzcash::SproutNotePlaintext::decrypt( decryptor, tx.vjoinsplit[js].ciphertexts[n], tx.vjoinsplit[js].ephemeralKey, diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.cpp b/src/wallet/asyncrpcoperation_mergetoaddress.cpp index b2d9eb4ab..49b01c394 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.cpp +++ b/src/wallet/asyncrpcoperation_mergetoaddress.cpp @@ -455,7 +455,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() ZCNoteDecryption decryptor(changeKey.receiving_key()); auto hSig = prevJoinSplit.h_sig(*pzcashParams, tx_.joinSplitPubKey); try { - NotePlaintext plaintext = NotePlaintext::decrypt( + SproutNotePlaintext plaintext = SproutNotePlaintext::decrypt( decryptor, prevJoinSplit.ciphertexts[changeOutputIndex], prevJoinSplit.ephemeralKey, diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index 42805b5e6..4a8cb43ab 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -571,7 +571,7 @@ bool AsyncRPCOperation_sendmany::main_impl() { ZCNoteDecryption decryptor(spendingkey_.receiving_key()); auto hSig = prevJoinSplit.h_sig(*pzcashParams, tx_.joinSplitPubKey); try { - NotePlaintext plaintext = NotePlaintext::decrypt( + SproutNotePlaintext plaintext = SproutNotePlaintext::decrypt( decryptor, prevJoinSplit.ciphertexts[changeOutputIndex], prevJoinSplit.ephemeralKey, @@ -877,13 +877,13 @@ bool AsyncRPCOperation_sendmany::find_utxos(bool fAcceptCoinbase=false) { bool AsyncRPCOperation_sendmany::find_unspent_notes() { - std::vector entries; + std::vector entries; { LOCK2(cs_main, pwalletMain->cs_wallet); pwalletMain->GetFilteredNotes(entries, fromaddress_, mindepth_); } - for (CNotePlaintextEntry & entry : entries) { + for (CSproutNotePlaintextEntry & entry : entries) { z_inputs_.push_back(SendManyInputJSOP(entry.jsop, entry.plaintext.note(frompaymentaddress_), CAmount(entry.plaintext.value))); std::string data(entry.plaintext.memo.begin(), entry.plaintext.memo.end()); LogPrint("zrpcunsafe", "%s: found unspent note (txid=%s, vjoinsplit=%d, ciphertext=%d, amount=%s, memo=%s)\n", diff --git a/src/wallet/gtest/test_wallet.cpp b/src/wallet/gtest/test_wallet.cpp index 78984abed..18df6feff 100644 --- a/src/wallet/gtest/test_wallet.cpp +++ b/src/wallet/gtest/test_wallet.cpp @@ -155,7 +155,7 @@ TEST(wallet_tests, find_unspent_notes) { EXPECT_FALSE(wallet.IsSpent(nullifier)); // We currently have an unspent and unconfirmed note in the wallet (depth of -1) - std::vector entries; + std::vector entries; wallet.GetFilteredNotes(entries, "", 0); EXPECT_EQ(0, entries.size()); entries.clear(); diff --git a/src/wallet/rpcdisclosure.cpp b/src/wallet/rpcdisclosure.cpp index e1c20ab0b..0e158830a 100644 --- a/src/wallet/rpcdisclosure.cpp +++ b/src/wallet/rpcdisclosure.cpp @@ -274,7 +274,7 @@ UniValue z_validatepaymentdisclosure(const UniValue& params, bool fHelp) CDataStream ssPlain(SER_NETWORK, PROTOCOL_VERSION); ssPlain << plaintext; - NotePlaintext npt; + SproutNotePlaintext npt; ssPlain >> npt; string memoHexString = HexStr(npt.memo.data(), npt.memo.data() + npt.memo.size()); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 0463c07e5..05004a7e0 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2539,9 +2539,9 @@ UniValue z_listunspent(const UniValue& params, bool fHelp) UniValue results(UniValue::VARR); if (zaddrs.size() > 0) { - std::vector entries; + std::vector entries; pwalletMain->GetUnspentFilteredNotes(entries, zaddrs, nMinDepth, nMaxDepth, !fIncludeWatchonly); - for (CUnspentNotePlaintextEntry & entry : entries) { + for (CUnspentSproutNotePlaintextEntry & entry : entries) { UniValue obj(UniValue::VOBJ); obj.push_back(Pair("txid",entry.jsop.hash.ToString())); obj.push_back(Pair("jsindex", (int)entry.jsop.js )); @@ -2809,7 +2809,7 @@ UniValue zc_raw_receive(const UniValue& params, bool fHelp) ZCNoteDecryption decryptor(k.receiving_key()); - NotePlaintext npt = NotePlaintext::decrypt( + SproutNotePlaintext npt = SproutNotePlaintext::decrypt( decryptor, ct, epk, @@ -2901,7 +2901,7 @@ UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp) keys.push_back(k); - NotePlaintext npt; + SproutNotePlaintext npt; { CDataStream ssData(ParseHexV(name_, "note"), SER_NETWORK, PROTOCOL_VERSION); @@ -3175,7 +3175,7 @@ CAmount getBalanceTaddr(std::string transparentAddress, int minDepth=1, bool ign CAmount getBalanceZaddr(std::string address, int minDepth = 1, bool ignoreUnspendable=true) { CAmount balance = 0; - std::vector entries; + std::vector entries; LOCK2(cs_main, pwalletMain->cs_wallet); pwalletMain->GetFilteredNotes(entries, address, minDepth, true, ignoreUnspendable); for (auto & entry : entries) { @@ -3235,9 +3235,9 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp) UniValue result(UniValue::VARR); - std::vector entries; + std::vector entries; pwalletMain->GetFilteredNotes(entries, fromaddress, nMinDepth, false, false); - for (CNotePlaintextEntry & entry : entries) { + for (CSproutNotePlaintextEntry & entry : entries) { UniValue obj(UniValue::VOBJ); obj.push_back(Pair("txid",entry.jsop.hash.ToString())); obj.push_back(Pair("amount", ValueFromAmount(CAmount(entry.plaintext.value)))); @@ -4140,11 +4140,11 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) if (useAny || useAnyNote || zaddrs.size() > 0) { // Get available notes - std::vector entries; + std::vector entries; pwalletMain->GetFilteredNotes(entries, zaddrs); // Find unspent notes and update estimated size - for (CNotePlaintextEntry& entry : entries) { + for (CSproutNotePlaintextEntry& entry : entries) { noteCounter++; CAmount nValue = entry.plaintext.value; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index d6d0a274a..448dd50e7 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1264,7 +1264,7 @@ boost::optional CWallet::GetNoteNullifier(const JSDescription& jsdesc, uint8_t n) const { boost::optional ret; - auto note_pt = libzcash::NotePlaintext::decrypt( + auto note_pt = libzcash::SproutNotePlaintext::decrypt( dec, jsdesc.ciphertexts[n], jsdesc.ephemeralKey, @@ -3712,7 +3712,7 @@ bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectAbsurdFee) * Find notes in the wallet filtered by payment address, min depth and ability to spend. * These notes are decrypted and added to the output parameter vector, outEntries. */ -void CWallet::GetFilteredNotes(std::vector & outEntries, std::string address, int minDepth, bool ignoreSpent, bool ignoreUnspendable) +void CWallet::GetFilteredNotes(std::vector & outEntries, std::string address, int minDepth, bool ignoreSpent, bool ignoreUnspendable) { std::set filterAddresses; @@ -3728,7 +3728,7 @@ void CWallet::GetFilteredNotes(std::vector & outEntries, st * These notes are decrypted and added to the output parameter vector, outEntries. */ void CWallet::GetFilteredNotes( - std::vector& outEntries, + std::vector& outEntries, std::set& filterAddresses, int minDepth, bool ignoreSpent, @@ -3786,14 +3786,14 @@ void CWallet::GetFilteredNotes( // determine amount of funds in the note auto hSig = wtx.vjoinsplit[i].h_sig(*pzcashParams, wtx.joinSplitPubKey); try { - NotePlaintext plaintext = NotePlaintext::decrypt( + SproutNotePlaintext plaintext = SproutNotePlaintext::decrypt( decryptor, wtx.vjoinsplit[i].ciphertexts[j], wtx.vjoinsplit[i].ephemeralKey, hSig, (unsigned char) j); - outEntries.push_back(CNotePlaintextEntry{jsop, pa, plaintext}); + outEntries.push_back(CSproutNotePlaintextEntry{jsop, pa, plaintext}); } catch (const note_decryption_failed &err) { // Couldn't decrypt with this spending key @@ -3809,7 +3809,7 @@ void CWallet::GetFilteredNotes( /* Find unspent notes filtered by payment address, min depth and max depth */ void CWallet::GetUnspentFilteredNotes( - std::vector& outEntries, + std::vector& outEntries, std::set& filterAddresses, int minDepth, int maxDepth, @@ -3862,14 +3862,14 @@ void CWallet::GetUnspentFilteredNotes( // determine amount of funds in the note auto hSig = wtx.vjoinsplit[i].h_sig(*pzcashParams, wtx.joinSplitPubKey); try { - NotePlaintext plaintext = NotePlaintext::decrypt( + SproutNotePlaintext plaintext = SproutNotePlaintext::decrypt( decryptor, wtx.vjoinsplit[i].ciphertexts[j], wtx.vjoinsplit[i].ephemeralKey, hSig, (unsigned char) j); - outEntries.push_back(CUnspentNotePlaintextEntry{jsop, pa, plaintext, wtx.GetDepthInMainChain()}); + outEntries.push_back(CUnspentSproutNotePlaintextEntry{jsop, pa, plaintext, wtx.GetDepthInMainChain()}); } catch (const note_decryption_failed &err) { // Couldn't decrypt with this spending key diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 6c968fca9..6c05244e4 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -265,18 +265,18 @@ public: typedef std::map mapNoteData_t; /** Decrypted note and its location in a transaction. */ -struct CNotePlaintextEntry +struct CSproutNotePlaintextEntry { JSOutPoint jsop; libzcash::PaymentAddress address; - libzcash::NotePlaintext plaintext; + libzcash::SproutNotePlaintext plaintext; }; /** Decrypted note, location in a transaction, and confirmation height. */ -struct CUnspentNotePlaintextEntry { +struct CUnspentSproutNotePlaintextEntry { JSOutPoint jsop; libzcash::PaymentAddress address; - libzcash::NotePlaintext plaintext; + libzcash::SproutNotePlaintext plaintext; int nHeight; }; @@ -1139,21 +1139,21 @@ public: void SetBroadcastTransactions(bool broadcast) { fBroadcastTransactions = broadcast; } /* Find notes filtered by payment address, min depth, ability to spend */ - void GetFilteredNotes(std::vector & outEntries, + void GetFilteredNotes(std::vector & outEntries, std::string address, int minDepth=1, bool ignoreSpent=true, bool ignoreUnspendable=true); /* Find notes filtered by payment addresses, min depth, ability to spend */ - void GetFilteredNotes(std::vector& outEntries, + void GetFilteredNotes(std::vector& outEntries, std::set& filterAddresses, int minDepth=1, bool ignoreSpent=true, bool ignoreUnspendable=true); /* Find unspent notes filtered by payment address, min depth and max depth */ - void GetUnspentFilteredNotes(std::vector& outEntries, + void GetUnspentFilteredNotes(std::vector& outEntries, std::set& filterAddresses, int minDepth=1, int maxDepth=INT_MAX, diff --git a/src/zcash/JoinSplit.cpp b/src/zcash/JoinSplit.cpp index 5751d1c6d..d4dee9bb9 100644 --- a/src/zcash/JoinSplit.cpp +++ b/src/zcash/JoinSplit.cpp @@ -246,7 +246,7 @@ public: ZCNoteEncryption encryptor(h_sig); for (size_t i = 0; i < NumOutputs; i++) { - NotePlaintext pt(out_notes[i], outputs[i].memo); + SproutNotePlaintext pt(out_notes[i], outputs[i].memo); out_ciphertexts[i] = pt.encrypt(encryptor, outputs[i].addr.pk_enc); } diff --git a/src/zcash/Note.cpp b/src/zcash/Note.cpp index 5b1ccf51d..0f73a567c 100644 --- a/src/zcash/Note.cpp +++ b/src/zcash/Note.cpp @@ -38,7 +38,7 @@ uint256 SproutNote::nullifier(const SpendingKey& a_sk) const { return PRF_nf(a_sk, rho); } -NotePlaintext::NotePlaintext( +SproutNotePlaintext::SproutNotePlaintext( const SproutNote& note, boost::array memo) : memo(memo) { @@ -47,12 +47,12 @@ NotePlaintext::NotePlaintext( r = note.r; } -SproutNote NotePlaintext::note(const PaymentAddress& addr) const +SproutNote SproutNotePlaintext::note(const PaymentAddress& addr) const { return SproutNote(addr.a_pk, value, rho, r); } -NotePlaintext NotePlaintext::decrypt(const ZCNoteDecryption& decryptor, +SproutNotePlaintext SproutNotePlaintext::decrypt(const ZCNoteDecryption& decryptor, const ZCNoteDecryption::Ciphertext& ciphertext, const uint256& ephemeralKey, const uint256& h_sig, @@ -64,7 +64,7 @@ NotePlaintext NotePlaintext::decrypt(const ZCNoteDecryption& decryptor, CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss << plaintext; - NotePlaintext ret; + SproutNotePlaintext ret; ss >> ret; assert(ss.size() == 0); @@ -72,7 +72,7 @@ NotePlaintext NotePlaintext::decrypt(const ZCNoteDecryption& decryptor, return ret; } -ZCNoteEncryption::Ciphertext NotePlaintext::encrypt(ZCNoteEncryption& encryptor, +ZCNoteEncryption::Ciphertext SproutNotePlaintext::encrypt(ZCNoteEncryption& encryptor, const uint256& pk_enc ) const { diff --git a/src/zcash/Note.hpp b/src/zcash/Note.hpp index 586b172b7..899d80090 100644 --- a/src/zcash/Note.hpp +++ b/src/zcash/Note.hpp @@ -38,16 +38,16 @@ public: uint256 nullifier(const SpendingKey& a_sk) const; }; -class NotePlaintext { +class SproutNotePlaintext { public: uint64_t value = 0; uint256 rho; uint256 r; boost::array memo; - NotePlaintext() {} + SproutNotePlaintext() {} - NotePlaintext(const SproutNote& note, boost::array memo); + SproutNotePlaintext(const SproutNote& note, boost::array memo); SproutNote note(const PaymentAddress& addr) const; @@ -59,7 +59,7 @@ public: READWRITE(leadingByte); if (leadingByte != 0x00) { - throw std::ios_base::failure("lead byte of NotePlaintext is not recognized"); + throw std::ios_base::failure("lead byte of SproutNotePlaintext is not recognized"); } READWRITE(value); @@ -68,7 +68,7 @@ public: READWRITE(memo); } - static NotePlaintext decrypt(const ZCNoteDecryption& decryptor, + static SproutNotePlaintext decrypt(const ZCNoteDecryption& decryptor, const ZCNoteDecryption::Ciphertext& ciphertext, const uint256& ephemeralKey, const uint256& h_sig, From d266f403933169eccb6394fb1f7e3401281fc809 Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 26 Apr 2018 14:05:36 -0700 Subject: [PATCH 7/8] Create class hierarchy for SproutNotePlaintext. BaseNotePlaintext contains member variable for common attribute, value. --- src/gtest/test_joinsplit.cpp | 14 ++++++++++++++ src/wallet/asyncrpcoperation_mergetoaddress.cpp | 4 ++-- src/wallet/asyncrpcoperation_sendmany.cpp | 8 ++++---- src/wallet/rpcdisclosure.cpp | 2 +- src/wallet/rpcwallet.cpp | 8 ++++---- src/zcash/Note.cpp | 4 ++-- src/zcash/Note.hpp | 17 ++++++++++++++--- 7 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/gtest/test_joinsplit.cpp b/src/gtest/test_joinsplit.cpp index 5730b988d..e89a7206f 100644 --- a/src/gtest/test_joinsplit.cpp +++ b/src/gtest/test_joinsplit.cpp @@ -6,6 +6,9 @@ #include "zcash/prf.h" #include "util.h" +#include "streams.h" +#include "version.h" +#include "serialize.h" #include "zcash/JoinSplit.hpp" #include "zcash/Note.hpp" @@ -546,6 +549,17 @@ TEST(joinsplit, note_plaintexts) ASSERT_TRUE(decrypted_note.value() == note.value()); ASSERT_TRUE(decrypted.memo == note_pt.memo); + + // Check serialization of note plaintext + CDataStream ss(SER_DISK, PROTOCOL_VERSION); + ss << note_pt; + SproutNotePlaintext note_pt2; + ss >> note_pt2; + ASSERT_EQ(note_pt.value(), note.value()); + ASSERT_EQ(note_pt.value(), note_pt2.value()); + ASSERT_EQ(note_pt.memo, note_pt2.memo); + ASSERT_EQ(note_pt.rho, note_pt2.rho); + ASSERT_EQ(note_pt.r, note_pt2.r); } TEST(joinsplit, note_class) diff --git a/src/wallet/asyncrpcoperation_mergetoaddress.cpp b/src/wallet/asyncrpcoperation_mergetoaddress.cpp index 49b01c394..2c9cdcb1d 100644 --- a/src/wallet/asyncrpcoperation_mergetoaddress.cpp +++ b/src/wallet/asyncrpcoperation_mergetoaddress.cpp @@ -466,11 +466,11 @@ bool AsyncRPCOperation_mergetoaddress::main_impl() info.notes.push_back(note); info.zkeys.push_back(changeKey); - jsInputValue += plaintext.value; + jsInputValue += plaintext.value(); LogPrint("zrpcunsafe", "%s: spending change (amount=%s)\n", getId(), - FormatMoney(plaintext.value)); + FormatMoney(plaintext.value())); } catch (const std::exception& e) { throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Error decrypting output note of previous JoinSplit: %s", e.what())); diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index 4a8cb43ab..4fc6708bc 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -581,11 +581,11 @@ bool AsyncRPCOperation_sendmany::main_impl() { SproutNote note = plaintext.note(frompaymentaddress_); info.notes.push_back(note); - jsInputValue += plaintext.value; + jsInputValue += plaintext.value(); LogPrint("zrpcunsafe", "%s: spending change (amount=%s)\n", getId(), - FormatMoney(plaintext.value) + FormatMoney(plaintext.value()) ); } catch (const std::exception& e) { @@ -884,14 +884,14 @@ bool AsyncRPCOperation_sendmany::find_unspent_notes() { } for (CSproutNotePlaintextEntry & entry : entries) { - z_inputs_.push_back(SendManyInputJSOP(entry.jsop, entry.plaintext.note(frompaymentaddress_), CAmount(entry.plaintext.value))); + z_inputs_.push_back(SendManyInputJSOP(entry.jsop, entry.plaintext.note(frompaymentaddress_), CAmount(entry.plaintext.value()))); std::string data(entry.plaintext.memo.begin(), entry.plaintext.memo.end()); LogPrint("zrpcunsafe", "%s: found unspent note (txid=%s, vjoinsplit=%d, ciphertext=%d, amount=%s, memo=%s)\n", getId(), entry.jsop.hash.ToString().substr(0, 10), entry.jsop.js, int(entry.jsop.n), // uint8_t - FormatMoney(entry.plaintext.value), + FormatMoney(entry.plaintext.value()), HexStr(data).substr(0, 10) ); } diff --git a/src/wallet/rpcdisclosure.cpp b/src/wallet/rpcdisclosure.cpp index 0e158830a..e9644be44 100644 --- a/src/wallet/rpcdisclosure.cpp +++ b/src/wallet/rpcdisclosure.cpp @@ -279,7 +279,7 @@ UniValue z_validatepaymentdisclosure(const UniValue& params, bool fHelp) string memoHexString = HexStr(npt.memo.data(), npt.memo.data() + npt.memo.size()); o.push_back(Pair("memo", memoHexString)); - o.push_back(Pair("value", ValueFromAmount(npt.value))); + o.push_back(Pair("value", ValueFromAmount(npt.value()))); // Check the blockchain commitment matches decrypted note commitment uint256 cm_blockchain = jsdesc.commitments[pd.payload.n]; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 05004a7e0..7c7021732 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2549,7 +2549,7 @@ UniValue z_listunspent(const UniValue& params, bool fHelp) obj.push_back(Pair("confirmations", entry.nHeight)); obj.push_back(Pair("spendable", pwalletMain->HaveSpendingKey(entry.address))); obj.push_back(Pair("address", CZCPaymentAddress(entry.address).ToString())); - obj.push_back(Pair("amount", ValueFromAmount(CAmount(entry.plaintext.value)))); + obj.push_back(Pair("amount", ValueFromAmount(CAmount(entry.plaintext.value())))); std::string data(entry.plaintext.memo.begin(), entry.plaintext.memo.end()); obj.push_back(Pair("memo", HexStr(data))); results.push_back(obj); @@ -3179,7 +3179,7 @@ CAmount getBalanceZaddr(std::string address, int minDepth = 1, bool ignoreUnspen LOCK2(cs_main, pwalletMain->cs_wallet); pwalletMain->GetFilteredNotes(entries, address, minDepth, true, ignoreUnspendable); for (auto & entry : entries) { - balance += CAmount(entry.plaintext.value); + balance += CAmount(entry.plaintext.value()); } return balance; } @@ -3240,7 +3240,7 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp) for (CSproutNotePlaintextEntry & entry : entries) { UniValue obj(UniValue::VOBJ); obj.push_back(Pair("txid",entry.jsop.hash.ToString())); - obj.push_back(Pair("amount", ValueFromAmount(CAmount(entry.plaintext.value)))); + obj.push_back(Pair("amount", ValueFromAmount(CAmount(entry.plaintext.value())))); std::string data(entry.plaintext.memo.begin(), entry.plaintext.memo.end()); obj.push_back(Pair("memo", HexStr(data))); // (txid, jsindex, jsoutindex) is needed to globally identify a note @@ -4146,7 +4146,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) // Find unspent notes and update estimated size for (CSproutNotePlaintextEntry& entry : entries) { noteCounter++; - CAmount nValue = entry.plaintext.value; + CAmount nValue = entry.plaintext.value(); if (!maxedOutNotesFlag) { // If we haven't added any notes yet and the merge is to a diff --git a/src/zcash/Note.cpp b/src/zcash/Note.cpp index 0f73a567c..6dc82be4c 100644 --- a/src/zcash/Note.cpp +++ b/src/zcash/Note.cpp @@ -42,14 +42,14 @@ SproutNotePlaintext::SproutNotePlaintext( const SproutNote& note, boost::array memo) : memo(memo) { - value = note.value(); + value_ = note.value(); rho = note.rho; r = note.r; } SproutNote SproutNotePlaintext::note(const PaymentAddress& addr) const { - return SproutNote(addr.a_pk, value, rho, r); + return SproutNote(addr.a_pk, value_, rho, r); } SproutNotePlaintext SproutNotePlaintext::decrypt(const ZCNoteDecryption& decryptor, diff --git a/src/zcash/Note.hpp b/src/zcash/Note.hpp index 899d80090..481db5e4b 100644 --- a/src/zcash/Note.hpp +++ b/src/zcash/Note.hpp @@ -38,9 +38,18 @@ public: uint256 nullifier(const SpendingKey& a_sk) const; }; -class SproutNotePlaintext { +class BaseNotePlaintext { +protected: + uint64_t value_ = 0; +public: + BaseNotePlaintext() {} + virtual ~BaseNotePlaintext() {} + + inline uint64_t value() const { return value_; } +}; + +class SproutNotePlaintext : public BaseNotePlaintext { public: - uint64_t value = 0; uint256 rho; uint256 r; boost::array memo; @@ -51,6 +60,8 @@ public: SproutNote note(const PaymentAddress& addr) const; + virtual ~SproutNotePlaintext() {} + ADD_SERIALIZE_METHODS; template @@ -62,7 +73,7 @@ public: throw std::ios_base::failure("lead byte of SproutNotePlaintext is not recognized"); } - READWRITE(value); + READWRITE(value_); READWRITE(rho); READWRITE(r); READWRITE(memo); From debf6af9f8750a698f4deb5580e84e7c01052147 Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 26 Apr 2018 14:53:54 -0700 Subject: [PATCH 8/8] Move memo member varible from SproutNotePlaintext to BaseNotePlaintext. Add memo() accessor to BaseNotePlaintext. --- src/gtest/test_joinsplit.cpp | 4 ++-- src/wallet/asyncrpcoperation_sendmany.cpp | 2 +- src/wallet/rpcdisclosure.cpp | 2 +- src/wallet/rpcwallet.cpp | 4 ++-- src/zcash/Note.cpp | 3 +-- src/zcash/Note.hpp | 7 +++++-- 6 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/gtest/test_joinsplit.cpp b/src/gtest/test_joinsplit.cpp index e89a7206f..dfde47c69 100644 --- a/src/gtest/test_joinsplit.cpp +++ b/src/gtest/test_joinsplit.cpp @@ -548,7 +548,7 @@ TEST(joinsplit, note_plaintexts) ASSERT_TRUE(decrypted_note.r == note.r); ASSERT_TRUE(decrypted_note.value() == note.value()); - ASSERT_TRUE(decrypted.memo == note_pt.memo); + ASSERT_TRUE(decrypted.memo() == note_pt.memo()); // Check serialization of note plaintext CDataStream ss(SER_DISK, PROTOCOL_VERSION); @@ -557,7 +557,7 @@ TEST(joinsplit, note_plaintexts) ss >> note_pt2; ASSERT_EQ(note_pt.value(), note.value()); ASSERT_EQ(note_pt.value(), note_pt2.value()); - ASSERT_EQ(note_pt.memo, note_pt2.memo); + ASSERT_EQ(note_pt.memo(), note_pt2.memo()); ASSERT_EQ(note_pt.rho, note_pt2.rho); ASSERT_EQ(note_pt.r, note_pt2.r); } diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index 4fc6708bc..567fb7248 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -885,7 +885,7 @@ bool AsyncRPCOperation_sendmany::find_unspent_notes() { for (CSproutNotePlaintextEntry & entry : entries) { z_inputs_.push_back(SendManyInputJSOP(entry.jsop, entry.plaintext.note(frompaymentaddress_), CAmount(entry.plaintext.value()))); - std::string data(entry.plaintext.memo.begin(), entry.plaintext.memo.end()); + std::string data(entry.plaintext.memo().begin(), entry.plaintext.memo().end()); LogPrint("zrpcunsafe", "%s: found unspent note (txid=%s, vjoinsplit=%d, ciphertext=%d, amount=%s, memo=%s)\n", getId(), entry.jsop.hash.ToString().substr(0, 10), diff --git a/src/wallet/rpcdisclosure.cpp b/src/wallet/rpcdisclosure.cpp index e9644be44..d4f87ab39 100644 --- a/src/wallet/rpcdisclosure.cpp +++ b/src/wallet/rpcdisclosure.cpp @@ -277,7 +277,7 @@ UniValue z_validatepaymentdisclosure(const UniValue& params, bool fHelp) SproutNotePlaintext npt; ssPlain >> npt; - string memoHexString = HexStr(npt.memo.data(), npt.memo.data() + npt.memo.size()); + string memoHexString = HexStr(npt.memo().data(), npt.memo().data() + npt.memo().size()); o.push_back(Pair("memo", memoHexString)); o.push_back(Pair("value", ValueFromAmount(npt.value()))); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 7c7021732..3a670e8a7 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2550,7 +2550,7 @@ UniValue z_listunspent(const UniValue& params, bool fHelp) obj.push_back(Pair("spendable", pwalletMain->HaveSpendingKey(entry.address))); obj.push_back(Pair("address", CZCPaymentAddress(entry.address).ToString())); obj.push_back(Pair("amount", ValueFromAmount(CAmount(entry.plaintext.value())))); - std::string data(entry.plaintext.memo.begin(), entry.plaintext.memo.end()); + std::string data(entry.plaintext.memo().begin(), entry.plaintext.memo().end()); obj.push_back(Pair("memo", HexStr(data))); results.push_back(obj); } @@ -3241,7 +3241,7 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp) UniValue obj(UniValue::VOBJ); obj.push_back(Pair("txid",entry.jsop.hash.ToString())); obj.push_back(Pair("amount", ValueFromAmount(CAmount(entry.plaintext.value())))); - std::string data(entry.plaintext.memo.begin(), entry.plaintext.memo.end()); + std::string data(entry.plaintext.memo().begin(), entry.plaintext.memo().end()); obj.push_back(Pair("memo", HexStr(data))); // (txid, jsindex, jsoutindex) is needed to globally identify a note obj.push_back(Pair("jsindex", entry.jsop.js)); diff --git a/src/zcash/Note.cpp b/src/zcash/Note.cpp index 6dc82be4c..407925e15 100644 --- a/src/zcash/Note.cpp +++ b/src/zcash/Note.cpp @@ -40,9 +40,8 @@ uint256 SproutNote::nullifier(const SpendingKey& a_sk) const { SproutNotePlaintext::SproutNotePlaintext( const SproutNote& note, - boost::array memo) : memo(memo) + boost::array memo) : BaseNotePlaintext(note, memo) { - value_ = note.value(); rho = note.rho; r = note.r; } diff --git a/src/zcash/Note.hpp b/src/zcash/Note.hpp index 481db5e4b..8254717bb 100644 --- a/src/zcash/Note.hpp +++ b/src/zcash/Note.hpp @@ -41,18 +41,21 @@ public: class BaseNotePlaintext { protected: uint64_t value_ = 0; + boost::array memo_; public: BaseNotePlaintext() {} + BaseNotePlaintext(const BaseNote& note, boost::array memo) + : value_(note.value()), memo_(memo) {} virtual ~BaseNotePlaintext() {} inline uint64_t value() const { return value_; } + inline boost::array memo() const { return memo_; } }; class SproutNotePlaintext : public BaseNotePlaintext { public: uint256 rho; uint256 r; - boost::array memo; SproutNotePlaintext() {} @@ -76,7 +79,7 @@ public: READWRITE(value_); READWRITE(rho); READWRITE(r); - READWRITE(memo); + READWRITE(memo_); } static SproutNotePlaintext decrypt(const ZCNoteDecryption& decryptor,