Auto merge of #3234 - str4d:3058-address-polymorphism, r=str4d
Use boost::variant to represent shielded addresses and keys Part of #3058 and #3059.
This commit is contained in:
commit
75546c697a
|
@ -25,8 +25,8 @@ void test_full_api(ZCJoinSplit* js)
|
||||||
auto verifier = libzcash::ProofVerifier::Strict();
|
auto verifier = libzcash::ProofVerifier::Strict();
|
||||||
|
|
||||||
// The recipient's information.
|
// The recipient's information.
|
||||||
SpendingKey recipient_key = SpendingKey::random();
|
SproutSpendingKey recipient_key = SproutSpendingKey::random();
|
||||||
PaymentAddress recipient_addr = recipient_key.address();
|
SproutPaymentAddress recipient_addr = recipient_key.address();
|
||||||
|
|
||||||
// Create the commitment tree
|
// Create the commitment tree
|
||||||
ZCIncrementalMerkleTree tree;
|
ZCIncrementalMerkleTree tree;
|
||||||
|
@ -122,8 +122,8 @@ void test_full_api(ZCJoinSplit* js)
|
||||||
JSInput(witness_recipient, decrypted_note, recipient_key)
|
JSInput(witness_recipient, decrypted_note, recipient_key)
|
||||||
};
|
};
|
||||||
|
|
||||||
SpendingKey second_recipient = SpendingKey::random();
|
SproutSpendingKey second_recipient = SproutSpendingKey::random();
|
||||||
PaymentAddress second_addr = second_recipient.address();
|
SproutPaymentAddress second_addr = second_recipient.address();
|
||||||
|
|
||||||
boost::array<JSOutput, 2> outputs = {
|
boost::array<JSOutput, 2> outputs = {
|
||||||
JSOutput(second_addr, 9),
|
JSOutput(second_addr, 9),
|
||||||
|
@ -317,8 +317,8 @@ TEST(joinsplit, full_api_test)
|
||||||
std::vector<ZCIncrementalWitness> witnesses;
|
std::vector<ZCIncrementalWitness> witnesses;
|
||||||
ZCIncrementalMerkleTree tree;
|
ZCIncrementalMerkleTree tree;
|
||||||
increment_note_witnesses(uint256(), witnesses, tree);
|
increment_note_witnesses(uint256(), witnesses, tree);
|
||||||
SpendingKey sk = SpendingKey::random();
|
SproutSpendingKey sk = SproutSpendingKey::random();
|
||||||
PaymentAddress addr = sk.address();
|
SproutPaymentAddress addr = sk.address();
|
||||||
SproutNote 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);
|
increment_note_witnesses(note1.cm(), witnesses, tree);
|
||||||
SproutNote note2(addr.a_pk, 100, random_uint256(), random_uint256());
|
SproutNote note2(addr.a_pk, 100, random_uint256(), random_uint256());
|
||||||
|
@ -422,7 +422,7 @@ TEST(joinsplit, full_api_test)
|
||||||
// Wrong secret key
|
// Wrong secret key
|
||||||
invokeAPIFailure(params,
|
invokeAPIFailure(params,
|
||||||
{
|
{
|
||||||
JSInput(witnesses[1], note1, SpendingKey::random()),
|
JSInput(witnesses[1], note1, SproutSpendingKey::random()),
|
||||||
JSInput()
|
JSInput()
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -519,7 +519,7 @@ TEST(joinsplit, note_plaintexts)
|
||||||
uint256 a_pk = PRF_addr_a_pk(a_sk);
|
uint256 a_pk = PRF_addr_a_pk(a_sk);
|
||||||
uint256 sk_enc = ZCNoteEncryption::generate_privkey(a_sk);
|
uint256 sk_enc = ZCNoteEncryption::generate_privkey(a_sk);
|
||||||
uint256 pk_enc = ZCNoteEncryption::generate_pubkey(sk_enc);
|
uint256 pk_enc = ZCNoteEncryption::generate_pubkey(sk_enc);
|
||||||
PaymentAddress addr_pk(a_pk, pk_enc);
|
SproutPaymentAddress addr_pk(a_pk, pk_enc);
|
||||||
|
|
||||||
uint256 h_sig;
|
uint256 h_sig;
|
||||||
|
|
||||||
|
@ -572,7 +572,7 @@ TEST(joinsplit, note_class)
|
||||||
uint256 a_pk = PRF_addr_a_pk(a_sk);
|
uint256 a_pk = PRF_addr_a_pk(a_sk);
|
||||||
uint256 sk_enc = ZCNoteEncryption::generate_privkey(a_sk);
|
uint256 sk_enc = ZCNoteEncryption::generate_privkey(a_sk);
|
||||||
uint256 pk_enc = ZCNoteEncryption::generate_pubkey(sk_enc);
|
uint256 pk_enc = ZCNoteEncryption::generate_pubkey(sk_enc);
|
||||||
PaymentAddress addr_pk(a_pk, pk_enc);
|
SproutPaymentAddress addr_pk(a_pk, pk_enc);
|
||||||
|
|
||||||
SproutNote note(a_pk,
|
SproutNote note(a_pk,
|
||||||
1945813,
|
1945813,
|
||||||
|
|
|
@ -9,13 +9,13 @@
|
||||||
|
|
||||||
TEST(keystore_tests, store_and_retrieve_spending_key) {
|
TEST(keystore_tests, store_and_retrieve_spending_key) {
|
||||||
CBasicKeyStore keyStore;
|
CBasicKeyStore keyStore;
|
||||||
libzcash::SpendingKey skOut;
|
libzcash::SproutSpendingKey skOut;
|
||||||
|
|
||||||
std::set<libzcash::PaymentAddress> addrs;
|
std::set<libzcash::SproutPaymentAddress> addrs;
|
||||||
keyStore.GetPaymentAddresses(addrs);
|
keyStore.GetPaymentAddresses(addrs);
|
||||||
EXPECT_EQ(0, addrs.size());
|
EXPECT_EQ(0, addrs.size());
|
||||||
|
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
auto addr = sk.address();
|
auto addr = sk.address();
|
||||||
|
|
||||||
// Sanity-check: we can't get a key we haven't added
|
// Sanity-check: we can't get a key we haven't added
|
||||||
|
@ -36,7 +36,7 @@ TEST(keystore_tests, store_and_retrieve_note_decryptor) {
|
||||||
CBasicKeyStore keyStore;
|
CBasicKeyStore keyStore;
|
||||||
ZCNoteDecryption decOut;
|
ZCNoteDecryption decOut;
|
||||||
|
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
auto addr = sk.address();
|
auto addr = sk.address();
|
||||||
|
|
||||||
EXPECT_FALSE(keyStore.GetNoteDecryptor(addr, decOut));
|
EXPECT_FALSE(keyStore.GetNoteDecryptor(addr, decOut));
|
||||||
|
@ -48,11 +48,11 @@ TEST(keystore_tests, store_and_retrieve_note_decryptor) {
|
||||||
|
|
||||||
TEST(keystore_tests, StoreAndRetrieveViewingKey) {
|
TEST(keystore_tests, StoreAndRetrieveViewingKey) {
|
||||||
CBasicKeyStore keyStore;
|
CBasicKeyStore keyStore;
|
||||||
libzcash::ViewingKey vkOut;
|
libzcash::SproutViewingKey vkOut;
|
||||||
libzcash::SpendingKey skOut;
|
libzcash::SproutSpendingKey skOut;
|
||||||
ZCNoteDecryption decOut;
|
ZCNoteDecryption decOut;
|
||||||
|
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
auto vk = sk.viewing_key();
|
auto vk = sk.viewing_key();
|
||||||
auto addr = sk.address();
|
auto addr = sk.address();
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ TEST(keystore_tests, StoreAndRetrieveViewingKey) {
|
||||||
EXPECT_FALSE(keyStore.GetNoteDecryptor(addr, decOut));
|
EXPECT_FALSE(keyStore.GetNoteDecryptor(addr, decOut));
|
||||||
|
|
||||||
// and we can't find it in our list of addresses
|
// and we can't find it in our list of addresses
|
||||||
std::set<libzcash::PaymentAddress> addresses;
|
std::set<libzcash::SproutPaymentAddress> addresses;
|
||||||
keyStore.GetPaymentAddresses(addresses);
|
keyStore.GetPaymentAddresses(addresses);
|
||||||
EXPECT_FALSE(addresses.count(addr));
|
EXPECT_FALSE(addresses.count(addr));
|
||||||
|
|
||||||
|
@ -115,12 +115,12 @@ TEST(keystore_tests, store_and_retrieve_spending_key_in_encrypted_store) {
|
||||||
TestCCryptoKeyStore keyStore;
|
TestCCryptoKeyStore keyStore;
|
||||||
uint256 r {GetRandHash()};
|
uint256 r {GetRandHash()};
|
||||||
CKeyingMaterial vMasterKey (r.begin(), r.end());
|
CKeyingMaterial vMasterKey (r.begin(), r.end());
|
||||||
libzcash::SpendingKey keyOut;
|
libzcash::SproutSpendingKey keyOut;
|
||||||
ZCNoteDecryption decOut;
|
ZCNoteDecryption decOut;
|
||||||
std::set<libzcash::PaymentAddress> addrs;
|
std::set<libzcash::SproutPaymentAddress> addrs;
|
||||||
|
|
||||||
// 1) Test adding a key to an unencrypted key store, then encrypting it
|
// 1) Test adding a key to an unencrypted key store, then encrypting it
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
auto addr = sk.address();
|
auto addr = sk.address();
|
||||||
EXPECT_FALSE(keyStore.GetNoteDecryptor(addr, decOut));
|
EXPECT_FALSE(keyStore.GetNoteDecryptor(addr, decOut));
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ TEST(keystore_tests, store_and_retrieve_spending_key_in_encrypted_store) {
|
||||||
ASSERT_EQ(1, addrs.count(addr));
|
ASSERT_EQ(1, addrs.count(addr));
|
||||||
|
|
||||||
// 2) Test adding a spending key to an already-encrypted key store
|
// 2) Test adding a spending key to an already-encrypted key store
|
||||||
auto sk2 = libzcash::SpendingKey::random();
|
auto sk2 = libzcash::SproutSpendingKey::random();
|
||||||
auto addr2 = sk2.address();
|
auto addr2 = sk2.address();
|
||||||
EXPECT_FALSE(keyStore.GetNoteDecryptor(addr2, decOut));
|
EXPECT_FALSE(keyStore.GetNoteDecryptor(addr2, decOut));
|
||||||
|
|
||||||
|
|
|
@ -120,7 +120,7 @@ TEST(paymentdisclosure, mainnet) {
|
||||||
PaymentDisclosureInfo info;
|
PaymentDisclosureInfo info;
|
||||||
info.esk = random_uint256();
|
info.esk = random_uint256();
|
||||||
info.joinSplitPrivKey = joinSplitPrivKey;
|
info.joinSplitPrivKey = joinSplitPrivKey;
|
||||||
info.zaddr = libzcash::SpendingKey::random().address();
|
info.zaddr = libzcash::SproutSpendingKey::random().address();
|
||||||
ASSERT_TRUE(mydb.Put(key, info));
|
ASSERT_TRUE(mydb.Put(key, info));
|
||||||
|
|
||||||
// Retrieve info from test database into new local variable and test it matches
|
// Retrieve info from test database into new local variable and test it matches
|
||||||
|
@ -131,7 +131,7 @@ TEST(paymentdisclosure, mainnet) {
|
||||||
// Modify this local variable and confirm it no longer matches
|
// Modify this local variable and confirm it no longer matches
|
||||||
info2.esk = random_uint256();
|
info2.esk = random_uint256();
|
||||||
info2.joinSplitPrivKey = random_uint256();
|
info2.joinSplitPrivKey = random_uint256();
|
||||||
info2.zaddr = libzcash::SpendingKey::random().address();
|
info2.zaddr = libzcash::SproutSpendingKey::random().address();
|
||||||
ASSERT_NE(info, info2);
|
ASSERT_NE(info, info2);
|
||||||
|
|
||||||
// Using the payment info object, let's create a dummy payload
|
// Using the payment info object, let's create a dummy payload
|
||||||
|
|
|
@ -12,8 +12,8 @@ TEST(Transaction, JSDescriptionRandomized) {
|
||||||
// construct a merkle tree
|
// construct a merkle tree
|
||||||
ZCIncrementalMerkleTree merkleTree;
|
ZCIncrementalMerkleTree merkleTree;
|
||||||
|
|
||||||
libzcash::SpendingKey k = libzcash::SpendingKey::random();
|
libzcash::SproutSpendingKey k = libzcash::SproutSpendingKey::random();
|
||||||
libzcash::PaymentAddress addr = k.address();
|
libzcash::SproutPaymentAddress addr = k.address();
|
||||||
|
|
||||||
libzcash::SproutNote note(addr.a_pk, 100, uint256(), uint256());
|
libzcash::SproutNote note(addr.a_pk, 100, uint256(), uint256());
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ TEST(Validation, ContextualCheckInputsPassesWithCoinbase) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Validation, ReceivedBlockTransactions) {
|
TEST(Validation, ReceivedBlockTransactions) {
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
|
|
||||||
// Create a fake genesis block
|
// Create a fake genesis block
|
||||||
CBlock block1;
|
CBlock block1;
|
||||||
|
|
108
src/key_io.cpp
108
src/key_io.cpp
|
@ -67,6 +67,70 @@ CTxDestination DecodeDestination(const std::string& str, const CChainParams& par
|
||||||
}
|
}
|
||||||
return CNoDestination();
|
return CNoDestination();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PaymentAddressEncoder : public boost::static_visitor<std::string>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const CChainParams& m_params;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PaymentAddressEncoder(const CChainParams& params) : m_params(params) {}
|
||||||
|
|
||||||
|
std::string operator()(const libzcash::SproutPaymentAddress& zaddr) const
|
||||||
|
{
|
||||||
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||||
|
ss << zaddr;
|
||||||
|
std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::ZCPAYMENT_ADDRRESS);
|
||||||
|
data.insert(data.end(), ss.begin(), ss.end());
|
||||||
|
return EncodeBase58Check(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string operator()(const libzcash::InvalidEncoding& no) const { return {}; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class ViewingKeyEncoder : public boost::static_visitor<std::string>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const CChainParams& m_params;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ViewingKeyEncoder(const CChainParams& params) : m_params(params) {}
|
||||||
|
|
||||||
|
std::string operator()(const libzcash::SproutViewingKey& vk) const
|
||||||
|
{
|
||||||
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||||
|
ss << vk;
|
||||||
|
std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::ZCVIEWING_KEY);
|
||||||
|
data.insert(data.end(), ss.begin(), ss.end());
|
||||||
|
std::string ret = EncodeBase58Check(data);
|
||||||
|
memory_cleanse(data.data(), data.size());
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string operator()(const libzcash::InvalidEncoding& no) const { return {}; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class SpendingKeyEncoder : public boost::static_visitor<std::string>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const CChainParams& m_params;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SpendingKeyEncoder(const CChainParams& params) : m_params(params) {}
|
||||||
|
|
||||||
|
std::string operator()(const libzcash::SproutSpendingKey& zkey) const
|
||||||
|
{
|
||||||
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||||
|
ss << zkey;
|
||||||
|
std::vector<unsigned char> data = m_params.Base58Prefix(CChainParams::ZCSPENDING_KEY);
|
||||||
|
data.insert(data.end(), ss.begin(), ss.end());
|
||||||
|
std::string ret = EncodeBase58Check(data);
|
||||||
|
memory_cleanse(data.data(), data.size());
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string operator()(const libzcash::InvalidEncoding& no) const { return {}; }
|
||||||
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
CKey DecodeSecret(const std::string& str)
|
CKey DecodeSecret(const std::string& str)
|
||||||
|
@ -167,14 +231,10 @@ bool IsValidDestinationString(const std::string& str)
|
||||||
|
|
||||||
std::string EncodePaymentAddress(const libzcash::PaymentAddress& zaddr)
|
std::string EncodePaymentAddress(const libzcash::PaymentAddress& zaddr)
|
||||||
{
|
{
|
||||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
return boost::apply_visitor(PaymentAddressEncoder(Params()), zaddr);
|
||||||
ss << zaddr;
|
|
||||||
std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::ZCPAYMENT_ADDRRESS);
|
|
||||||
data.insert(data.end(), ss.begin(), ss.end());
|
|
||||||
return EncodeBase58Check(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::optional<libzcash::PaymentAddress> DecodePaymentAddress(const std::string& str)
|
libzcash::PaymentAddress DecodePaymentAddress(const std::string& str)
|
||||||
{
|
{
|
||||||
std::vector<unsigned char> data;
|
std::vector<unsigned char> data;
|
||||||
if (DecodeBase58Check(str, data)) {
|
if (DecodeBase58Check(str, data)) {
|
||||||
|
@ -183,26 +243,24 @@ boost::optional<libzcash::PaymentAddress> DecodePaymentAddress(const std::string
|
||||||
std::equal(zaddr_prefix.begin(), zaddr_prefix.end(), data.begin())) {
|
std::equal(zaddr_prefix.begin(), zaddr_prefix.end(), data.begin())) {
|
||||||
CSerializeData serialized(data.begin() + zaddr_prefix.size(), data.end());
|
CSerializeData serialized(data.begin() + zaddr_prefix.size(), data.end());
|
||||||
CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION);
|
CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION);
|
||||||
libzcash::PaymentAddress ret;
|
libzcash::SproutPaymentAddress ret;
|
||||||
ss >> ret;
|
ss >> ret;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return boost::none;
|
return libzcash::InvalidEncoding();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsValidPaymentAddressString(const std::string& str) {
|
||||||
|
return IsValidPaymentAddress(DecodePaymentAddress(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string EncodeViewingKey(const libzcash::ViewingKey& vk)
|
std::string EncodeViewingKey(const libzcash::ViewingKey& vk)
|
||||||
{
|
{
|
||||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
return boost::apply_visitor(ViewingKeyEncoder(Params()), vk);
|
||||||
ss << vk;
|
|
||||||
std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::ZCVIEWING_KEY);
|
|
||||||
data.insert(data.end(), ss.begin(), ss.end());
|
|
||||||
std::string ret = EncodeBase58Check(data);
|
|
||||||
memory_cleanse(data.data(), data.size());
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::optional<libzcash::ViewingKey> DecodeViewingKey(const std::string& str)
|
libzcash::ViewingKey DecodeViewingKey(const std::string& str)
|
||||||
{
|
{
|
||||||
std::vector<unsigned char> data;
|
std::vector<unsigned char> data;
|
||||||
if (DecodeBase58Check(str, data)) {
|
if (DecodeBase58Check(str, data)) {
|
||||||
|
@ -211,7 +269,7 @@ boost::optional<libzcash::ViewingKey> DecodeViewingKey(const std::string& str)
|
||||||
std::equal(vk_prefix.begin(), vk_prefix.end(), data.begin())) {
|
std::equal(vk_prefix.begin(), vk_prefix.end(), data.begin())) {
|
||||||
CSerializeData serialized(data.begin() + vk_prefix.size(), data.end());
|
CSerializeData serialized(data.begin() + vk_prefix.size(), data.end());
|
||||||
CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION);
|
CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION);
|
||||||
libzcash::ViewingKey ret;
|
libzcash::SproutViewingKey ret;
|
||||||
ss >> ret;
|
ss >> ret;
|
||||||
memory_cleanse(serialized.data(), serialized.size());
|
memory_cleanse(serialized.data(), serialized.size());
|
||||||
memory_cleanse(data.data(), data.size());
|
memory_cleanse(data.data(), data.size());
|
||||||
|
@ -219,21 +277,15 @@ boost::optional<libzcash::ViewingKey> DecodeViewingKey(const std::string& str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
memory_cleanse(data.data(), data.size());
|
memory_cleanse(data.data(), data.size());
|
||||||
return boost::none;
|
return libzcash::InvalidEncoding();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string EncodeSpendingKey(const libzcash::SpendingKey& zkey)
|
std::string EncodeSpendingKey(const libzcash::SpendingKey& zkey)
|
||||||
{
|
{
|
||||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
return boost::apply_visitor(SpendingKeyEncoder(Params()), zkey);
|
||||||
ss << zkey;
|
|
||||||
std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::ZCSPENDING_KEY);
|
|
||||||
data.insert(data.end(), ss.begin(), ss.end());
|
|
||||||
std::string ret = EncodeBase58Check(data);
|
|
||||||
memory_cleanse(data.data(), data.size());
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::optional<libzcash::SpendingKey> DecodeSpendingKey(const std::string& str)
|
libzcash::SpendingKey DecodeSpendingKey(const std::string& str)
|
||||||
{
|
{
|
||||||
std::vector<unsigned char> data;
|
std::vector<unsigned char> data;
|
||||||
if (DecodeBase58Check(str, data)) {
|
if (DecodeBase58Check(str, data)) {
|
||||||
|
@ -242,7 +294,7 @@ boost::optional<libzcash::SpendingKey> DecodeSpendingKey(const std::string& str)
|
||||||
std::equal(zkey_prefix.begin(), zkey_prefix.end(), data.begin())) {
|
std::equal(zkey_prefix.begin(), zkey_prefix.end(), data.begin())) {
|
||||||
CSerializeData serialized(data.begin() + zkey_prefix.size(), data.end());
|
CSerializeData serialized(data.begin() + zkey_prefix.size(), data.end());
|
||||||
CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION);
|
CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION);
|
||||||
libzcash::SpendingKey ret;
|
libzcash::SproutSpendingKey ret;
|
||||||
ss >> ret;
|
ss >> ret;
|
||||||
memory_cleanse(serialized.data(), serialized.size());
|
memory_cleanse(serialized.data(), serialized.size());
|
||||||
memory_cleanse(data.data(), data.size());
|
memory_cleanse(data.data(), data.size());
|
||||||
|
@ -250,5 +302,5 @@ boost::optional<libzcash::SpendingKey> DecodeSpendingKey(const std::string& str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
memory_cleanse(data.data(), data.size());
|
memory_cleanse(data.data(), data.size());
|
||||||
return boost::none;
|
return libzcash::InvalidEncoding();
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,12 +29,13 @@ bool IsValidDestinationString(const std::string& str);
|
||||||
bool IsValidDestinationString(const std::string& str, const CChainParams& params);
|
bool IsValidDestinationString(const std::string& str, const CChainParams& params);
|
||||||
|
|
||||||
std::string EncodePaymentAddress(const libzcash::PaymentAddress& zaddr);
|
std::string EncodePaymentAddress(const libzcash::PaymentAddress& zaddr);
|
||||||
boost::optional<libzcash::PaymentAddress> DecodePaymentAddress(const std::string& str);
|
libzcash::PaymentAddress DecodePaymentAddress(const std::string& str);
|
||||||
|
bool IsValidPaymentAddressString(const std::string& str);
|
||||||
|
|
||||||
std::string EncodeViewingKey(const libzcash::ViewingKey& vk);
|
std::string EncodeViewingKey(const libzcash::ViewingKey& vk);
|
||||||
boost::optional<libzcash::ViewingKey> DecodeViewingKey(const std::string& str);
|
libzcash::ViewingKey DecodeViewingKey(const std::string& str);
|
||||||
|
|
||||||
std::string EncodeSpendingKey(const libzcash::SpendingKey& zkey);
|
std::string EncodeSpendingKey(const libzcash::SpendingKey& zkey);
|
||||||
boost::optional<libzcash::SpendingKey> DecodeSpendingKey(const std::string& str);
|
libzcash::SpendingKey DecodeSpendingKey(const std::string& str);
|
||||||
|
|
||||||
#endif // BITCOIN_KEYIO_H
|
#endif // BITCOIN_KEYIO_H
|
||||||
|
|
|
@ -84,7 +84,7 @@ bool CBasicKeyStore::HaveWatchOnly() const
|
||||||
return (!setWatchOnly.empty());
|
return (!setWatchOnly.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CBasicKeyStore::AddSpendingKey(const libzcash::SpendingKey &sk)
|
bool CBasicKeyStore::AddSpendingKey(const libzcash::SproutSpendingKey &sk)
|
||||||
{
|
{
|
||||||
LOCK(cs_SpendingKeyStore);
|
LOCK(cs_SpendingKeyStore);
|
||||||
auto address = sk.address();
|
auto address = sk.address();
|
||||||
|
@ -93,7 +93,7 @@ bool CBasicKeyStore::AddSpendingKey(const libzcash::SpendingKey &sk)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CBasicKeyStore::AddViewingKey(const libzcash::ViewingKey &vk)
|
bool CBasicKeyStore::AddViewingKey(const libzcash::SproutViewingKey &vk)
|
||||||
{
|
{
|
||||||
LOCK(cs_SpendingKeyStore);
|
LOCK(cs_SpendingKeyStore);
|
||||||
auto address = vk.address();
|
auto address = vk.address();
|
||||||
|
@ -102,21 +102,21 @@ bool CBasicKeyStore::AddViewingKey(const libzcash::ViewingKey &vk)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CBasicKeyStore::RemoveViewingKey(const libzcash::ViewingKey &vk)
|
bool CBasicKeyStore::RemoveViewingKey(const libzcash::SproutViewingKey &vk)
|
||||||
{
|
{
|
||||||
LOCK(cs_SpendingKeyStore);
|
LOCK(cs_SpendingKeyStore);
|
||||||
mapViewingKeys.erase(vk.address());
|
mapViewingKeys.erase(vk.address());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CBasicKeyStore::HaveViewingKey(const libzcash::PaymentAddress &address) const
|
bool CBasicKeyStore::HaveViewingKey(const libzcash::SproutPaymentAddress &address) const
|
||||||
{
|
{
|
||||||
LOCK(cs_SpendingKeyStore);
|
LOCK(cs_SpendingKeyStore);
|
||||||
return mapViewingKeys.count(address) > 0;
|
return mapViewingKeys.count(address) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CBasicKeyStore::GetViewingKey(const libzcash::PaymentAddress &address,
|
bool CBasicKeyStore::GetViewingKey(const libzcash::SproutPaymentAddress &address,
|
||||||
libzcash::ViewingKey &vkOut) const
|
libzcash::SproutViewingKey &vkOut) const
|
||||||
{
|
{
|
||||||
LOCK(cs_SpendingKeyStore);
|
LOCK(cs_SpendingKeyStore);
|
||||||
ViewingKeyMap::const_iterator mi = mapViewingKeys.find(address);
|
ViewingKeyMap::const_iterator mi = mapViewingKeys.find(address);
|
||||||
|
|
|
@ -49,26 +49,26 @@ public:
|
||||||
virtual bool HaveWatchOnly() const =0;
|
virtual bool HaveWatchOnly() const =0;
|
||||||
|
|
||||||
//! Add a spending key to the store.
|
//! Add a spending key to the store.
|
||||||
virtual bool AddSpendingKey(const libzcash::SpendingKey &sk) =0;
|
virtual bool AddSpendingKey(const libzcash::SproutSpendingKey &sk) =0;
|
||||||
|
|
||||||
//! Check whether a spending key corresponding to a given payment address is present in the store.
|
//! Check whether a spending key corresponding to a given payment address is present in the store.
|
||||||
virtual bool HaveSpendingKey(const libzcash::PaymentAddress &address) const =0;
|
virtual bool HaveSpendingKey(const libzcash::SproutPaymentAddress &address) const =0;
|
||||||
virtual bool GetSpendingKey(const libzcash::PaymentAddress &address, libzcash::SpendingKey& skOut) const =0;
|
virtual bool GetSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey& skOut) const =0;
|
||||||
virtual void GetPaymentAddresses(std::set<libzcash::PaymentAddress> &setAddress) const =0;
|
virtual void GetPaymentAddresses(std::set<libzcash::SproutPaymentAddress> &setAddress) const =0;
|
||||||
|
|
||||||
//! Support for viewing keys
|
//! Support for viewing keys
|
||||||
virtual bool AddViewingKey(const libzcash::ViewingKey &vk) =0;
|
virtual bool AddViewingKey(const libzcash::SproutViewingKey &vk) =0;
|
||||||
virtual bool RemoveViewingKey(const libzcash::ViewingKey &vk) =0;
|
virtual bool RemoveViewingKey(const libzcash::SproutViewingKey &vk) =0;
|
||||||
virtual bool HaveViewingKey(const libzcash::PaymentAddress &address) const =0;
|
virtual bool HaveViewingKey(const libzcash::SproutPaymentAddress &address) const =0;
|
||||||
virtual bool GetViewingKey(const libzcash::PaymentAddress &address, libzcash::ViewingKey& vkOut) const =0;
|
virtual bool GetViewingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutViewingKey& vkOut) const =0;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<CKeyID, CKey> KeyMap;
|
typedef std::map<CKeyID, CKey> KeyMap;
|
||||||
typedef std::map<CScriptID, CScript > ScriptMap;
|
typedef std::map<CScriptID, CScript > ScriptMap;
|
||||||
typedef std::set<CScript> WatchOnlySet;
|
typedef std::set<CScript> WatchOnlySet;
|
||||||
typedef std::map<libzcash::PaymentAddress, libzcash::SpendingKey> SpendingKeyMap;
|
typedef std::map<libzcash::SproutPaymentAddress, libzcash::SproutSpendingKey> SpendingKeyMap;
|
||||||
typedef std::map<libzcash::PaymentAddress, libzcash::ViewingKey> ViewingKeyMap;
|
typedef std::map<libzcash::SproutPaymentAddress, libzcash::SproutViewingKey> ViewingKeyMap;
|
||||||
typedef std::map<libzcash::PaymentAddress, ZCNoteDecryption> NoteDecryptorMap;
|
typedef std::map<libzcash::SproutPaymentAddress, ZCNoteDecryption> NoteDecryptorMap;
|
||||||
|
|
||||||
/** Basic key store, that keeps keys in an address->secret map */
|
/** Basic key store, that keeps keys in an address->secret map */
|
||||||
class CBasicKeyStore : public CKeyStore
|
class CBasicKeyStore : public CKeyStore
|
||||||
|
@ -127,8 +127,8 @@ public:
|
||||||
virtual bool HaveWatchOnly(const CScript &dest) const;
|
virtual bool HaveWatchOnly(const CScript &dest) const;
|
||||||
virtual bool HaveWatchOnly() const;
|
virtual bool HaveWatchOnly() const;
|
||||||
|
|
||||||
bool AddSpendingKey(const libzcash::SpendingKey &sk);
|
bool AddSpendingKey(const libzcash::SproutSpendingKey &sk);
|
||||||
bool HaveSpendingKey(const libzcash::PaymentAddress &address) const
|
bool HaveSpendingKey(const libzcash::SproutPaymentAddress &address) const
|
||||||
{
|
{
|
||||||
bool result;
|
bool result;
|
||||||
{
|
{
|
||||||
|
@ -137,7 +137,7 @@ public:
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
bool GetSpendingKey(const libzcash::PaymentAddress &address, libzcash::SpendingKey &skOut) const
|
bool GetSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey &skOut) const
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
LOCK(cs_SpendingKeyStore);
|
LOCK(cs_SpendingKeyStore);
|
||||||
|
@ -150,7 +150,7 @@ public:
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool GetNoteDecryptor(const libzcash::PaymentAddress &address, ZCNoteDecryption &decOut) const
|
bool GetNoteDecryptor(const libzcash::SproutPaymentAddress &address, ZCNoteDecryption &decOut) const
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
LOCK(cs_SpendingKeyStore);
|
LOCK(cs_SpendingKeyStore);
|
||||||
|
@ -163,7 +163,7 @@ public:
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
void GetPaymentAddresses(std::set<libzcash::PaymentAddress> &setAddress) const
|
void GetPaymentAddresses(std::set<libzcash::SproutPaymentAddress> &setAddress) const
|
||||||
{
|
{
|
||||||
setAddress.clear();
|
setAddress.clear();
|
||||||
{
|
{
|
||||||
|
@ -183,14 +183,14 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool AddViewingKey(const libzcash::ViewingKey &vk);
|
virtual bool AddViewingKey(const libzcash::SproutViewingKey &vk);
|
||||||
virtual bool RemoveViewingKey(const libzcash::ViewingKey &vk);
|
virtual bool RemoveViewingKey(const libzcash::SproutViewingKey &vk);
|
||||||
virtual bool HaveViewingKey(const libzcash::PaymentAddress &address) const;
|
virtual bool HaveViewingKey(const libzcash::SproutPaymentAddress &address) const;
|
||||||
virtual bool GetViewingKey(const libzcash::PaymentAddress &address, libzcash::ViewingKey& vkOut) const;
|
virtual bool GetViewingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutViewingKey& vkOut) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;
|
typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;
|
||||||
typedef std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char> > > CryptedKeyMap;
|
typedef std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char> > > CryptedKeyMap;
|
||||||
typedef std::map<libzcash::PaymentAddress, std::vector<unsigned char> > CryptedSpendingKeyMap;
|
typedef std::map<libzcash::SproutPaymentAddress, std::vector<unsigned char> > CryptedSpendingKeyMap;
|
||||||
|
|
||||||
#endif // BITCOIN_KEYSTORE_H
|
#endif // BITCOIN_KEYSTORE_H
|
||||||
|
|
|
@ -38,12 +38,12 @@ struct PaymentDisclosureInfo {
|
||||||
uint256 joinSplitPrivKey; // primitives/transaction.h
|
uint256 joinSplitPrivKey; // primitives/transaction.h
|
||||||
// ed25519 - not tied to implementation e.g. libsodium, see ed25519 rfc
|
// ed25519 - not tied to implementation e.g. libsodium, see ed25519 rfc
|
||||||
|
|
||||||
libzcash::PaymentAddress zaddr;
|
libzcash::SproutPaymentAddress zaddr;
|
||||||
|
|
||||||
PaymentDisclosureInfo() : version(PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL) {
|
PaymentDisclosureInfo() : version(PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL) {
|
||||||
}
|
}
|
||||||
|
|
||||||
PaymentDisclosureInfo(uint8_t v, uint256 esk, uint256 key, libzcash::PaymentAddress zaddr) : version(v), esk(esk), joinSplitPrivKey(key), zaddr(zaddr) { }
|
PaymentDisclosureInfo(uint8_t v, uint256 esk, uint256 key, libzcash::SproutPaymentAddress zaddr) : version(v), esk(esk), joinSplitPrivKey(key), zaddr(zaddr) { }
|
||||||
|
|
||||||
ADD_SERIALIZE_METHODS;
|
ADD_SERIALIZE_METHODS;
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ struct PaymentDisclosurePayload {
|
||||||
uint256 txid; // primitives/transaction.h
|
uint256 txid; // primitives/transaction.h
|
||||||
uint64_t js; // Index into CTransaction.vjoinsplit
|
uint64_t js; // Index into CTransaction.vjoinsplit
|
||||||
uint8_t n; // Index into JSDescription fields of length ZC_NUM_JS_OUTPUTS
|
uint8_t n; // Index into JSDescription fields of length ZC_NUM_JS_OUTPUTS
|
||||||
libzcash::PaymentAddress zaddr; // zcash/Address.hpp
|
libzcash::SproutPaymentAddress zaddr; // zcash/Address.hpp
|
||||||
std::string message; // parameter to RPC call
|
std::string message; // parameter to RPC call
|
||||||
|
|
||||||
ADD_SERIALIZE_METHODS;
|
ADD_SERIALIZE_METHODS;
|
||||||
|
|
|
@ -239,9 +239,12 @@ UniValue z_validateaddress(const UniValue& params, bool fHelp)
|
||||||
std::string payingKey, transmissionKey;
|
std::string payingKey, transmissionKey;
|
||||||
|
|
||||||
string strAddress = params[0].get_str();
|
string strAddress = params[0].get_str();
|
||||||
auto isValid = DecodePaymentAddress(strAddress);
|
auto address = DecodePaymentAddress(strAddress);
|
||||||
|
bool isValid = IsValidPaymentAddress(address);
|
||||||
if (isValid) {
|
if (isValid) {
|
||||||
libzcash::PaymentAddress addr = *isValid;
|
// TODO: Add Sapling support
|
||||||
|
assert(boost::get<libzcash::SproutPaymentAddress>(&address) != nullptr);
|
||||||
|
libzcash::SproutPaymentAddress addr = boost::get<libzcash::SproutPaymentAddress>(address);
|
||||||
|
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
isMine = pwalletMain->HaveSpendingKey(addr);
|
isMine = pwalletMain->HaveSpendingKey(addr);
|
||||||
|
|
|
@ -247,8 +247,8 @@ public:
|
||||||
|
|
||||||
uint256 appendRandomCommitment(ZCIncrementalMerkleTree &tree)
|
uint256 appendRandomCommitment(ZCIncrementalMerkleTree &tree)
|
||||||
{
|
{
|
||||||
libzcash::SpendingKey k = libzcash::SpendingKey::random();
|
libzcash::SproutSpendingKey k = libzcash::SproutSpendingKey::random();
|
||||||
libzcash::PaymentAddress addr = k.address();
|
libzcash::SproutPaymentAddress addr = k.address();
|
||||||
|
|
||||||
libzcash::SproutNote note(addr.a_pk, 0, uint256(), uint256());
|
libzcash::SproutNote note(addr.a_pk, 0, uint256(), uint256());
|
||||||
|
|
||||||
|
|
|
@ -188,7 +188,7 @@ BOOST_AUTO_TEST_CASE(key_test1)
|
||||||
BOOST_AUTO_TEST_CASE(zc_address_test)
|
BOOST_AUTO_TEST_CASE(zc_address_test)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < 1000; i++) {
|
for (size_t i = 0; i < 1000; i++) {
|
||||||
auto sk = SpendingKey::random();
|
auto sk = SproutSpendingKey::random();
|
||||||
{
|
{
|
||||||
string sk_string = EncodeSpendingKey(sk);
|
string sk_string = EncodeSpendingKey(sk);
|
||||||
|
|
||||||
|
@ -196,8 +196,9 @@ BOOST_AUTO_TEST_CASE(zc_address_test)
|
||||||
BOOST_CHECK(sk_string[1] == 'K');
|
BOOST_CHECK(sk_string[1] == 'K');
|
||||||
|
|
||||||
auto spendingkey2 = DecodeSpendingKey(sk_string);
|
auto spendingkey2 = DecodeSpendingKey(sk_string);
|
||||||
BOOST_ASSERT(static_cast<bool>(spendingkey2));
|
BOOST_CHECK(IsValidSpendingKey(spendingkey2));
|
||||||
SpendingKey sk2 = *spendingkey2;
|
BOOST_ASSERT(boost::get<SproutSpendingKey>(&spendingkey2) != nullptr);
|
||||||
|
auto sk2 = boost::get<SproutSpendingKey>(spendingkey2);
|
||||||
BOOST_CHECK(sk.inner() == sk2.inner());
|
BOOST_CHECK(sk.inner() == sk2.inner());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
@ -209,9 +210,10 @@ BOOST_AUTO_TEST_CASE(zc_address_test)
|
||||||
BOOST_CHECK(addr_string[1] == 'c');
|
BOOST_CHECK(addr_string[1] == 'c');
|
||||||
|
|
||||||
auto paymentaddr2 = DecodePaymentAddress(addr_string);
|
auto paymentaddr2 = DecodePaymentAddress(addr_string);
|
||||||
BOOST_ASSERT(static_cast<bool>(paymentaddr2));
|
BOOST_ASSERT(IsValidPaymentAddress(paymentaddr2));
|
||||||
|
|
||||||
PaymentAddress addr2 = *paymentaddr2;
|
BOOST_ASSERT(boost::get<SproutPaymentAddress>(&paymentaddr2) != nullptr);
|
||||||
|
auto addr2 = boost::get<SproutPaymentAddress>(paymentaddr2);
|
||||||
BOOST_CHECK(addr.a_pk == addr2.a_pk);
|
BOOST_CHECK(addr.a_pk == addr2.a_pk);
|
||||||
BOOST_CHECK(addr.pk_enc == addr2.pk_enc);
|
BOOST_CHECK(addr.pk_enc == addr2.pk_enc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -343,7 +343,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_validateaddress)
|
||||||
BOOST_CHECK_THROW(CallRPC("z_validateaddress toomany args"), runtime_error);
|
BOOST_CHECK_THROW(CallRPC("z_validateaddress toomany args"), runtime_error);
|
||||||
|
|
||||||
// Wallet should be empty
|
// Wallet should be empty
|
||||||
std::set<libzcash::PaymentAddress> addrs;
|
std::set<libzcash::SproutPaymentAddress> addrs;
|
||||||
pwalletMain->GetPaymentAddresses(addrs);
|
pwalletMain->GetPaymentAddresses(addrs);
|
||||||
BOOST_CHECK(addrs.size()==0);
|
BOOST_CHECK(addrs.size()==0);
|
||||||
|
|
||||||
|
@ -381,12 +381,15 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_exportwallet)
|
||||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||||
|
|
||||||
// wallet should be empty
|
// wallet should be empty
|
||||||
std::set<libzcash::PaymentAddress> addrs;
|
std::set<libzcash::SproutPaymentAddress> addrs;
|
||||||
pwalletMain->GetPaymentAddresses(addrs);
|
pwalletMain->GetPaymentAddresses(addrs);
|
||||||
BOOST_CHECK(addrs.size()==0);
|
BOOST_CHECK(addrs.size()==0);
|
||||||
|
|
||||||
// wallet should have one key
|
// wallet should have one key
|
||||||
auto addr = pwalletMain->GenerateNewZKey();
|
auto address = pwalletMain->GenerateNewZKey();
|
||||||
|
BOOST_CHECK(IsValidPaymentAddress(address));
|
||||||
|
BOOST_ASSERT(boost::get<libzcash::SproutPaymentAddress>(&address) != nullptr);
|
||||||
|
auto addr = boost::get<libzcash::SproutPaymentAddress>(address);
|
||||||
pwalletMain->GetPaymentAddresses(addrs);
|
pwalletMain->GetPaymentAddresses(addrs);
|
||||||
BOOST_CHECK(addrs.size()==1);
|
BOOST_CHECK(addrs.size()==1);
|
||||||
|
|
||||||
|
@ -411,7 +414,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_exportwallet)
|
||||||
BOOST_CHECK_NO_THROW(CallRPC(string("z_exportwallet ") + tmpfilename.string()));
|
BOOST_CHECK_NO_THROW(CallRPC(string("z_exportwallet ") + tmpfilename.string()));
|
||||||
|
|
||||||
|
|
||||||
libzcash::SpendingKey key;
|
libzcash::SproutSpendingKey key;
|
||||||
BOOST_CHECK(pwalletMain->GetSpendingKey(addr, key));
|
BOOST_CHECK(pwalletMain->GetSpendingKey(addr, key));
|
||||||
|
|
||||||
std::string s1 = EncodePaymentAddress(addr);
|
std::string s1 = EncodePaymentAddress(addr);
|
||||||
|
@ -456,7 +459,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importwallet)
|
||||||
BOOST_CHECK_THROW(CallRPC("z_importwallet toomany args"), runtime_error);
|
BOOST_CHECK_THROW(CallRPC("z_importwallet toomany args"), runtime_error);
|
||||||
|
|
||||||
// create a random key locally
|
// create a random key locally
|
||||||
auto testSpendingKey = libzcash::SpendingKey::random();
|
auto testSpendingKey = libzcash::SproutSpendingKey::random();
|
||||||
auto testPaymentAddress = testSpendingKey.address();
|
auto testPaymentAddress = testSpendingKey.address();
|
||||||
std::string testAddr = EncodePaymentAddress(testPaymentAddress);
|
std::string testAddr = EncodePaymentAddress(testPaymentAddress);
|
||||||
std::string testKey = EncodeSpendingKey(testSpendingKey);
|
std::string testKey = EncodeSpendingKey(testSpendingKey);
|
||||||
|
@ -485,7 +488,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importwallet)
|
||||||
file << std::flush;
|
file << std::flush;
|
||||||
|
|
||||||
// wallet should currently be empty
|
// wallet should currently be empty
|
||||||
std::set<libzcash::PaymentAddress> addrs;
|
std::set<libzcash::SproutPaymentAddress> addrs;
|
||||||
pwalletMain->GetPaymentAddresses(addrs);
|
pwalletMain->GetPaymentAddresses(addrs);
|
||||||
BOOST_CHECK(addrs.size()==0);
|
BOOST_CHECK(addrs.size()==0);
|
||||||
|
|
||||||
|
@ -497,11 +500,14 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importwallet)
|
||||||
BOOST_CHECK(addrs.size()==1);
|
BOOST_CHECK(addrs.size()==1);
|
||||||
|
|
||||||
// check that we have the spending key for the address
|
// check that we have the spending key for the address
|
||||||
auto addr = *DecodePaymentAddress(testAddr);
|
auto address = DecodePaymentAddress(testAddr);
|
||||||
|
BOOST_CHECK(IsValidPaymentAddress(address));
|
||||||
|
BOOST_ASSERT(boost::get<libzcash::SproutPaymentAddress>(&address) != nullptr);
|
||||||
|
auto addr = boost::get<libzcash::SproutPaymentAddress>(address);
|
||||||
BOOST_CHECK(pwalletMain->HaveSpendingKey(addr));
|
BOOST_CHECK(pwalletMain->HaveSpendingKey(addr));
|
||||||
|
|
||||||
// Verify the spending key is the same as the test data
|
// Verify the spending key is the same as the test data
|
||||||
libzcash::SpendingKey k;
|
libzcash::SproutSpendingKey k;
|
||||||
BOOST_CHECK(pwalletMain->GetSpendingKey(addr, k));
|
BOOST_CHECK(pwalletMain->GetSpendingKey(addr, k));
|
||||||
BOOST_CHECK_EQUAL(testKey, EncodeSpendingKey(k));
|
BOOST_CHECK_EQUAL(testKey, EncodeSpendingKey(k));
|
||||||
}
|
}
|
||||||
|
@ -526,7 +532,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport)
|
||||||
BOOST_CHECK_THROW(CallRPC("z_exportkey toomany args"), runtime_error);
|
BOOST_CHECK_THROW(CallRPC("z_exportkey toomany args"), runtime_error);
|
||||||
|
|
||||||
// error if invalid args
|
// error if invalid args
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
std::string prefix = std::string("z_importkey ") + EncodeSpendingKey(sk) + " yes ";
|
std::string prefix = std::string("z_importkey ") + EncodeSpendingKey(sk) + " yes ";
|
||||||
BOOST_CHECK_THROW(CallRPC(prefix + "-1"), runtime_error);
|
BOOST_CHECK_THROW(CallRPC(prefix + "-1"), runtime_error);
|
||||||
BOOST_CHECK_THROW(CallRPC(prefix + "2147483647"), runtime_error); // allowed, but > height of active chain tip
|
BOOST_CHECK_THROW(CallRPC(prefix + "2147483647"), runtime_error); // allowed, but > height of active chain tip
|
||||||
|
@ -534,14 +540,14 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport)
|
||||||
BOOST_CHECK_THROW(CallRPC(prefix + "100badchars"), runtime_error);
|
BOOST_CHECK_THROW(CallRPC(prefix + "100badchars"), runtime_error);
|
||||||
|
|
||||||
// wallet should currently be empty
|
// wallet should currently be empty
|
||||||
std::set<libzcash::PaymentAddress> addrs;
|
std::set<libzcash::SproutPaymentAddress> addrs;
|
||||||
pwalletMain->GetPaymentAddresses(addrs);
|
pwalletMain->GetPaymentAddresses(addrs);
|
||||||
BOOST_CHECK(addrs.size()==0);
|
BOOST_CHECK(addrs.size()==0);
|
||||||
|
|
||||||
// verify import and export key
|
// verify import and export key
|
||||||
for (int i = 0; i < n1; i++) {
|
for (int i = 0; i < n1; i++) {
|
||||||
// create a random key locally
|
// create a random key locally
|
||||||
auto testSpendingKey = libzcash::SpendingKey::random();
|
auto testSpendingKey = libzcash::SproutSpendingKey::random();
|
||||||
auto testPaymentAddress = testSpendingKey.address();
|
auto testPaymentAddress = testSpendingKey.address();
|
||||||
std::string testAddr = EncodePaymentAddress(testPaymentAddress);
|
std::string testAddr = EncodePaymentAddress(testPaymentAddress);
|
||||||
std::string testKey = EncodeSpendingKey(testSpendingKey);
|
std::string testKey = EncodeSpendingKey(testSpendingKey);
|
||||||
|
@ -590,7 +596,10 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport)
|
||||||
// Add one more address
|
// Add one more address
|
||||||
BOOST_CHECK_NO_THROW(retValue = CallRPC("z_getnewaddress"));
|
BOOST_CHECK_NO_THROW(retValue = CallRPC("z_getnewaddress"));
|
||||||
std::string newaddress = retValue.get_str();
|
std::string newaddress = retValue.get_str();
|
||||||
auto newAddr = *DecodePaymentAddress(newaddress);
|
auto address = DecodePaymentAddress(newaddress);
|
||||||
|
BOOST_CHECK(IsValidPaymentAddress(address));
|
||||||
|
BOOST_ASSERT(boost::get<libzcash::SproutPaymentAddress>(&address) != nullptr);
|
||||||
|
auto newAddr = boost::get<libzcash::SproutPaymentAddress>(address);
|
||||||
BOOST_CHECK(pwalletMain->HaveSpendingKey(newAddr));
|
BOOST_CHECK(pwalletMain->HaveSpendingKey(newAddr));
|
||||||
|
|
||||||
// Check if too many args
|
// Check if too many args
|
||||||
|
@ -1217,7 +1226,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_encrypted_wallet_zkeys)
|
||||||
int n = 100;
|
int n = 100;
|
||||||
|
|
||||||
// wallet should currently be empty
|
// wallet should currently be empty
|
||||||
std::set<libzcash::PaymentAddress> addrs;
|
std::set<libzcash::SproutPaymentAddress> addrs;
|
||||||
pwalletMain->GetPaymentAddresses(addrs);
|
pwalletMain->GetPaymentAddresses(addrs);
|
||||||
BOOST_CHECK(addrs.size()==0);
|
BOOST_CHECK(addrs.size()==0);
|
||||||
|
|
||||||
|
|
|
@ -342,8 +342,8 @@ BOOST_AUTO_TEST_CASE(test_basic_joinsplit_verification)
|
||||||
// construct a merkle tree
|
// construct a merkle tree
|
||||||
ZCIncrementalMerkleTree merkleTree;
|
ZCIncrementalMerkleTree merkleTree;
|
||||||
|
|
||||||
libzcash::SpendingKey k = libzcash::SpendingKey::random();
|
auto k = libzcash::SproutSpendingKey::random();
|
||||||
libzcash::PaymentAddress addr = k.address();
|
auto addr = k.address();
|
||||||
|
|
||||||
libzcash::SproutNote note(addr.a_pk, 100, uint256(), uint256());
|
libzcash::SproutNote note(addr.a_pk, 100, uint256(), uint256());
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include "consensus/upgrades.h"
|
#include "consensus/upgrades.h"
|
||||||
|
|
||||||
CWalletTx GetValidReceive(ZCJoinSplit& params,
|
CWalletTx GetValidReceive(ZCJoinSplit& params,
|
||||||
const libzcash::SpendingKey& sk, CAmount value,
|
const libzcash::SproutSpendingKey& sk, CAmount value,
|
||||||
bool randomInputs) {
|
bool randomInputs) {
|
||||||
CMutableTransaction mtx;
|
CMutableTransaction mtx;
|
||||||
mtx.nVersion = 2; // Enable JoinSplits
|
mtx.nVersion = 2; // Enable JoinSplits
|
||||||
|
@ -62,7 +62,7 @@ CWalletTx GetValidReceive(ZCJoinSplit& params,
|
||||||
}
|
}
|
||||||
|
|
||||||
libzcash::SproutNote GetNote(ZCJoinSplit& params,
|
libzcash::SproutNote GetNote(ZCJoinSplit& params,
|
||||||
const libzcash::SpendingKey& sk,
|
const libzcash::SproutSpendingKey& sk,
|
||||||
const CTransaction& tx, size_t js, size_t n) {
|
const CTransaction& tx, size_t js, size_t n) {
|
||||||
ZCNoteDecryption decryptor {sk.receiving_key()};
|
ZCNoteDecryption decryptor {sk.receiving_key()};
|
||||||
auto hSig = tx.vjoinsplit[js].h_sig(params, tx.joinSplitPubKey);
|
auto hSig = tx.vjoinsplit[js].h_sig(params, tx.joinSplitPubKey);
|
||||||
|
@ -76,7 +76,7 @@ libzcash::SproutNote GetNote(ZCJoinSplit& params,
|
||||||
}
|
}
|
||||||
|
|
||||||
CWalletTx GetValidSpend(ZCJoinSplit& params,
|
CWalletTx GetValidSpend(ZCJoinSplit& params,
|
||||||
const libzcash::SpendingKey& sk,
|
const libzcash::SproutSpendingKey& sk,
|
||||||
const libzcash::SproutNote& note, CAmount value) {
|
const libzcash::SproutNote& note, CAmount value) {
|
||||||
CMutableTransaction mtx;
|
CMutableTransaction mtx;
|
||||||
mtx.vout.resize(2);
|
mtx.vout.resize(2);
|
||||||
|
@ -97,12 +97,12 @@ CWalletTx GetValidSpend(ZCJoinSplit& params,
|
||||||
|
|
||||||
{
|
{
|
||||||
if (note.value() > value) {
|
if (note.value() > value) {
|
||||||
libzcash::SpendingKey dummykey = libzcash::SpendingKey::random();
|
libzcash::SproutSpendingKey dummykey = libzcash::SproutSpendingKey::random();
|
||||||
libzcash::PaymentAddress dummyaddr = dummykey.address();
|
libzcash::SproutPaymentAddress dummyaddr = dummykey.address();
|
||||||
dummyout = libzcash::JSOutput(dummyaddr, note.value() - value);
|
dummyout = libzcash::JSOutput(dummyaddr, note.value() - value);
|
||||||
} else if (note.value() < value) {
|
} else if (note.value() < value) {
|
||||||
libzcash::SpendingKey dummykey = libzcash::SpendingKey::random();
|
libzcash::SproutSpendingKey dummykey = libzcash::SproutSpendingKey::random();
|
||||||
libzcash::PaymentAddress dummyaddr = dummykey.address();
|
libzcash::SproutPaymentAddress 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());
|
tree.append(dummynote.cm());
|
||||||
dummyin = libzcash::JSInput(tree.witness(), dummynote, dummykey);
|
dummyin = libzcash::JSInput(tree.witness(), dummynote, dummykey);
|
||||||
|
|
|
@ -8,11 +8,11 @@
|
||||||
#include "zcash/NoteEncryption.hpp"
|
#include "zcash/NoteEncryption.hpp"
|
||||||
|
|
||||||
CWalletTx GetValidReceive(ZCJoinSplit& params,
|
CWalletTx GetValidReceive(ZCJoinSplit& params,
|
||||||
const libzcash::SpendingKey& sk, CAmount value,
|
const libzcash::SproutSpendingKey& sk, CAmount value,
|
||||||
bool randomInputs);
|
bool randomInputs);
|
||||||
libzcash::SproutNote GetNote(ZCJoinSplit& params,
|
libzcash::SproutNote GetNote(ZCJoinSplit& params,
|
||||||
const libzcash::SpendingKey& sk,
|
const libzcash::SproutSpendingKey& sk,
|
||||||
const CTransaction& tx, size_t js, size_t n);
|
const CTransaction& tx, size_t js, size_t n);
|
||||||
CWalletTx GetValidSpend(ZCJoinSplit& params,
|
CWalletTx GetValidSpend(ZCJoinSplit& params,
|
||||||
const libzcash::SpendingKey& sk,
|
const libzcash::SproutSpendingKey& sk,
|
||||||
const libzcash::SproutNote& note, CAmount value);
|
const libzcash::SproutNote& note, CAmount value);
|
||||||
|
|
|
@ -80,9 +80,11 @@ AsyncRPCOperation_mergetoaddress::AsyncRPCOperation_mergetoaddress(
|
||||||
|
|
||||||
if (!isToTaddr_) {
|
if (!isToTaddr_) {
|
||||||
auto address = DecodePaymentAddress(std::get<0>(recipient));
|
auto address = DecodePaymentAddress(std::get<0>(recipient));
|
||||||
if (address) {
|
if (IsValidPaymentAddress(address)) {
|
||||||
isToZaddr_ = true;
|
isToZaddr_ = true;
|
||||||
toPaymentAddress_ = *address;
|
// TODO: Add Sapling support. For now, ensure we can later convert freely.
|
||||||
|
assert(boost::get<libzcash::SproutPaymentAddress>(&address) != nullptr);
|
||||||
|
toPaymentAddress_ = address;
|
||||||
} else {
|
} else {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid recipient address");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid recipient address");
|
||||||
}
|
}
|
||||||
|
@ -307,7 +309,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
|
||||||
info.vpub_old = sendAmount;
|
info.vpub_old = sendAmount;
|
||||||
info.vpub_new = 0;
|
info.vpub_new = 0;
|
||||||
|
|
||||||
JSOutput jso = JSOutput(toPaymentAddress_, sendAmount);
|
JSOutput jso = JSOutput(boost::get<libzcash::SproutPaymentAddress>(toPaymentAddress_), sendAmount);
|
||||||
if (hexMemo.size() > 0) {
|
if (hexMemo.size() > 0) {
|
||||||
jso.memo = get_memo_from_hex_string(hexMemo);
|
jso.memo = get_memo_from_hex_string(hexMemo);
|
||||||
}
|
}
|
||||||
|
@ -326,6 +328,8 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
|
||||||
// Copy zinputs to more flexible containers
|
// Copy zinputs to more flexible containers
|
||||||
std::deque<MergeToAddressInputNote> zInputsDeque;
|
std::deque<MergeToAddressInputNote> zInputsDeque;
|
||||||
for (auto o : noteInputs_) {
|
for (auto o : noteInputs_) {
|
||||||
|
// TODO: Add Sapling support. For now, ensure we can later convert freely.
|
||||||
|
assert(boost::get<libzcash::SproutSpendingKey>(&std::get<3>(o)) != nullptr);
|
||||||
zInputsDeque.push_back(o);
|
zInputsDeque.push_back(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,8 +369,8 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
|
||||||
|
|
||||||
// At this point, we are guaranteed to have at least one input note.
|
// At this point, we are guaranteed to have at least one input note.
|
||||||
// Use address of first input note as the temporary change address.
|
// Use address of first input note as the temporary change address.
|
||||||
SpendingKey changeKey = std::get<3>(zInputsDeque.front());
|
SproutSpendingKey changeKey = boost::get<libzcash::SproutSpendingKey>(std::get<3>(zInputsDeque.front()));
|
||||||
PaymentAddress changeAddress = changeKey.address();
|
SproutPaymentAddress changeAddress = changeKey.address();
|
||||||
|
|
||||||
CAmount vpubOldTarget = 0;
|
CAmount vpubOldTarget = 0;
|
||||||
CAmount vpubNewTarget = 0;
|
CAmount vpubNewTarget = 0;
|
||||||
|
@ -481,7 +485,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
|
||||||
// Consume spendable non-change notes
|
// Consume spendable non-change notes
|
||||||
//
|
//
|
||||||
std::vector<SproutNote> vInputNotes;
|
std::vector<SproutNote> vInputNotes;
|
||||||
std::vector<SpendingKey> vInputZKeys;
|
std::vector<SproutSpendingKey> vInputZKeys;
|
||||||
std::vector<JSOutPoint> vOutPoints;
|
std::vector<JSOutPoint> vOutPoints;
|
||||||
std::vector<boost::optional<ZCIncrementalWitness>> vInputWitnesses;
|
std::vector<boost::optional<ZCIncrementalWitness>> vInputWitnesses;
|
||||||
uint256 inputAnchor;
|
uint256 inputAnchor;
|
||||||
|
@ -491,7 +495,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
|
||||||
JSOutPoint jso = std::get<0>(t);
|
JSOutPoint jso = std::get<0>(t);
|
||||||
SproutNote note = std::get<1>(t);
|
SproutNote note = std::get<1>(t);
|
||||||
CAmount noteFunds = std::get<2>(t);
|
CAmount noteFunds = std::get<2>(t);
|
||||||
SpendingKey zkey = std::get<3>(t);
|
SproutSpendingKey zkey = boost::get<libzcash::SproutSpendingKey>(std::get<3>(t));
|
||||||
zInputsDeque.pop_front();
|
zInputsDeque.pop_front();
|
||||||
|
|
||||||
MergeToAddressWitnessAnchorData wad = jsopWitnessAnchorMap[jso.ToString()];
|
MergeToAddressWitnessAnchorData wad = jsopWitnessAnchorMap[jso.ToString()];
|
||||||
|
@ -590,7 +594,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
|
||||||
// If this is the final output, set the target and memo
|
// If this is the final output, set the target and memo
|
||||||
if (isToZaddr_ && vpubNewProcessed) {
|
if (isToZaddr_ && vpubNewProcessed) {
|
||||||
outputType = "target";
|
outputType = "target";
|
||||||
jso.addr = toPaymentAddress_;
|
jso.addr = boost::get<libzcash::SproutPaymentAddress>(toPaymentAddress_);
|
||||||
if (!hexMemo.empty()) {
|
if (!hexMemo.empty()) {
|
||||||
jso.memo = get_memo_from_hex_string(hexMemo);
|
jso.memo = get_memo_from_hex_string(hexMemo);
|
||||||
}
|
}
|
||||||
|
@ -852,7 +856,7 @@ UniValue AsyncRPCOperation_mergetoaddress::perform_joinsplit(
|
||||||
// placeholder for txid will be filled in later when tx has been finalized and signed.
|
// placeholder for txid will be filled in later when tx has been finalized and signed.
|
||||||
PaymentDisclosureKey pdKey = {placeholder, js_index, mapped_index};
|
PaymentDisclosureKey pdKey = {placeholder, js_index, mapped_index};
|
||||||
JSOutput output = outputs[mapped_index];
|
JSOutput output = outputs[mapped_index];
|
||||||
libzcash::PaymentAddress zaddr = output.addr; // randomized output
|
libzcash::SproutPaymentAddress zaddr = output.addr; // randomized output
|
||||||
PaymentDisclosureInfo pdInfo = {PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL, esk, joinSplitPrivKey, zaddr};
|
PaymentDisclosureInfo pdInfo = {PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL, esk, joinSplitPrivKey, zaddr};
|
||||||
paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo));
|
paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo));
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ struct MergeToAddressJSInfo {
|
||||||
std::vector<JSInput> vjsin;
|
std::vector<JSInput> vjsin;
|
||||||
std::vector<JSOutput> vjsout;
|
std::vector<JSOutput> vjsout;
|
||||||
std::vector<SproutNote> notes;
|
std::vector<SproutNote> notes;
|
||||||
std::vector<SpendingKey> zkeys;
|
std::vector<SproutSpendingKey> zkeys;
|
||||||
CAmount vpub_old = 0;
|
CAmount vpub_old = 0;
|
||||||
CAmount vpub_new = 0;
|
CAmount vpub_new = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -81,11 +81,13 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany(
|
||||||
|
|
||||||
if (!isfromtaddr_) {
|
if (!isfromtaddr_) {
|
||||||
auto address = DecodePaymentAddress(fromAddress);
|
auto address = DecodePaymentAddress(fromAddress);
|
||||||
if (address) {
|
if (IsValidPaymentAddress(address)) {
|
||||||
PaymentAddress addr = *address;
|
// TODO: Add Sapling support. For now, ensure we can freely convert.
|
||||||
|
assert(boost::get<libzcash::SproutPaymentAddress>(&address) != nullptr);
|
||||||
|
SproutPaymentAddress addr = boost::get<libzcash::SproutPaymentAddress>(address);
|
||||||
|
|
||||||
// We don't need to lock on the wallet as spending key related methods are thread-safe
|
// We don't need to lock on the wallet as spending key related methods are thread-safe
|
||||||
SpendingKey key;
|
SproutSpendingKey key;
|
||||||
if (!pwalletMain->GetSpendingKey(addr, key)) {
|
if (!pwalletMain->GetSpendingKey(addr, key)) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid from address, no spending key found for zaddr");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid from address, no spending key found for zaddr");
|
||||||
}
|
}
|
||||||
|
@ -401,6 +403,9 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
||||||
}
|
}
|
||||||
std::deque<SendManyRecipient> zOutputsDeque;
|
std::deque<SendManyRecipient> zOutputsDeque;
|
||||||
for (auto o : z_outputs_) {
|
for (auto o : z_outputs_) {
|
||||||
|
// TODO: Add Sapling support. For now, ensure we can later convert freely.
|
||||||
|
auto addr = DecodePaymentAddress(std::get<0>(o));
|
||||||
|
assert(boost::get<libzcash::SproutPaymentAddress>(&addr) != nullptr);
|
||||||
zOutputsDeque.push_back(o);
|
zOutputsDeque.push_back(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -468,8 +473,8 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
||||||
std::string hexMemo = std::get<2>(smr);
|
std::string hexMemo = std::get<2>(smr);
|
||||||
zOutputsDeque.pop_front();
|
zOutputsDeque.pop_front();
|
||||||
|
|
||||||
PaymentAddress pa = *DecodePaymentAddress(address);
|
PaymentAddress pa = DecodePaymentAddress(address);
|
||||||
JSOutput jso = JSOutput(pa, value);
|
JSOutput jso = JSOutput(boost::get<libzcash::SproutPaymentAddress>(pa), value);
|
||||||
if (hexMemo.size() > 0) {
|
if (hexMemo.size() > 0) {
|
||||||
jso.memo = get_memo_from_hex_string(hexMemo);
|
jso.memo = get_memo_from_hex_string(hexMemo);
|
||||||
}
|
}
|
||||||
|
@ -569,7 +574,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
||||||
intermediates.insert(std::make_pair(tree.root(), tree)); // chained js are interstitial (found in between block boundaries)
|
intermediates.insert(std::make_pair(tree.root(), tree)); // chained js are interstitial (found in between block boundaries)
|
||||||
|
|
||||||
// Decrypt the change note's ciphertext to retrieve some data we need
|
// Decrypt the change note's ciphertext to retrieve some data we need
|
||||||
ZCNoteDecryption decryptor(spendingkey_.receiving_key());
|
ZCNoteDecryption decryptor(boost::get<libzcash::SproutSpendingKey>(spendingkey_).receiving_key());
|
||||||
auto hSig = prevJoinSplit.h_sig(*pzcashParams, tx_.joinSplitPubKey);
|
auto hSig = prevJoinSplit.h_sig(*pzcashParams, tx_.joinSplitPubKey);
|
||||||
try {
|
try {
|
||||||
SproutNotePlaintext plaintext = SproutNotePlaintext::decrypt(
|
SproutNotePlaintext plaintext = SproutNotePlaintext::decrypt(
|
||||||
|
@ -579,7 +584,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
||||||
hSig,
|
hSig,
|
||||||
(unsigned char) changeOutputIndex);
|
(unsigned char) changeOutputIndex);
|
||||||
|
|
||||||
SproutNote note = plaintext.note(frompaymentaddress_);
|
SproutNote note = plaintext.note(boost::get<libzcash::SproutPaymentAddress>(frompaymentaddress_));
|
||||||
info.notes.push_back(note);
|
info.notes.push_back(note);
|
||||||
|
|
||||||
jsInputValue += plaintext.value();
|
jsInputValue += plaintext.value();
|
||||||
|
@ -727,8 +732,8 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
||||||
assert(value==0);
|
assert(value==0);
|
||||||
info.vjsout.push_back(JSOutput()); // dummy output while we accumulate funds into a change note for vpub_new
|
info.vjsout.push_back(JSOutput()); // dummy output while we accumulate funds into a change note for vpub_new
|
||||||
} else {
|
} else {
|
||||||
PaymentAddress pa = *DecodePaymentAddress(address);
|
PaymentAddress pa = DecodePaymentAddress(address);
|
||||||
JSOutput jso = JSOutput(pa, value);
|
JSOutput jso = JSOutput(boost::get<libzcash::SproutPaymentAddress>(pa), value);
|
||||||
if (hexMemo.size() > 0) {
|
if (hexMemo.size() > 0) {
|
||||||
jso.memo = get_memo_from_hex_string(hexMemo);
|
jso.memo = get_memo_from_hex_string(hexMemo);
|
||||||
}
|
}
|
||||||
|
@ -737,7 +742,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
||||||
|
|
||||||
// create output for any change
|
// create output for any change
|
||||||
if (jsChange>0) {
|
if (jsChange>0) {
|
||||||
info.vjsout.push_back(JSOutput(frompaymentaddress_, jsChange));
|
info.vjsout.push_back(JSOutput(boost::get<libzcash::SproutPaymentAddress>(frompaymentaddress_), jsChange));
|
||||||
|
|
||||||
LogPrint("zrpcunsafe", "%s: generating note for change (amount=%s)\n",
|
LogPrint("zrpcunsafe", "%s: generating note for change (amount=%s)\n",
|
||||||
getId(),
|
getId(),
|
||||||
|
@ -886,7 +891,7 @@ bool AsyncRPCOperation_sendmany::find_unspent_notes() {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (CSproutNotePlaintextEntry & entry : entries) {
|
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(boost::get<libzcash::SproutPaymentAddress>(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",
|
LogPrint("zrpcunsafe", "%s: found unspent note (txid=%s, vjoinsplit=%d, ciphertext=%d, amount=%s, memo=%s)\n",
|
||||||
getId(),
|
getId(),
|
||||||
|
@ -948,7 +953,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit(
|
||||||
if (!witnesses[i]) {
|
if (!witnesses[i]) {
|
||||||
throw runtime_error("joinsplit input could not be found in tree");
|
throw runtime_error("joinsplit input could not be found in tree");
|
||||||
}
|
}
|
||||||
info.vjsin.push_back(JSInput(*witnesses[i], info.notes[i], spendingkey_));
|
info.vjsin.push_back(JSInput(*witnesses[i], info.notes[i], boost::get<libzcash::SproutSpendingKey>(spendingkey_)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure there are two inputs and two outputs
|
// Make sure there are two inputs and two outputs
|
||||||
|
@ -1077,7 +1082,7 @@ UniValue AsyncRPCOperation_sendmany::perform_joinsplit(
|
||||||
// placeholder for txid will be filled in later when tx has been finalized and signed.
|
// placeholder for txid will be filled in later when tx has been finalized and signed.
|
||||||
PaymentDisclosureKey pdKey = {placeholder, js_index, mapped_index};
|
PaymentDisclosureKey pdKey = {placeholder, js_index, mapped_index};
|
||||||
JSOutput output = outputs[mapped_index];
|
JSOutput output = outputs[mapped_index];
|
||||||
libzcash::PaymentAddress zaddr = output.addr; // randomized output
|
libzcash::SproutPaymentAddress zaddr = output.addr; // randomized output
|
||||||
PaymentDisclosureInfo pdInfo = {PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL, esk, joinSplitPrivKey, zaddr};
|
PaymentDisclosureInfo pdInfo = {PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL, esk, joinSplitPrivKey, zaddr};
|
||||||
paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo));
|
paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo));
|
||||||
|
|
||||||
|
|
|
@ -73,8 +73,10 @@ AsyncRPCOperation_shieldcoinbase::AsyncRPCOperation_shieldcoinbase(
|
||||||
|
|
||||||
// Check the destination address is valid for this network i.e. not testnet being used on mainnet
|
// Check the destination address is valid for this network i.e. not testnet being used on mainnet
|
||||||
auto address = DecodePaymentAddress(toAddress);
|
auto address = DecodePaymentAddress(toAddress);
|
||||||
if (address) {
|
if (IsValidPaymentAddress(address)) {
|
||||||
tozaddr_ = *address;
|
// TODO: Add Sapling support. For now, ensure we can freely convert.
|
||||||
|
assert(boost::get<libzcash::SproutPaymentAddress>(&address) != nullptr);
|
||||||
|
tozaddr_ = address;
|
||||||
} else {
|
} else {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid to address");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid to address");
|
||||||
}
|
}
|
||||||
|
@ -233,7 +235,7 @@ bool AsyncRPCOperation_shieldcoinbase::main_impl() {
|
||||||
ShieldCoinbaseJSInfo info;
|
ShieldCoinbaseJSInfo info;
|
||||||
info.vpub_old = sendAmount;
|
info.vpub_old = sendAmount;
|
||||||
info.vpub_new = 0;
|
info.vpub_new = 0;
|
||||||
JSOutput jso = JSOutput(tozaddr_, sendAmount);
|
JSOutput jso = JSOutput(boost::get<libzcash::SproutPaymentAddress>(tozaddr_), sendAmount);
|
||||||
info.vjsout.push_back(jso);
|
info.vjsout.push_back(jso);
|
||||||
obj = perform_joinsplit(info);
|
obj = perform_joinsplit(info);
|
||||||
|
|
||||||
|
@ -448,7 +450,7 @@ UniValue AsyncRPCOperation_shieldcoinbase::perform_joinsplit(ShieldCoinbaseJSInf
|
||||||
// placeholder for txid will be filled in later when tx has been finalized and signed.
|
// placeholder for txid will be filled in later when tx has been finalized and signed.
|
||||||
PaymentDisclosureKey pdKey = {placeholder, js_index, mapped_index};
|
PaymentDisclosureKey pdKey = {placeholder, js_index, mapped_index};
|
||||||
JSOutput output = outputs[mapped_index];
|
JSOutput output = outputs[mapped_index];
|
||||||
libzcash::PaymentAddress zaddr = output.addr; // randomized output
|
libzcash::SproutPaymentAddress zaddr = output.addr; // randomized output
|
||||||
PaymentDisclosureInfo pdInfo = {PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL, esk, joinSplitPrivKey, zaddr};
|
PaymentDisclosureInfo pdInfo = {PAYMENT_DISCLOSURE_VERSION_EXPERIMENTAL, esk, joinSplitPrivKey, zaddr};
|
||||||
paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo));
|
paymentDisclosureData_.push_back(PaymentDisclosureKeyInfo(pdKey, pdInfo));
|
||||||
|
|
||||||
|
|
|
@ -136,8 +136,8 @@ static bool DecryptKey(const CKeyingMaterial& vMasterKey, const std::vector<unsi
|
||||||
|
|
||||||
static bool DecryptSpendingKey(const CKeyingMaterial& vMasterKey,
|
static bool DecryptSpendingKey(const CKeyingMaterial& vMasterKey,
|
||||||
const std::vector<unsigned char>& vchCryptedSecret,
|
const std::vector<unsigned char>& vchCryptedSecret,
|
||||||
const libzcash::PaymentAddress& address,
|
const libzcash::SproutPaymentAddress& address,
|
||||||
libzcash::SpendingKey& sk)
|
libzcash::SproutSpendingKey& sk)
|
||||||
{
|
{
|
||||||
CKeyingMaterial vchSecret;
|
CKeyingMaterial vchSecret;
|
||||||
if(!DecryptSecret(vMasterKey, vchCryptedSecret, address.GetHash(), vchSecret))
|
if(!DecryptSecret(vMasterKey, vchCryptedSecret, address.GetHash(), vchSecret))
|
||||||
|
@ -203,9 +203,9 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
|
||||||
CryptedSpendingKeyMap::const_iterator skmi = mapCryptedSpendingKeys.begin();
|
CryptedSpendingKeyMap::const_iterator skmi = mapCryptedSpendingKeys.begin();
|
||||||
for (; skmi != mapCryptedSpendingKeys.end(); ++skmi)
|
for (; skmi != mapCryptedSpendingKeys.end(); ++skmi)
|
||||||
{
|
{
|
||||||
const libzcash::PaymentAddress &address = (*skmi).first;
|
const libzcash::SproutPaymentAddress &address = (*skmi).first;
|
||||||
const std::vector<unsigned char> &vchCryptedSecret = (*skmi).second;
|
const std::vector<unsigned char> &vchCryptedSecret = (*skmi).second;
|
||||||
libzcash::SpendingKey sk;
|
libzcash::SproutSpendingKey sk;
|
||||||
if (!DecryptSpendingKey(vMasterKeyIn, vchCryptedSecret, address, sk))
|
if (!DecryptSpendingKey(vMasterKeyIn, vchCryptedSecret, address, sk))
|
||||||
{
|
{
|
||||||
keyFail = true;
|
keyFail = true;
|
||||||
|
@ -298,7 +298,7 @@ bool CCryptoKeyStore::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) co
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCryptoKeyStore::AddSpendingKey(const libzcash::SpendingKey &sk)
|
bool CCryptoKeyStore::AddSpendingKey(const libzcash::SproutSpendingKey &sk)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
LOCK(cs_SpendingKeyStore);
|
LOCK(cs_SpendingKeyStore);
|
||||||
|
@ -322,7 +322,7 @@ bool CCryptoKeyStore::AddSpendingKey(const libzcash::SpendingKey &sk)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCryptoKeyStore::AddCryptedSpendingKey(const libzcash::PaymentAddress &address,
|
bool CCryptoKeyStore::AddCryptedSpendingKey(const libzcash::SproutPaymentAddress &address,
|
||||||
const libzcash::ReceivingKey &rk,
|
const libzcash::ReceivingKey &rk,
|
||||||
const std::vector<unsigned char> &vchCryptedSecret)
|
const std::vector<unsigned char> &vchCryptedSecret)
|
||||||
{
|
{
|
||||||
|
@ -337,7 +337,7 @@ bool CCryptoKeyStore::AddCryptedSpendingKey(const libzcash::PaymentAddress &addr
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCryptoKeyStore::GetSpendingKey(const libzcash::PaymentAddress &address, libzcash::SpendingKey &skOut) const
|
bool CCryptoKeyStore::GetSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey &skOut) const
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
LOCK(cs_SpendingKeyStore);
|
LOCK(cs_SpendingKeyStore);
|
||||||
|
@ -376,11 +376,11 @@ bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn)
|
||||||
mapKeys.clear();
|
mapKeys.clear();
|
||||||
BOOST_FOREACH(SpendingKeyMap::value_type& mSpendingKey, mapSpendingKeys)
|
BOOST_FOREACH(SpendingKeyMap::value_type& mSpendingKey, mapSpendingKeys)
|
||||||
{
|
{
|
||||||
const libzcash::SpendingKey &sk = mSpendingKey.second;
|
const libzcash::SproutSpendingKey &sk = mSpendingKey.second;
|
||||||
CSecureDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
CSecureDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||||
ss << sk;
|
ss << sk;
|
||||||
CKeyingMaterial vchSecret(ss.begin(), ss.end());
|
CKeyingMaterial vchSecret(ss.begin(), ss.end());
|
||||||
libzcash::PaymentAddress address = sk.address();
|
libzcash::SproutPaymentAddress address = sk.address();
|
||||||
std::vector<unsigned char> vchCryptedSecret;
|
std::vector<unsigned char> vchCryptedSecret;
|
||||||
if (!EncryptSecret(vMasterKeyIn, vchSecret, address.GetHash(), vchCryptedSecret))
|
if (!EncryptSecret(vMasterKeyIn, vchSecret, address.GetHash(), vchCryptedSecret))
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -200,11 +200,11 @@ public:
|
||||||
mi++;
|
mi++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual bool AddCryptedSpendingKey(const libzcash::PaymentAddress &address,
|
virtual bool AddCryptedSpendingKey(const libzcash::SproutPaymentAddress &address,
|
||||||
const libzcash::ReceivingKey &rk,
|
const libzcash::ReceivingKey &rk,
|
||||||
const std::vector<unsigned char> &vchCryptedSecret);
|
const std::vector<unsigned char> &vchCryptedSecret);
|
||||||
bool AddSpendingKey(const libzcash::SpendingKey &sk);
|
bool AddSpendingKey(const libzcash::SproutSpendingKey &sk);
|
||||||
bool HaveSpendingKey(const libzcash::PaymentAddress &address) const
|
bool HaveSpendingKey(const libzcash::SproutPaymentAddress &address) const
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
LOCK(cs_SpendingKeyStore);
|
LOCK(cs_SpendingKeyStore);
|
||||||
|
@ -214,8 +214,8 @@ public:
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool GetSpendingKey(const libzcash::PaymentAddress &address, libzcash::SpendingKey &skOut) const;
|
bool GetSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey &skOut) const;
|
||||||
void GetPaymentAddresses(std::set<libzcash::PaymentAddress> &setAddress) const
|
void GetPaymentAddresses(std::set<libzcash::SproutPaymentAddress> &setAddress) const
|
||||||
{
|
{
|
||||||
if (!IsCrypted())
|
if (!IsCrypted())
|
||||||
{
|
{
|
||||||
|
|
|
@ -68,22 +68,22 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
CWalletTx GetValidReceive(const libzcash::SpendingKey& sk, CAmount value, bool randomInputs) {
|
CWalletTx GetValidReceive(const libzcash::SproutSpendingKey& sk, CAmount value, bool randomInputs) {
|
||||||
return GetValidReceive(*params, sk, value, randomInputs);
|
return GetValidReceive(*params, sk, value, randomInputs);
|
||||||
}
|
}
|
||||||
|
|
||||||
libzcash::SproutNote GetNote(const libzcash::SpendingKey& sk,
|
libzcash::SproutNote GetNote(const libzcash::SproutSpendingKey& sk,
|
||||||
const CTransaction& tx, size_t js, size_t n) {
|
const CTransaction& tx, size_t js, size_t n) {
|
||||||
return GetNote(*params, sk, tx, js, n);
|
return GetNote(*params, sk, tx, js, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
CWalletTx GetValidSpend(const libzcash::SpendingKey& sk,
|
CWalletTx GetValidSpend(const libzcash::SproutSpendingKey& sk,
|
||||||
const libzcash::SproutNote& note, CAmount value) {
|
const libzcash::SproutNote& note, CAmount value) {
|
||||||
return GetValidSpend(*params, sk, note, value);
|
return GetValidSpend(*params, sk, note, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
JSOutPoint CreateValidBlock(TestWallet& wallet,
|
JSOutPoint CreateValidBlock(TestWallet& wallet,
|
||||||
const libzcash::SpendingKey& sk,
|
const libzcash::SproutSpendingKey& sk,
|
||||||
const CBlockIndex& index,
|
const CBlockIndex& index,
|
||||||
CBlock& block,
|
CBlock& block,
|
||||||
ZCIncrementalMerkleTree& tree) {
|
ZCIncrementalMerkleTree& tree) {
|
||||||
|
@ -112,7 +112,7 @@ TEST(wallet_tests, setup_datadir_location_run_as_first_test) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(wallet_tests, note_data_serialisation) {
|
TEST(wallet_tests, note_data_serialisation) {
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
auto wtx = GetValidReceive(sk, 10, true);
|
auto wtx = GetValidReceive(sk, 10, true);
|
||||||
auto note = GetNote(sk, wtx, 0, 1);
|
auto note = GetNote(sk, wtx, 0, 1);
|
||||||
auto nullifier = note.nullifier(sk);
|
auto nullifier = note.nullifier(sk);
|
||||||
|
@ -138,7 +138,7 @@ TEST(wallet_tests, note_data_serialisation) {
|
||||||
TEST(wallet_tests, find_unspent_notes) {
|
TEST(wallet_tests, find_unspent_notes) {
|
||||||
SelectParams(CBaseChainParams::TESTNET);
|
SelectParams(CBaseChainParams::TESTNET);
|
||||||
CWallet wallet;
|
CWallet wallet;
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
wallet.AddSpendingKey(sk);
|
wallet.AddSpendingKey(sk);
|
||||||
|
|
||||||
auto wtx = GetValidReceive(sk, 10, true);
|
auto wtx = GetValidReceive(sk, 10, true);
|
||||||
|
@ -295,7 +295,7 @@ TEST(wallet_tests, find_unspent_notes) {
|
||||||
|
|
||||||
|
|
||||||
TEST(wallet_tests, set_note_addrs_in_cwallettx) {
|
TEST(wallet_tests, set_note_addrs_in_cwallettx) {
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
auto wtx = GetValidReceive(sk, 10, true);
|
auto wtx = GetValidReceive(sk, 10, true);
|
||||||
auto note = GetNote(sk, wtx, 0, 1);
|
auto note = GetNote(sk, wtx, 0, 1);
|
||||||
auto nullifier = note.nullifier(sk);
|
auto nullifier = note.nullifier(sk);
|
||||||
|
@ -315,7 +315,7 @@ TEST(wallet_tests, set_invalid_note_addrs_in_cwallettx) {
|
||||||
EXPECT_EQ(0, wtx.mapNoteData.size());
|
EXPECT_EQ(0, wtx.mapNoteData.size());
|
||||||
|
|
||||||
mapNoteData_t noteData;
|
mapNoteData_t noteData;
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
JSOutPoint jsoutpt {wtx.GetHash(), 0, 1};
|
JSOutPoint jsoutpt {wtx.GetHash(), 0, 1};
|
||||||
CNoteData nd {sk.address(), uint256()};
|
CNoteData nd {sk.address(), uint256()};
|
||||||
noteData[jsoutpt] = nd;
|
noteData[jsoutpt] = nd;
|
||||||
|
@ -326,7 +326,7 @@ TEST(wallet_tests, set_invalid_note_addrs_in_cwallettx) {
|
||||||
TEST(wallet_tests, GetNoteNullifier) {
|
TEST(wallet_tests, GetNoteNullifier) {
|
||||||
CWallet wallet;
|
CWallet wallet;
|
||||||
|
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
auto address = sk.address();
|
auto address = sk.address();
|
||||||
auto dec = ZCNoteDecryption(sk.receiving_key());
|
auto dec = ZCNoteDecryption(sk.receiving_key());
|
||||||
|
|
||||||
|
@ -357,8 +357,8 @@ TEST(wallet_tests, GetNoteNullifier) {
|
||||||
TEST(wallet_tests, FindMyNotes) {
|
TEST(wallet_tests, FindMyNotes) {
|
||||||
CWallet wallet;
|
CWallet wallet;
|
||||||
|
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
auto sk2 = libzcash::SpendingKey::random();
|
auto sk2 = libzcash::SproutSpendingKey::random();
|
||||||
wallet.AddSpendingKey(sk2);
|
wallet.AddSpendingKey(sk2);
|
||||||
|
|
||||||
auto wtx = GetValidReceive(sk, 10, true);
|
auto wtx = GetValidReceive(sk, 10, true);
|
||||||
|
@ -384,7 +384,7 @@ TEST(wallet_tests, FindMyNotesInEncryptedWallet) {
|
||||||
uint256 r {GetRandHash()};
|
uint256 r {GetRandHash()};
|
||||||
CKeyingMaterial vMasterKey (r.begin(), r.end());
|
CKeyingMaterial vMasterKey (r.begin(), r.end());
|
||||||
|
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
wallet.AddSpendingKey(sk);
|
wallet.AddSpendingKey(sk);
|
||||||
|
|
||||||
ASSERT_TRUE(wallet.EncryptKeys(vMasterKey));
|
ASSERT_TRUE(wallet.EncryptKeys(vMasterKey));
|
||||||
|
@ -412,7 +412,7 @@ TEST(wallet_tests, FindMyNotesInEncryptedWallet) {
|
||||||
TEST(wallet_tests, get_conflicted_notes) {
|
TEST(wallet_tests, get_conflicted_notes) {
|
||||||
CWallet wallet;
|
CWallet wallet;
|
||||||
|
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
wallet.AddSpendingKey(sk);
|
wallet.AddSpendingKey(sk);
|
||||||
|
|
||||||
auto wtx = GetValidReceive(sk, 10, true);
|
auto wtx = GetValidReceive(sk, 10, true);
|
||||||
|
@ -443,7 +443,7 @@ TEST(wallet_tests, get_conflicted_notes) {
|
||||||
TEST(wallet_tests, nullifier_is_spent) {
|
TEST(wallet_tests, nullifier_is_spent) {
|
||||||
CWallet wallet;
|
CWallet wallet;
|
||||||
|
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
wallet.AddSpendingKey(sk);
|
wallet.AddSpendingKey(sk);
|
||||||
|
|
||||||
auto wtx = GetValidReceive(sk, 10, true);
|
auto wtx = GetValidReceive(sk, 10, true);
|
||||||
|
@ -483,7 +483,7 @@ TEST(wallet_tests, nullifier_is_spent) {
|
||||||
TEST(wallet_tests, navigate_from_nullifier_to_note) {
|
TEST(wallet_tests, navigate_from_nullifier_to_note) {
|
||||||
CWallet wallet;
|
CWallet wallet;
|
||||||
|
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
wallet.AddSpendingKey(sk);
|
wallet.AddSpendingKey(sk);
|
||||||
|
|
||||||
auto wtx = GetValidReceive(sk, 10, true);
|
auto wtx = GetValidReceive(sk, 10, true);
|
||||||
|
@ -509,7 +509,7 @@ TEST(wallet_tests, navigate_from_nullifier_to_note) {
|
||||||
TEST(wallet_tests, spent_note_is_from_me) {
|
TEST(wallet_tests, spent_note_is_from_me) {
|
||||||
CWallet wallet;
|
CWallet wallet;
|
||||||
|
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
wallet.AddSpendingKey(sk);
|
wallet.AddSpendingKey(sk);
|
||||||
|
|
||||||
auto wtx = GetValidReceive(sk, 10, true);
|
auto wtx = GetValidReceive(sk, 10, true);
|
||||||
|
@ -537,7 +537,7 @@ TEST(wallet_tests, spent_note_is_from_me) {
|
||||||
TEST(wallet_tests, cached_witnesses_empty_chain) {
|
TEST(wallet_tests, cached_witnesses_empty_chain) {
|
||||||
TestWallet wallet;
|
TestWallet wallet;
|
||||||
|
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
wallet.AddSpendingKey(sk);
|
wallet.AddSpendingKey(sk);
|
||||||
|
|
||||||
auto wtx = GetValidReceive(sk, 10, true);
|
auto wtx = GetValidReceive(sk, 10, true);
|
||||||
|
@ -590,7 +590,7 @@ TEST(wallet_tests, cached_witnesses_chain_tip) {
|
||||||
CBlock block1;
|
CBlock block1;
|
||||||
ZCIncrementalMerkleTree tree;
|
ZCIncrementalMerkleTree tree;
|
||||||
|
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
wallet.AddSpendingKey(sk);
|
wallet.AddSpendingKey(sk);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -672,7 +672,7 @@ TEST(wallet_tests, CachedWitnessesDecrementFirst) {
|
||||||
CBlockIndex index2(block2);
|
CBlockIndex index2(block2);
|
||||||
ZCIncrementalMerkleTree tree;
|
ZCIncrementalMerkleTree tree;
|
||||||
|
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
wallet.AddSpendingKey(sk);
|
wallet.AddSpendingKey(sk);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -744,7 +744,7 @@ TEST(wallet_tests, CachedWitnessesCleanIndex) {
|
||||||
ZCIncrementalMerkleTree riTree = tree;
|
ZCIncrementalMerkleTree riTree = tree;
|
||||||
std::vector<boost::optional<ZCIncrementalWitness>> witnesses;
|
std::vector<boost::optional<ZCIncrementalWitness>> witnesses;
|
||||||
|
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
wallet.AddSpendingKey(sk);
|
wallet.AddSpendingKey(sk);
|
||||||
|
|
||||||
// Generate a chain
|
// Generate a chain
|
||||||
|
@ -813,7 +813,7 @@ TEST(wallet_tests, CachedWitnessesCleanIndex) {
|
||||||
TEST(wallet_tests, ClearNoteWitnessCache) {
|
TEST(wallet_tests, ClearNoteWitnessCache) {
|
||||||
TestWallet wallet;
|
TestWallet wallet;
|
||||||
|
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
wallet.AddSpendingKey(sk);
|
wallet.AddSpendingKey(sk);
|
||||||
|
|
||||||
auto wtx = GetValidReceive(sk, 10, true);
|
auto wtx = GetValidReceive(sk, 10, true);
|
||||||
|
@ -862,7 +862,7 @@ TEST(wallet_tests, WriteWitnessCache) {
|
||||||
MockWalletDB walletdb;
|
MockWalletDB walletdb;
|
||||||
CBlockLocator loc;
|
CBlockLocator loc;
|
||||||
|
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
wallet.AddSpendingKey(sk);
|
wallet.AddSpendingKey(sk);
|
||||||
|
|
||||||
auto wtx = GetValidReceive(sk, 10, true);
|
auto wtx = GetValidReceive(sk, 10, true);
|
||||||
|
@ -939,7 +939,7 @@ TEST(wallet_tests, UpdateNullifierNoteMap) {
|
||||||
uint256 r {GetRandHash()};
|
uint256 r {GetRandHash()};
|
||||||
CKeyingMaterial vMasterKey (r.begin(), r.end());
|
CKeyingMaterial vMasterKey (r.begin(), r.end());
|
||||||
|
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
wallet.AddSpendingKey(sk);
|
wallet.AddSpendingKey(sk);
|
||||||
|
|
||||||
ASSERT_TRUE(wallet.EncryptKeys(vMasterKey));
|
ASSERT_TRUE(wallet.EncryptKeys(vMasterKey));
|
||||||
|
@ -972,7 +972,7 @@ TEST(wallet_tests, UpdateNullifierNoteMap) {
|
||||||
TEST(wallet_tests, UpdatedNoteData) {
|
TEST(wallet_tests, UpdatedNoteData) {
|
||||||
TestWallet wallet;
|
TestWallet wallet;
|
||||||
|
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
wallet.AddSpendingKey(sk);
|
wallet.AddSpendingKey(sk);
|
||||||
|
|
||||||
auto wtx = GetValidReceive(sk, 10, true);
|
auto wtx = GetValidReceive(sk, 10, true);
|
||||||
|
@ -1019,7 +1019,7 @@ TEST(wallet_tests, UpdatedNoteData) {
|
||||||
TEST(wallet_tests, MarkAffectedTransactionsDirty) {
|
TEST(wallet_tests, MarkAffectedTransactionsDirty) {
|
||||||
TestWallet wallet;
|
TestWallet wallet;
|
||||||
|
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
wallet.AddSpendingKey(sk);
|
wallet.AddSpendingKey(sk);
|
||||||
|
|
||||||
auto wtx = GetValidReceive(sk, 10, true);
|
auto wtx = GetValidReceive(sk, 10, true);
|
||||||
|
@ -1050,7 +1050,7 @@ TEST(wallet_tests, MarkAffectedTransactionsDirty) {
|
||||||
TEST(wallet_tests, NoteLocking) {
|
TEST(wallet_tests, NoteLocking) {
|
||||||
TestWallet wallet;
|
TestWallet wallet;
|
||||||
|
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
wallet.AddSpendingKey(sk);
|
wallet.AddSpendingKey(sk);
|
||||||
|
|
||||||
auto wtx = GetValidReceive(sk, 10, true);
|
auto wtx = GetValidReceive(sk, 10, true);
|
||||||
|
|
|
@ -20,12 +20,14 @@ TEST(wallet_zkeys_tests, store_and_load_zkeys) {
|
||||||
CWallet wallet;
|
CWallet wallet;
|
||||||
|
|
||||||
// wallet should be empty
|
// wallet should be empty
|
||||||
std::set<libzcash::PaymentAddress> addrs;
|
std::set<libzcash::SproutPaymentAddress> addrs;
|
||||||
wallet.GetPaymentAddresses(addrs);
|
wallet.GetPaymentAddresses(addrs);
|
||||||
ASSERT_EQ(0, addrs.size());
|
ASSERT_EQ(0, addrs.size());
|
||||||
|
|
||||||
// wallet should have one key
|
// wallet should have one key
|
||||||
auto addr = wallet.GenerateNewZKey();
|
auto address = wallet.GenerateNewZKey();
|
||||||
|
ASSERT_NE(boost::get<libzcash::SproutPaymentAddress>(&address), nullptr);
|
||||||
|
auto addr = boost::get<libzcash::SproutPaymentAddress>(address);
|
||||||
wallet.GetPaymentAddresses(addrs);
|
wallet.GetPaymentAddresses(addrs);
|
||||||
ASSERT_EQ(1, addrs.size());
|
ASSERT_EQ(1, addrs.size());
|
||||||
|
|
||||||
|
@ -33,7 +35,7 @@ TEST(wallet_zkeys_tests, store_and_load_zkeys) {
|
||||||
ASSERT_TRUE(wallet.HaveSpendingKey(addr));
|
ASSERT_TRUE(wallet.HaveSpendingKey(addr));
|
||||||
|
|
||||||
// manually add new spending key to wallet
|
// manually add new spending key to wallet
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
ASSERT_TRUE(wallet.AddZKey(sk));
|
ASSERT_TRUE(wallet.AddZKey(sk));
|
||||||
|
|
||||||
// verify wallet did add it
|
// verify wallet did add it
|
||||||
|
@ -41,7 +43,7 @@ TEST(wallet_zkeys_tests, store_and_load_zkeys) {
|
||||||
ASSERT_TRUE(wallet.HaveSpendingKey(addr));
|
ASSERT_TRUE(wallet.HaveSpendingKey(addr));
|
||||||
|
|
||||||
// verify spending key stored correctly
|
// verify spending key stored correctly
|
||||||
libzcash::SpendingKey keyOut;
|
libzcash::SproutSpendingKey keyOut;
|
||||||
wallet.GetSpendingKey(addr, keyOut);
|
wallet.GetSpendingKey(addr, keyOut);
|
||||||
ASSERT_EQ(sk, keyOut);
|
ASSERT_EQ(sk, keyOut);
|
||||||
|
|
||||||
|
@ -51,7 +53,7 @@ TEST(wallet_zkeys_tests, store_and_load_zkeys) {
|
||||||
ASSERT_EQ(1, addrs.count(addr));
|
ASSERT_EQ(1, addrs.count(addr));
|
||||||
|
|
||||||
// Load a third key into the wallet
|
// Load a third key into the wallet
|
||||||
sk = libzcash::SpendingKey::random();
|
sk = libzcash::SproutSpendingKey::random();
|
||||||
ASSERT_TRUE(wallet.LoadZKey(sk));
|
ASSERT_TRUE(wallet.LoadZKey(sk));
|
||||||
|
|
||||||
// attach metadata to this third key
|
// attach metadata to this third key
|
||||||
|
@ -77,12 +79,12 @@ TEST(wallet_zkeys_tests, StoreAndLoadViewingKeys) {
|
||||||
CWallet wallet;
|
CWallet wallet;
|
||||||
|
|
||||||
// wallet should be empty
|
// wallet should be empty
|
||||||
std::set<libzcash::PaymentAddress> addrs;
|
std::set<libzcash::SproutPaymentAddress> addrs;
|
||||||
wallet.GetPaymentAddresses(addrs);
|
wallet.GetPaymentAddresses(addrs);
|
||||||
ASSERT_EQ(0, addrs.size());
|
ASSERT_EQ(0, addrs.size());
|
||||||
|
|
||||||
// manually add new viewing key to wallet
|
// manually add new viewing key to wallet
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
auto vk = sk.viewing_key();
|
auto vk = sk.viewing_key();
|
||||||
ASSERT_TRUE(wallet.AddViewingKey(vk));
|
ASSERT_TRUE(wallet.AddViewingKey(vk));
|
||||||
|
|
||||||
|
@ -93,12 +95,12 @@ TEST(wallet_zkeys_tests, StoreAndLoadViewingKeys) {
|
||||||
ASSERT_FALSE(wallet.HaveSpendingKey(addr));
|
ASSERT_FALSE(wallet.HaveSpendingKey(addr));
|
||||||
|
|
||||||
// verify viewing key stored correctly
|
// verify viewing key stored correctly
|
||||||
libzcash::ViewingKey vkOut;
|
libzcash::SproutViewingKey vkOut;
|
||||||
wallet.GetViewingKey(addr, vkOut);
|
wallet.GetViewingKey(addr, vkOut);
|
||||||
ASSERT_EQ(vk, vkOut);
|
ASSERT_EQ(vk, vkOut);
|
||||||
|
|
||||||
// Load a second viewing key into the wallet
|
// Load a second viewing key into the wallet
|
||||||
auto sk2 = libzcash::SpendingKey::random();
|
auto sk2 = libzcash::SproutSpendingKey::random();
|
||||||
ASSERT_TRUE(wallet.LoadViewingKey(sk2.viewing_key()));
|
ASSERT_TRUE(wallet.LoadViewingKey(sk2.viewing_key()));
|
||||||
|
|
||||||
// verify wallet did add it
|
// verify wallet did add it
|
||||||
|
@ -133,7 +135,7 @@ TEST(wallet_zkeys_tests, write_zkey_direct_to_db) {
|
||||||
ASSERT_TRUE(fFirstRun);
|
ASSERT_TRUE(fFirstRun);
|
||||||
|
|
||||||
// wallet should be empty
|
// wallet should be empty
|
||||||
std::set<libzcash::PaymentAddress> addrs;
|
std::set<libzcash::SproutPaymentAddress> addrs;
|
||||||
wallet.GetPaymentAddresses(addrs);
|
wallet.GetPaymentAddresses(addrs);
|
||||||
ASSERT_EQ(0, addrs.size());
|
ASSERT_EQ(0, addrs.size());
|
||||||
|
|
||||||
|
@ -145,7 +147,7 @@ TEST(wallet_zkeys_tests, write_zkey_direct_to_db) {
|
||||||
ASSERT_EQ(1, addrs.size());
|
ASSERT_EQ(1, addrs.size());
|
||||||
|
|
||||||
// create random key and add it to database directly, bypassing wallet
|
// create random key and add it to database directly, bypassing wallet
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
auto addr = sk.address();
|
auto addr = sk.address();
|
||||||
int64_t now = GetTime();
|
int64_t now = GetTime();
|
||||||
CKeyMetadata meta(now);
|
CKeyMetadata meta(now);
|
||||||
|
@ -171,7 +173,7 @@ TEST(wallet_zkeys_tests, write_zkey_direct_to_db) {
|
||||||
ASSERT_TRUE(wallet.HaveSpendingKey(addr));
|
ASSERT_TRUE(wallet.HaveSpendingKey(addr));
|
||||||
|
|
||||||
// check key is the same
|
// check key is the same
|
||||||
libzcash::SpendingKey keyOut;
|
libzcash::SproutSpendingKey keyOut;
|
||||||
wallet.GetSpendingKey(addr, keyOut);
|
wallet.GetSpendingKey(addr, keyOut);
|
||||||
ASSERT_EQ(sk, keyOut);
|
ASSERT_EQ(sk, keyOut);
|
||||||
|
|
||||||
|
@ -205,7 +207,7 @@ TEST(wallet_zkeys_tests, WriteViewingKeyDirectToDB) {
|
||||||
ASSERT_TRUE(fFirstRun);
|
ASSERT_TRUE(fFirstRun);
|
||||||
|
|
||||||
// create random viewing key and add it to database directly, bypassing wallet
|
// create random viewing key and add it to database directly, bypassing wallet
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
auto vk = sk.viewing_key();
|
auto vk = sk.viewing_key();
|
||||||
auto addr = sk.address();
|
auto addr = sk.address();
|
||||||
int64_t now = GetTime();
|
int64_t now = GetTime();
|
||||||
|
@ -223,7 +225,7 @@ TEST(wallet_zkeys_tests, WriteViewingKeyDirectToDB) {
|
||||||
ASSERT_TRUE(wallet.HaveViewingKey(addr));
|
ASSERT_TRUE(wallet.HaveViewingKey(addr));
|
||||||
|
|
||||||
// check key is the same
|
// check key is the same
|
||||||
libzcash::ViewingKey vkOut;
|
libzcash::SproutViewingKey vkOut;
|
||||||
wallet.GetViewingKey(addr, vkOut);
|
wallet.GetViewingKey(addr, vkOut);
|
||||||
ASSERT_EQ(vk, vkOut);
|
ASSERT_EQ(vk, vkOut);
|
||||||
}
|
}
|
||||||
|
@ -252,12 +254,14 @@ TEST(wallet_zkeys_tests, write_cryptedzkey_direct_to_db) {
|
||||||
ASSERT_TRUE(fFirstRun);
|
ASSERT_TRUE(fFirstRun);
|
||||||
|
|
||||||
// wallet should be empty
|
// wallet should be empty
|
||||||
std::set<libzcash::PaymentAddress> addrs;
|
std::set<libzcash::SproutPaymentAddress> addrs;
|
||||||
wallet.GetPaymentAddresses(addrs);
|
wallet.GetPaymentAddresses(addrs);
|
||||||
ASSERT_EQ(0, addrs.size());
|
ASSERT_EQ(0, addrs.size());
|
||||||
|
|
||||||
// Add random key to the wallet
|
// Add random key to the wallet
|
||||||
auto paymentAddress = wallet.GenerateNewZKey();
|
auto address = wallet.GenerateNewZKey();
|
||||||
|
ASSERT_NE(boost::get<libzcash::SproutPaymentAddress>(&address), nullptr);
|
||||||
|
auto paymentAddress = boost::get<libzcash::SproutPaymentAddress>(address);
|
||||||
|
|
||||||
// wallet should have one key
|
// wallet should have one key
|
||||||
wallet.GetPaymentAddresses(addrs);
|
wallet.GetPaymentAddresses(addrs);
|
||||||
|
@ -274,7 +278,9 @@ TEST(wallet_zkeys_tests, write_cryptedzkey_direct_to_db) {
|
||||||
|
|
||||||
// unlock wallet and then add
|
// unlock wallet and then add
|
||||||
wallet.Unlock(strWalletPass);
|
wallet.Unlock(strWalletPass);
|
||||||
auto paymentAddress2 = wallet.GenerateNewZKey();
|
auto address2 = wallet.GenerateNewZKey();
|
||||||
|
ASSERT_NE(boost::get<libzcash::SproutPaymentAddress>(&address2), nullptr);
|
||||||
|
auto paymentAddress2 = boost::get<libzcash::SproutPaymentAddress>(address2);
|
||||||
|
|
||||||
// Create a new wallet from the existing wallet path
|
// Create a new wallet from the existing wallet path
|
||||||
CWallet wallet2("wallet_crypted.dat");
|
CWallet wallet2("wallet_crypted.dat");
|
||||||
|
@ -292,7 +298,7 @@ TEST(wallet_zkeys_tests, write_cryptedzkey_direct_to_db) {
|
||||||
ASSERT_TRUE(addrs.count(paymentAddress2));
|
ASSERT_TRUE(addrs.count(paymentAddress2));
|
||||||
|
|
||||||
// spending key is crypted, so we can't extract valid payment address
|
// spending key is crypted, so we can't extract valid payment address
|
||||||
libzcash::SpendingKey keyOut;
|
libzcash::SproutSpendingKey keyOut;
|
||||||
wallet2.GetSpendingKey(paymentAddress, keyOut);
|
wallet2.GetSpendingKey(paymentAddress, keyOut);
|
||||||
ASSERT_FALSE(paymentAddress == keyOut.address());
|
ASSERT_FALSE(paymentAddress == keyOut.address());
|
||||||
|
|
||||||
|
|
|
@ -253,7 +253,7 @@ UniValue z_validatepaymentdisclosure(const UniValue& params, bool fHelp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the payment address is valid
|
// Check the payment address is valid
|
||||||
PaymentAddress zaddr = pd.payload.zaddr;
|
SproutPaymentAddress zaddr = pd.payload.zaddr;
|
||||||
{
|
{
|
||||||
o.push_back(Pair("paymentAddress", EncodePaymentAddress(zaddr)));
|
o.push_back(Pair("paymentAddress", EncodePaymentAddress(zaddr)));
|
||||||
|
|
||||||
|
|
|
@ -296,9 +296,11 @@ UniValue importwallet_impl(const UniValue& params, bool fHelp, bool fImportZKeys
|
||||||
// Let's see if the address is a valid Zcash spending key
|
// Let's see if the address is a valid Zcash spending key
|
||||||
if (fImportZKeys) {
|
if (fImportZKeys) {
|
||||||
auto spendingkey = DecodeSpendingKey(vstr[0]);
|
auto spendingkey = DecodeSpendingKey(vstr[0]);
|
||||||
if (spendingkey) {
|
if (IsValidSpendingKey(spendingkey)) {
|
||||||
libzcash::SpendingKey key = *spendingkey;
|
// TODO: Add Sapling support. For now, ensure we can freely convert.
|
||||||
libzcash::PaymentAddress addr = key.address();
|
assert(boost::get<libzcash::SproutSpendingKey>(&spendingkey) != nullptr);
|
||||||
|
auto key = boost::get<libzcash::SproutSpendingKey>(spendingkey);
|
||||||
|
auto addr = key.address();
|
||||||
if (pwalletMain->HaveSpendingKey(addr)) {
|
if (pwalletMain->HaveSpendingKey(addr)) {
|
||||||
LogPrint("zrpc", "Skipping import of zaddr %s (key already present)\n", EncodePaymentAddress(addr));
|
LogPrint("zrpc", "Skipping import of zaddr %s (key already present)\n", EncodePaymentAddress(addr));
|
||||||
continue;
|
continue;
|
||||||
|
@ -526,13 +528,13 @@ UniValue dumpwallet_impl(const UniValue& params, bool fHelp, bool fDumpZKeys)
|
||||||
file << "\n";
|
file << "\n";
|
||||||
|
|
||||||
if (fDumpZKeys) {
|
if (fDumpZKeys) {
|
||||||
std::set<libzcash::PaymentAddress> addresses;
|
std::set<libzcash::SproutPaymentAddress> addresses;
|
||||||
pwalletMain->GetPaymentAddresses(addresses);
|
pwalletMain->GetPaymentAddresses(addresses);
|
||||||
file << "\n";
|
file << "\n";
|
||||||
file << "# Zkeys\n";
|
file << "# Zkeys\n";
|
||||||
file << "\n";
|
file << "\n";
|
||||||
for (auto addr : addresses ) {
|
for (auto addr : addresses ) {
|
||||||
libzcash::SpendingKey key;
|
libzcash::SproutSpendingKey key;
|
||||||
if (pwalletMain->GetSpendingKey(addr, key)) {
|
if (pwalletMain->GetSpendingKey(addr, key)) {
|
||||||
std::string strTime = EncodeDumpTime(pwalletMain->mapZKeyMetadata[addr].nCreateTime);
|
std::string strTime = EncodeDumpTime(pwalletMain->mapZKeyMetadata[addr].nCreateTime);
|
||||||
file << strprintf("%s %s # zaddr=%s\n", EncodeSpendingKey(key), strTime, EncodePaymentAddress(addr));
|
file << strprintf("%s %s # zaddr=%s\n", EncodeSpendingKey(key), strTime, EncodePaymentAddress(addr));
|
||||||
|
@ -614,10 +616,12 @@ UniValue z_importkey(const UniValue& params, bool fHelp)
|
||||||
|
|
||||||
string strSecret = params[0].get_str();
|
string strSecret = params[0].get_str();
|
||||||
auto spendingkey = DecodeSpendingKey(strSecret);
|
auto spendingkey = DecodeSpendingKey(strSecret);
|
||||||
if (!spendingkey) {
|
if (!IsValidSpendingKey(spendingkey)) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid spending key");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid spending key");
|
||||||
}
|
}
|
||||||
auto key = *spendingkey;
|
// TODO: Add Sapling support. For now, ensure we can freely convert.
|
||||||
|
assert(boost::get<libzcash::SproutSpendingKey>(&spendingkey) != nullptr);
|
||||||
|
auto key = boost::get<libzcash::SproutSpendingKey>(spendingkey);
|
||||||
auto addr = key.address();
|
auto addr = key.address();
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -706,10 +710,12 @@ UniValue z_importviewingkey(const UniValue& params, bool fHelp)
|
||||||
|
|
||||||
string strVKey = params[0].get_str();
|
string strVKey = params[0].get_str();
|
||||||
auto viewingkey = DecodeViewingKey(strVKey);
|
auto viewingkey = DecodeViewingKey(strVKey);
|
||||||
if (!viewingkey) {
|
if (!IsValidViewingKey(viewingkey)) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid viewing key");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid viewing key");
|
||||||
}
|
}
|
||||||
auto vkey = *viewingkey;
|
// TODO: Add Sapling support. For now, ensure we can freely convert.
|
||||||
|
assert(boost::get<libzcash::SproutViewingKey>(&viewingkey) != nullptr);
|
||||||
|
auto vkey = boost::get<libzcash::SproutViewingKey>(viewingkey);
|
||||||
auto addr = vkey.address();
|
auto addr = vkey.address();
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -766,12 +772,14 @@ UniValue z_exportkey(const UniValue& params, bool fHelp)
|
||||||
string strAddress = params[0].get_str();
|
string strAddress = params[0].get_str();
|
||||||
|
|
||||||
auto address = DecodePaymentAddress(strAddress);
|
auto address = DecodePaymentAddress(strAddress);
|
||||||
if (!address) {
|
if (!IsValidPaymentAddress(address)) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid zaddr");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid zaddr");
|
||||||
}
|
}
|
||||||
auto addr = *address;
|
// TODO: Add Sapling support. For now, ensure we can freely convert.
|
||||||
|
assert(boost::get<libzcash::SproutPaymentAddress>(&address) != nullptr);
|
||||||
|
auto addr = boost::get<libzcash::SproutPaymentAddress>(address);
|
||||||
|
|
||||||
libzcash::SpendingKey k;
|
libzcash::SproutSpendingKey k;
|
||||||
if (!pwalletMain->GetSpendingKey(addr, k))
|
if (!pwalletMain->GetSpendingKey(addr, k))
|
||||||
throw JSONRPCError(RPC_WALLET_ERROR, "Wallet does not hold private zkey for this zaddr");
|
throw JSONRPCError(RPC_WALLET_ERROR, "Wallet does not hold private zkey for this zaddr");
|
||||||
|
|
||||||
|
@ -804,14 +812,16 @@ UniValue z_exportviewingkey(const UniValue& params, bool fHelp)
|
||||||
string strAddress = params[0].get_str();
|
string strAddress = params[0].get_str();
|
||||||
|
|
||||||
auto address = DecodePaymentAddress(strAddress);
|
auto address = DecodePaymentAddress(strAddress);
|
||||||
if (!address) {
|
if (!IsValidPaymentAddress(address)) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid zaddr");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid zaddr");
|
||||||
}
|
}
|
||||||
auto addr = *address;
|
// TODO: Add Sapling support. For now, ensure we can freely convert.
|
||||||
|
assert(boost::get<libzcash::SproutPaymentAddress>(&address) != nullptr);
|
||||||
|
auto addr = boost::get<libzcash::SproutPaymentAddress>(address);
|
||||||
|
|
||||||
libzcash::ViewingKey vk;
|
libzcash::SproutViewingKey vk;
|
||||||
if (!pwalletMain->GetViewingKey(addr, vk)) {
|
if (!pwalletMain->GetViewingKey(addr, vk)) {
|
||||||
libzcash::SpendingKey k;
|
libzcash::SproutSpendingKey k;
|
||||||
if (!pwalletMain->GetSpendingKey(addr, k)) {
|
if (!pwalletMain->GetSpendingKey(addr, k)) {
|
||||||
throw JSONRPCError(RPC_WALLET_ERROR, "Wallet does not hold private key or viewing key for this zaddr");
|
throw JSONRPCError(RPC_WALLET_ERROR, "Wallet does not hold private key or viewing key for this zaddr");
|
||||||
}
|
}
|
||||||
|
|
|
@ -2522,8 +2522,10 @@ UniValue z_listunspent(const UniValue& params, bool fHelp)
|
||||||
}
|
}
|
||||||
string address = o.get_str();
|
string address = o.get_str();
|
||||||
auto zaddr = DecodePaymentAddress(address);
|
auto zaddr = DecodePaymentAddress(address);
|
||||||
if (zaddr) {
|
if (IsValidPaymentAddress(zaddr)) {
|
||||||
libzcash::PaymentAddress addr = *zaddr;
|
// TODO: Add Sapling support. For now, ensure we can freely convert.
|
||||||
|
assert(boost::get<libzcash::SproutPaymentAddress>(&zaddr) != nullptr);
|
||||||
|
libzcash::SproutPaymentAddress addr = boost::get<libzcash::SproutPaymentAddress>(zaddr);
|
||||||
if (!fIncludeWatchonly && !pwalletMain->HaveSpendingKey(addr)) {
|
if (!fIncludeWatchonly && !pwalletMain->HaveSpendingKey(addr)) {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, spending key for address does not belong to wallet: ") + address);
|
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, spending key for address does not belong to wallet: ") + address);
|
||||||
}
|
}
|
||||||
|
@ -2540,7 +2542,10 @@ UniValue z_listunspent(const UniValue& params, bool fHelp)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// User did not provide zaddrs, so use default i.e. all addresses
|
// User did not provide zaddrs, so use default i.e. all addresses
|
||||||
pwalletMain->GetPaymentAddresses(zaddrs);
|
// TODO: Add Sapling support
|
||||||
|
std::set<libzcash::SproutPaymentAddress> sproutzaddrs = {};
|
||||||
|
pwalletMain->GetPaymentAddresses(sproutzaddrs);
|
||||||
|
zaddrs.insert(sproutzaddrs.begin(), sproutzaddrs.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue results(UniValue::VARR);
|
UniValue results(UniValue::VARR);
|
||||||
|
@ -2554,7 +2559,7 @@ UniValue z_listunspent(const UniValue& params, bool fHelp)
|
||||||
obj.push_back(Pair("jsindex", (int)entry.jsop.js ));
|
obj.push_back(Pair("jsindex", (int)entry.jsop.js ));
|
||||||
obj.push_back(Pair("jsoutindex", (int)entry.jsop.n));
|
obj.push_back(Pair("jsoutindex", (int)entry.jsop.n));
|
||||||
obj.push_back(Pair("confirmations", entry.nHeight));
|
obj.push_back(Pair("confirmations", entry.nHeight));
|
||||||
obj.push_back(Pair("spendable", pwalletMain->HaveSpendingKey(entry.address)));
|
obj.push_back(Pair("spendable", pwalletMain->HaveSpendingKey(boost::get<libzcash::SproutPaymentAddress>(entry.address))));
|
||||||
obj.push_back(Pair("address", EncodePaymentAddress(entry.address)));
|
obj.push_back(Pair("address", EncodePaymentAddress(entry.address)));
|
||||||
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());
|
std::string data(entry.plaintext.memo().begin(), entry.plaintext.memo().end());
|
||||||
|
@ -2793,10 +2798,13 @@ UniValue zc_raw_receive(const UniValue& params, bool fHelp)
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
|
|
||||||
auto spendingkey = DecodeSpendingKey(params[0].get_str());
|
auto spendingkey = DecodeSpendingKey(params[0].get_str());
|
||||||
if (!spendingkey) {
|
if (!IsValidSpendingKey(spendingkey)) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid spending key");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid spending key");
|
||||||
}
|
}
|
||||||
SpendingKey k = *spendingkey;
|
if (boost::get<libzcash::SproutSpendingKey>(&spendingkey) == nullptr) {
|
||||||
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Only works with Sprout spending keys");
|
||||||
|
}
|
||||||
|
SproutSpendingKey k = boost::get<libzcash::SproutSpendingKey>(spendingkey);
|
||||||
|
|
||||||
uint256 epk;
|
uint256 epk;
|
||||||
unsigned char nonce;
|
unsigned char nonce;
|
||||||
|
@ -2826,7 +2834,7 @@ UniValue zc_raw_receive(const UniValue& params, bool fHelp)
|
||||||
h_sig,
|
h_sig,
|
||||||
nonce
|
nonce
|
||||||
);
|
);
|
||||||
PaymentAddress payment_addr = k.address();
|
SproutPaymentAddress payment_addr = k.address();
|
||||||
SproutNote decrypted_note = npt.note(payment_addr);
|
SproutNote decrypted_note = npt.note(payment_addr);
|
||||||
|
|
||||||
assert(pwalletMain != NULL);
|
assert(pwalletMain != NULL);
|
||||||
|
@ -2902,15 +2910,18 @@ UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp)
|
||||||
std::vector<JSInput> vjsin;
|
std::vector<JSInput> vjsin;
|
||||||
std::vector<JSOutput> vjsout;
|
std::vector<JSOutput> vjsout;
|
||||||
std::vector<SproutNote> notes;
|
std::vector<SproutNote> notes;
|
||||||
std::vector<SpendingKey> keys;
|
std::vector<SproutSpendingKey> keys;
|
||||||
std::vector<uint256> commitments;
|
std::vector<uint256> commitments;
|
||||||
|
|
||||||
for (const string& name_ : inputs.getKeys()) {
|
for (const string& name_ : inputs.getKeys()) {
|
||||||
auto spendingkey = DecodeSpendingKey(inputs[name_].get_str());
|
auto spendingkey = DecodeSpendingKey(inputs[name_].get_str());
|
||||||
if (!spendingkey) {
|
if (!IsValidSpendingKey(spendingkey)) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid spending key");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid spending key");
|
||||||
}
|
}
|
||||||
SpendingKey k = *spendingkey;
|
if (boost::get<libzcash::SproutSpendingKey>(&spendingkey) == nullptr) {
|
||||||
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Only works with Sprout spending keys");
|
||||||
|
}
|
||||||
|
SproutSpendingKey k = boost::get<libzcash::SproutSpendingKey>(spendingkey);
|
||||||
|
|
||||||
keys.push_back(k);
|
keys.push_back(k);
|
||||||
|
|
||||||
|
@ -2921,7 +2932,7 @@ UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp)
|
||||||
ssData >> npt;
|
ssData >> npt;
|
||||||
}
|
}
|
||||||
|
|
||||||
PaymentAddress addr = k.address();
|
SproutPaymentAddress addr = k.address();
|
||||||
SproutNote note = npt.note(addr);
|
SproutNote note = npt.note(addr);
|
||||||
notes.push_back(note);
|
notes.push_back(note);
|
||||||
commitments.push_back(note.cm());
|
commitments.push_back(note.cm());
|
||||||
|
@ -2952,12 +2963,15 @@ UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp)
|
||||||
|
|
||||||
for (const string& name_ : outputs.getKeys()) {
|
for (const string& name_ : outputs.getKeys()) {
|
||||||
auto addrTo = DecodePaymentAddress(name_);
|
auto addrTo = DecodePaymentAddress(name_);
|
||||||
if (!addrTo) {
|
if (!IsValidPaymentAddress(addrTo)) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid recipient address.");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid recipient address.");
|
||||||
}
|
}
|
||||||
|
if (boost::get<libzcash::SproutPaymentAddress>(&addrTo) == nullptr) {
|
||||||
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Only works with Sprout payment addresses");
|
||||||
|
}
|
||||||
CAmount nAmount = AmountFromValue(outputs[name_]);
|
CAmount nAmount = AmountFromValue(outputs[name_]);
|
||||||
|
|
||||||
vjsout.push_back(JSOutput(*addrTo, nAmount));
|
vjsout.push_back(JSOutput(boost::get<libzcash::SproutPaymentAddress>(addrTo), nAmount));
|
||||||
}
|
}
|
||||||
|
|
||||||
while (vjsout.size() < ZC_NUM_JS_OUTPUTS) {
|
while (vjsout.size() < ZC_NUM_JS_OUTPUTS) {
|
||||||
|
@ -3063,7 +3077,7 @@ UniValue zc_raw_keygen(const UniValue& params, bool fHelp)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto k = SpendingKey::random();
|
auto k = SproutSpendingKey::random();
|
||||||
auto addr = k.address();
|
auto addr = k.address();
|
||||||
auto viewing_key = k.viewing_key();
|
auto viewing_key = k.viewing_key();
|
||||||
|
|
||||||
|
@ -3130,7 +3144,8 @@ UniValue z_listaddresses(const UniValue& params, bool fHelp)
|
||||||
}
|
}
|
||||||
|
|
||||||
UniValue ret(UniValue::VARR);
|
UniValue ret(UniValue::VARR);
|
||||||
std::set<libzcash::PaymentAddress> addresses;
|
// TODO: Add Sapling support
|
||||||
|
std::set<libzcash::SproutPaymentAddress> addresses;
|
||||||
pwalletMain->GetPaymentAddresses(addresses);
|
pwalletMain->GetPaymentAddresses(addresses);
|
||||||
for (auto addr : addresses ) {
|
for (auto addr : addresses ) {
|
||||||
if (fIncludeWatchonly || pwalletMain->HaveSpendingKey(addr)) {
|
if (fIncludeWatchonly || pwalletMain->HaveSpendingKey(addr)) {
|
||||||
|
@ -3232,11 +3247,14 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp)
|
||||||
auto fromaddress = params[0].get_str();
|
auto fromaddress = params[0].get_str();
|
||||||
|
|
||||||
auto zaddr = DecodePaymentAddress(fromaddress);
|
auto zaddr = DecodePaymentAddress(fromaddress);
|
||||||
if (!zaddr) {
|
if (!IsValidPaymentAddress(zaddr)) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid zaddr.");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid zaddr.");
|
||||||
}
|
}
|
||||||
|
// TODO: Add Sapling support. For now, ensure we can freely convert.
|
||||||
|
assert(boost::get<libzcash::SproutPaymentAddress>(&zaddr) != nullptr);
|
||||||
|
auto sproutzaddr = boost::get<libzcash::SproutPaymentAddress>(zaddr);
|
||||||
|
|
||||||
if (!(pwalletMain->HaveSpendingKey(*zaddr) || pwalletMain->HaveViewingKey(*zaddr))) {
|
if (!(pwalletMain->HaveSpendingKey(sproutzaddr) || pwalletMain->HaveViewingKey(sproutzaddr))) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, zaddr spending key or viewing key not found.");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, zaddr spending key or viewing key not found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3299,13 +3317,14 @@ UniValue z_getbalance(const UniValue& params, bool fHelp)
|
||||||
bool fromTaddr = false;
|
bool fromTaddr = false;
|
||||||
CTxDestination taddr = DecodeDestination(fromaddress);
|
CTxDestination taddr = DecodeDestination(fromaddress);
|
||||||
fromTaddr = IsValidDestination(taddr);
|
fromTaddr = IsValidDestination(taddr);
|
||||||
libzcash::PaymentAddress zaddr;
|
|
||||||
if (!fromTaddr) {
|
if (!fromTaddr) {
|
||||||
auto res = DecodePaymentAddress(fromaddress);
|
auto res = DecodePaymentAddress(fromaddress);
|
||||||
if (!res) {
|
if (!IsValidPaymentAddress(res)) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid from address, should be a taddr or zaddr.");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid from address, should be a taddr or zaddr.");
|
||||||
}
|
}
|
||||||
zaddr = *res;
|
// TODO: Add Sapling support. For now, ensure we can freely convert.
|
||||||
|
assert(boost::get<libzcash::SproutPaymentAddress>(&res) != nullptr);
|
||||||
|
auto zaddr = boost::get<libzcash::SproutPaymentAddress>(res);
|
||||||
if (!(pwalletMain->HaveSpendingKey(zaddr) || pwalletMain->HaveViewingKey(zaddr))) {
|
if (!(pwalletMain->HaveSpendingKey(zaddr) || pwalletMain->HaveViewingKey(zaddr))) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, zaddr spending key or viewing key not found.");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, zaddr spending key or viewing key not found.");
|
||||||
}
|
}
|
||||||
|
@ -3534,14 +3553,16 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
|
||||||
bool fromTaddr = false;
|
bool fromTaddr = false;
|
||||||
CTxDestination taddr = DecodeDestination(fromaddress);
|
CTxDestination taddr = DecodeDestination(fromaddress);
|
||||||
fromTaddr = IsValidDestination(taddr);
|
fromTaddr = IsValidDestination(taddr);
|
||||||
libzcash::PaymentAddress zaddr;
|
libzcash::SproutPaymentAddress zaddr;
|
||||||
if (!fromTaddr) {
|
if (!fromTaddr) {
|
||||||
auto res = DecodePaymentAddress(fromaddress);
|
auto res = DecodePaymentAddress(fromaddress);
|
||||||
if (!res) {
|
if (!IsValidPaymentAddress(res)) {
|
||||||
// invalid
|
// invalid
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid from address, should be a taddr or zaddr.");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid from address, should be a taddr or zaddr.");
|
||||||
}
|
}
|
||||||
zaddr = *res;
|
// TODO: Add Sapling support. For now, ensure we can freely convert.
|
||||||
|
assert(boost::get<libzcash::SproutPaymentAddress>(&res) != nullptr);
|
||||||
|
zaddr = boost::get<libzcash::SproutPaymentAddress>(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that we have the spending key
|
// Check that we have the spending key
|
||||||
|
@ -3579,7 +3600,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
|
||||||
bool isZaddr = false;
|
bool isZaddr = false;
|
||||||
CTxDestination taddr = DecodeDestination(address);
|
CTxDestination taddr = DecodeDestination(address);
|
||||||
if (!IsValidDestination(taddr)) {
|
if (!IsValidDestination(taddr)) {
|
||||||
if (DecodePaymentAddress(address)) {
|
if (IsValidPaymentAddressString(address)) {
|
||||||
isZaddr = true;
|
isZaddr = true;
|
||||||
} else {
|
} else {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ")+address );
|
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ")+address );
|
||||||
|
@ -3773,7 +3794,7 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp)
|
||||||
|
|
||||||
// Validate the destination address
|
// Validate the destination address
|
||||||
auto destaddress = params[1].get_str();
|
auto destaddress = params[1].get_str();
|
||||||
if (!DecodePaymentAddress(destaddress)) {
|
if (!IsValidPaymentAddressString(destaddress)) {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ") + destaddress );
|
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ") + destaddress );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4015,10 +4036,10 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto zaddr = DecodePaymentAddress(address);
|
auto zaddr = DecodePaymentAddress(address);
|
||||||
if (zaddr) {
|
if (IsValidPaymentAddress(zaddr)) {
|
||||||
// Ignore listed z-addrs if we are using all of them
|
// Ignore listed z-addrs if we are using all of them
|
||||||
if (!(useAny || useAnyNote)) {
|
if (!(useAny || useAnyNote)) {
|
||||||
zaddrs.insert(*zaddr);
|
zaddrs.insert(zaddr);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
throw JSONRPCError(
|
throw JSONRPCError(
|
||||||
|
@ -4038,7 +4059,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
|
||||||
bool isToZaddr = false;
|
bool isToZaddr = false;
|
||||||
CTxDestination taddr = DecodeDestination(destaddress);
|
CTxDestination taddr = DecodeDestination(destaddress);
|
||||||
if (!IsValidDestination(taddr)) {
|
if (!IsValidDestination(taddr)) {
|
||||||
if (DecodePaymentAddress(destaddress)) {
|
if (IsValidPaymentAddressString(destaddress)) {
|
||||||
isToZaddr = true;
|
isToZaddr = true;
|
||||||
} else {
|
} else {
|
||||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ") + destaddress );
|
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ") + destaddress );
|
||||||
|
@ -4174,9 +4195,11 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
|
||||||
maxedOutNotesFlag = true;
|
maxedOutNotesFlag = true;
|
||||||
} else {
|
} else {
|
||||||
estimatedTxSize += increase;
|
estimatedTxSize += increase;
|
||||||
SpendingKey zkey;
|
// TODO: Add Sapling support
|
||||||
pwalletMain->GetSpendingKey(entry.address, zkey);
|
auto zaddr = boost::get<SproutPaymentAddress>(entry.address);
|
||||||
noteInputs.emplace_back(entry.jsop, entry.plaintext.note(entry.address), nValue, zkey);
|
SproutSpendingKey zkey;
|
||||||
|
pwalletMain->GetSpendingKey(zaddr, zkey);
|
||||||
|
noteInputs.emplace_back(entry.jsop, entry.plaintext.note(zaddr), nValue, zkey);
|
||||||
mergedNoteValue += nValue;
|
mergedNoteValue += nValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,8 @@ const CWalletTx* CWallet::GetWalletTx(const uint256& hash) const
|
||||||
libzcash::PaymentAddress CWallet::GenerateNewZKey()
|
libzcash::PaymentAddress CWallet::GenerateNewZKey()
|
||||||
{
|
{
|
||||||
AssertLockHeld(cs_wallet); // mapZKeyMetadata
|
AssertLockHeld(cs_wallet); // mapZKeyMetadata
|
||||||
auto k = SpendingKey::random();
|
// TODO: Add Sapling support
|
||||||
|
auto k = SproutSpendingKey::random();
|
||||||
auto addr = k.address();
|
auto addr = k.address();
|
||||||
|
|
||||||
// Check for collision, even though it is unlikely to ever occur
|
// Check for collision, even though it is unlikely to ever occur
|
||||||
|
@ -100,7 +101,8 @@ libzcash::PaymentAddress CWallet::GenerateNewZKey()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add spending key to keystore and persist to disk
|
// Add spending key to keystore and persist to disk
|
||||||
bool CWallet::AddZKey(const libzcash::SpendingKey &key)
|
// TODO: Add Sapling support
|
||||||
|
bool CWallet::AddZKey(const libzcash::SproutSpendingKey &key)
|
||||||
{
|
{
|
||||||
AssertLockHeld(cs_wallet); // mapZKeyMetadata
|
AssertLockHeld(cs_wallet); // mapZKeyMetadata
|
||||||
auto addr = key.address();
|
auto addr = key.address();
|
||||||
|
@ -194,7 +196,7 @@ bool CWallet::AddCryptedKey(const CPubKey &vchPubKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool CWallet::AddCryptedSpendingKey(const libzcash::PaymentAddress &address,
|
bool CWallet::AddCryptedSpendingKey(const libzcash::SproutPaymentAddress &address,
|
||||||
const libzcash::ReceivingKey &rk,
|
const libzcash::ReceivingKey &rk,
|
||||||
const std::vector<unsigned char> &vchCryptedSecret)
|
const std::vector<unsigned char> &vchCryptedSecret)
|
||||||
{
|
{
|
||||||
|
@ -229,7 +231,7 @@ bool CWallet::LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &meta)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWallet::LoadZKeyMetadata(const PaymentAddress &addr, const CKeyMetadata &meta)
|
bool CWallet::LoadZKeyMetadata(const SproutPaymentAddress &addr, const CKeyMetadata &meta)
|
||||||
{
|
{
|
||||||
AssertLockHeld(cs_wallet); // mapZKeyMetadata
|
AssertLockHeld(cs_wallet); // mapZKeyMetadata
|
||||||
mapZKeyMetadata[addr] = meta;
|
mapZKeyMetadata[addr] = meta;
|
||||||
|
@ -241,17 +243,17 @@ bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigne
|
||||||
return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret);
|
return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWallet::LoadCryptedZKey(const libzcash::PaymentAddress &addr, const libzcash::ReceivingKey &rk, const std::vector<unsigned char> &vchCryptedSecret)
|
bool CWallet::LoadCryptedZKey(const libzcash::SproutPaymentAddress &addr, const libzcash::ReceivingKey &rk, const std::vector<unsigned char> &vchCryptedSecret)
|
||||||
{
|
{
|
||||||
return CCryptoKeyStore::AddCryptedSpendingKey(addr, rk, vchCryptedSecret);
|
return CCryptoKeyStore::AddCryptedSpendingKey(addr, rk, vchCryptedSecret);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWallet::LoadZKey(const libzcash::SpendingKey &key)
|
bool CWallet::LoadZKey(const libzcash::SproutSpendingKey &key)
|
||||||
{
|
{
|
||||||
return CCryptoKeyStore::AddSpendingKey(key);
|
return CCryptoKeyStore::AddSpendingKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWallet::AddViewingKey(const libzcash::ViewingKey &vk)
|
bool CWallet::AddViewingKey(const libzcash::SproutViewingKey &vk)
|
||||||
{
|
{
|
||||||
if (!CCryptoKeyStore::AddViewingKey(vk)) {
|
if (!CCryptoKeyStore::AddViewingKey(vk)) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -263,7 +265,7 @@ bool CWallet::AddViewingKey(const libzcash::ViewingKey &vk)
|
||||||
return CWalletDB(strWalletFile).WriteViewingKey(vk);
|
return CWalletDB(strWalletFile).WriteViewingKey(vk);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWallet::RemoveViewingKey(const libzcash::ViewingKey &vk)
|
bool CWallet::RemoveViewingKey(const libzcash::SproutViewingKey &vk)
|
||||||
{
|
{
|
||||||
AssertLockHeld(cs_wallet);
|
AssertLockHeld(cs_wallet);
|
||||||
if (!CCryptoKeyStore::RemoveViewingKey(vk)) {
|
if (!CCryptoKeyStore::RemoveViewingKey(vk)) {
|
||||||
|
@ -278,7 +280,7 @@ bool CWallet::RemoveViewingKey(const libzcash::ViewingKey &vk)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWallet::LoadViewingKey(const libzcash::ViewingKey &vk)
|
bool CWallet::LoadViewingKey(const libzcash::SproutViewingKey &vk)
|
||||||
{
|
{
|
||||||
return CCryptoKeyStore::AddViewingKey(vk);
|
return CCryptoKeyStore::AddViewingKey(vk);
|
||||||
}
|
}
|
||||||
|
@ -1257,7 +1259,7 @@ void CWallet::EraseFromWallet(const uint256 &hash)
|
||||||
* Throws std::runtime_error if the decryptor doesn't match this note
|
* Throws std::runtime_error if the decryptor doesn't match this note
|
||||||
*/
|
*/
|
||||||
boost::optional<uint256> CWallet::GetNoteNullifier(const JSDescription& jsdesc,
|
boost::optional<uint256> CWallet::GetNoteNullifier(const JSDescription& jsdesc,
|
||||||
const libzcash::PaymentAddress& address,
|
const libzcash::SproutPaymentAddress& address,
|
||||||
const ZCNoteDecryption& dec,
|
const ZCNoteDecryption& dec,
|
||||||
const uint256& hSig,
|
const uint256& hSig,
|
||||||
uint8_t n) const
|
uint8_t n) const
|
||||||
|
@ -1273,7 +1275,7 @@ boost::optional<uint256> CWallet::GetNoteNullifier(const JSDescription& jsdesc,
|
||||||
// SpendingKeys are only available if:
|
// SpendingKeys are only available if:
|
||||||
// - We have them (this isn't a viewing key)
|
// - We have them (this isn't a viewing key)
|
||||||
// - The wallet is unlocked
|
// - The wallet is unlocked
|
||||||
libzcash::SpendingKey key;
|
libzcash::SproutSpendingKey key;
|
||||||
if (GetSpendingKey(address, key)) {
|
if (GetSpendingKey(address, key)) {
|
||||||
ret = note.nullifier(key);
|
ret = note.nullifier(key);
|
||||||
}
|
}
|
||||||
|
@ -3715,7 +3717,7 @@ void CWallet::GetFilteredNotes(std::vector<CSproutNotePlaintextEntry> & outEntri
|
||||||
std::set<PaymentAddress> filterAddresses;
|
std::set<PaymentAddress> filterAddresses;
|
||||||
|
|
||||||
if (address.length() > 0) {
|
if (address.length() > 0) {
|
||||||
filterAddresses.insert(*DecodePaymentAddress(address));
|
filterAddresses.insert(DecodePaymentAddress(address));
|
||||||
}
|
}
|
||||||
|
|
||||||
GetFilteredNotes(outEntries, filterAddresses, minDepth, ignoreSpent, ignoreUnspendable);
|
GetFilteredNotes(outEntries, filterAddresses, minDepth, ignoreSpent, ignoreUnspendable);
|
||||||
|
@ -3749,7 +3751,7 @@ void CWallet::GetFilteredNotes(
|
||||||
for (auto & pair : wtx.mapNoteData) {
|
for (auto & pair : wtx.mapNoteData) {
|
||||||
JSOutPoint jsop = pair.first;
|
JSOutPoint jsop = pair.first;
|
||||||
CNoteData nd = pair.second;
|
CNoteData nd = pair.second;
|
||||||
PaymentAddress pa = nd.address;
|
SproutPaymentAddress pa = nd.address;
|
||||||
|
|
||||||
// skip notes which belong to a different payment address in the wallet
|
// skip notes which belong to a different payment address in the wallet
|
||||||
if (!(filterAddresses.empty() || filterAddresses.count(pa))) {
|
if (!(filterAddresses.empty() || filterAddresses.count(pa))) {
|
||||||
|
@ -3830,7 +3832,7 @@ void CWallet::GetUnspentFilteredNotes(
|
||||||
for (auto & pair : wtx.mapNoteData) {
|
for (auto & pair : wtx.mapNoteData) {
|
||||||
JSOutPoint jsop = pair.first;
|
JSOutPoint jsop = pair.first;
|
||||||
CNoteData nd = pair.second;
|
CNoteData nd = pair.second;
|
||||||
PaymentAddress pa = nd.address;
|
SproutPaymentAddress pa = nd.address;
|
||||||
|
|
||||||
// skip notes which belong to a different payment address in the wallet
|
// skip notes which belong to a different payment address in the wallet
|
||||||
if (!(filterAddresses.empty() || filterAddresses.count(pa))) {
|
if (!(filterAddresses.empty() || filterAddresses.count(pa))) {
|
||||||
|
|
|
@ -199,7 +199,7 @@ public:
|
||||||
class CNoteData
|
class CNoteData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
libzcash::PaymentAddress address;
|
libzcash::SproutPaymentAddress address;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cached note nullifier. May not be set if the wallet was not unlocked when
|
* Cached note nullifier. May not be set if the wallet was not unlocked when
|
||||||
|
@ -233,9 +233,9 @@ public:
|
||||||
int witnessHeight;
|
int witnessHeight;
|
||||||
|
|
||||||
CNoteData() : address(), nullifier(), witnessHeight {-1} { }
|
CNoteData() : address(), nullifier(), witnessHeight {-1} { }
|
||||||
CNoteData(libzcash::PaymentAddress a) :
|
CNoteData(libzcash::SproutPaymentAddress a) :
|
||||||
address {a}, nullifier(), witnessHeight {-1} { }
|
address {a}, nullifier(), witnessHeight {-1} { }
|
||||||
CNoteData(libzcash::PaymentAddress a, uint256 n) :
|
CNoteData(libzcash::SproutPaymentAddress a, uint256 n) :
|
||||||
address {a}, nullifier {n}, witnessHeight {-1} { }
|
address {a}, nullifier {n}, witnessHeight {-1} { }
|
||||||
|
|
||||||
ADD_SERIALIZE_METHODS;
|
ADD_SERIALIZE_METHODS;
|
||||||
|
@ -268,14 +268,14 @@ typedef std::map<JSOutPoint, CNoteData> mapNoteData_t;
|
||||||
struct CSproutNotePlaintextEntry
|
struct CSproutNotePlaintextEntry
|
||||||
{
|
{
|
||||||
JSOutPoint jsop;
|
JSOutPoint jsop;
|
||||||
libzcash::PaymentAddress address;
|
libzcash::SproutPaymentAddress address;
|
||||||
libzcash::SproutNotePlaintext plaintext;
|
libzcash::SproutNotePlaintext plaintext;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Decrypted note, location in a transaction, and confirmation height. */
|
/** Decrypted note, location in a transaction, and confirmation height. */
|
||||||
struct CUnspentSproutNotePlaintextEntry {
|
struct CUnspentSproutNotePlaintextEntry {
|
||||||
JSOutPoint jsop;
|
JSOutPoint jsop;
|
||||||
libzcash::PaymentAddress address;
|
libzcash::SproutPaymentAddress address;
|
||||||
libzcash::SproutNotePlaintext plaintext;
|
libzcash::SproutNotePlaintext plaintext;
|
||||||
int nHeight;
|
int nHeight;
|
||||||
};
|
};
|
||||||
|
@ -785,7 +785,7 @@ public:
|
||||||
|
|
||||||
std::set<int64_t> setKeyPool;
|
std::set<int64_t> setKeyPool;
|
||||||
std::map<CKeyID, CKeyMetadata> mapKeyMetadata;
|
std::map<CKeyID, CKeyMetadata> mapKeyMetadata;
|
||||||
std::map<libzcash::PaymentAddress, CKeyMetadata> mapZKeyMetadata;
|
std::map<libzcash::SproutPaymentAddress, CKeyMetadata> mapZKeyMetadata;
|
||||||
|
|
||||||
typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
|
typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
|
||||||
MasterKeyMap mapMasterKeys;
|
MasterKeyMap mapMasterKeys;
|
||||||
|
@ -962,21 +962,21 @@ public:
|
||||||
//! Generates a new zaddr
|
//! Generates a new zaddr
|
||||||
libzcash::PaymentAddress GenerateNewZKey();
|
libzcash::PaymentAddress GenerateNewZKey();
|
||||||
//! Adds spending key to the store, and saves it to disk
|
//! Adds spending key to the store, and saves it to disk
|
||||||
bool AddZKey(const libzcash::SpendingKey &key);
|
bool AddZKey(const libzcash::SproutSpendingKey &key);
|
||||||
//! Adds spending key to the store, without saving it to disk (used by LoadWallet)
|
//! Adds spending key to the store, without saving it to disk (used by LoadWallet)
|
||||||
bool LoadZKey(const libzcash::SpendingKey &key);
|
bool LoadZKey(const libzcash::SproutSpendingKey &key);
|
||||||
//! Load spending key metadata (used by LoadWallet)
|
//! Load spending key metadata (used by LoadWallet)
|
||||||
bool LoadZKeyMetadata(const libzcash::PaymentAddress &addr, const CKeyMetadata &meta);
|
bool LoadZKeyMetadata(const libzcash::SproutPaymentAddress &addr, const CKeyMetadata &meta);
|
||||||
//! Adds an encrypted spending key to the store, without saving it to disk (used by LoadWallet)
|
//! Adds an encrypted spending key to the store, without saving it to disk (used by LoadWallet)
|
||||||
bool LoadCryptedZKey(const libzcash::PaymentAddress &addr, const libzcash::ReceivingKey &rk, const std::vector<unsigned char> &vchCryptedSecret);
|
bool LoadCryptedZKey(const libzcash::SproutPaymentAddress &addr, const libzcash::ReceivingKey &rk, const std::vector<unsigned char> &vchCryptedSecret);
|
||||||
//! Adds an encrypted spending key to the store, and saves it to disk (virtual method, declared in crypter.h)
|
//! Adds an encrypted spending key to the store, and saves it to disk (virtual method, declared in crypter.h)
|
||||||
bool AddCryptedSpendingKey(const libzcash::PaymentAddress &address, const libzcash::ReceivingKey &rk, const std::vector<unsigned char> &vchCryptedSecret);
|
bool AddCryptedSpendingKey(const libzcash::SproutPaymentAddress &address, const libzcash::ReceivingKey &rk, const std::vector<unsigned char> &vchCryptedSecret);
|
||||||
|
|
||||||
//! Adds a viewing key to the store, and saves it to disk.
|
//! Adds a viewing key to the store, and saves it to disk.
|
||||||
bool AddViewingKey(const libzcash::ViewingKey &vk);
|
bool AddViewingKey(const libzcash::SproutViewingKey &vk);
|
||||||
bool RemoveViewingKey(const libzcash::ViewingKey &vk);
|
bool RemoveViewingKey(const libzcash::SproutViewingKey &vk);
|
||||||
//! Adds a viewing key to the store, without saving it to disk (used by LoadWallet)
|
//! Adds a viewing key to the store, without saving it to disk (used by LoadWallet)
|
||||||
bool LoadViewingKey(const libzcash::ViewingKey &dest);
|
bool LoadViewingKey(const libzcash::SproutViewingKey &dest);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Increment the next transaction order id
|
* Increment the next transaction order id
|
||||||
|
@ -1039,7 +1039,7 @@ public:
|
||||||
|
|
||||||
boost::optional<uint256> GetNoteNullifier(
|
boost::optional<uint256> GetNoteNullifier(
|
||||||
const JSDescription& jsdesc,
|
const JSDescription& jsdesc,
|
||||||
const libzcash::PaymentAddress& address,
|
const libzcash::SproutPaymentAddress& address,
|
||||||
const ZCNoteDecryption& dec,
|
const ZCNoteDecryption& dec,
|
||||||
const uint256& hSig,
|
const uint256& hSig,
|
||||||
uint8_t n) const;
|
uint8_t n) const;
|
||||||
|
|
|
@ -105,7 +105,7 @@ bool CWalletDB::WriteCryptedKey(const CPubKey& vchPubKey,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::WriteCryptedZKey(const libzcash::PaymentAddress & addr,
|
bool CWalletDB::WriteCryptedZKey(const libzcash::SproutPaymentAddress & addr,
|
||||||
const libzcash::ReceivingKey &rk,
|
const libzcash::ReceivingKey &rk,
|
||||||
const std::vector<unsigned char>& vchCryptedSecret,
|
const std::vector<unsigned char>& vchCryptedSecret,
|
||||||
const CKeyMetadata &keyMeta)
|
const CKeyMetadata &keyMeta)
|
||||||
|
@ -131,7 +131,7 @@ bool CWalletDB::WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey)
|
||||||
return Write(std::make_pair(std::string("mkey"), nID), kMasterKey, true);
|
return Write(std::make_pair(std::string("mkey"), nID), kMasterKey, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::WriteZKey(const libzcash::PaymentAddress& addr, const libzcash::SpendingKey& key, const CKeyMetadata &keyMeta)
|
bool CWalletDB::WriteZKey(const libzcash::SproutPaymentAddress& addr, const libzcash::SproutSpendingKey& key, const CKeyMetadata &keyMeta)
|
||||||
{
|
{
|
||||||
nWalletDBUpdated++;
|
nWalletDBUpdated++;
|
||||||
|
|
||||||
|
@ -142,13 +142,13 @@ bool CWalletDB::WriteZKey(const libzcash::PaymentAddress& addr, const libzcash::
|
||||||
return Write(std::make_pair(std::string("zkey"), addr), key, false);
|
return Write(std::make_pair(std::string("zkey"), addr), key, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::WriteViewingKey(const libzcash::ViewingKey &vk)
|
bool CWalletDB::WriteViewingKey(const libzcash::SproutViewingKey &vk)
|
||||||
{
|
{
|
||||||
nWalletDBUpdated++;
|
nWalletDBUpdated++;
|
||||||
return Write(std::make_pair(std::string("vkey"), vk), '1');
|
return Write(std::make_pair(std::string("vkey"), vk), '1');
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWalletDB::EraseViewingKey(const libzcash::ViewingKey &vk)
|
bool CWalletDB::EraseViewingKey(const libzcash::SproutViewingKey &vk)
|
||||||
{
|
{
|
||||||
nWalletDBUpdated++;
|
nWalletDBUpdated++;
|
||||||
return Erase(std::make_pair(std::string("vkey"), vk));
|
return Erase(std::make_pair(std::string("vkey"), vk));
|
||||||
|
@ -485,7 +485,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
|
||||||
}
|
}
|
||||||
else if (strType == "vkey")
|
else if (strType == "vkey")
|
||||||
{
|
{
|
||||||
libzcash::ViewingKey vk;
|
libzcash::SproutViewingKey vk;
|
||||||
ssKey >> vk;
|
ssKey >> vk;
|
||||||
char fYes;
|
char fYes;
|
||||||
ssValue >> fYes;
|
ssValue >> fYes;
|
||||||
|
@ -498,9 +498,9 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
|
||||||
}
|
}
|
||||||
else if (strType == "zkey")
|
else if (strType == "zkey")
|
||||||
{
|
{
|
||||||
libzcash::PaymentAddress addr;
|
libzcash::SproutPaymentAddress addr;
|
||||||
ssKey >> addr;
|
ssKey >> addr;
|
||||||
libzcash::SpendingKey key;
|
libzcash::SproutSpendingKey key;
|
||||||
ssValue >> key;
|
ssValue >> key;
|
||||||
|
|
||||||
if (!pwallet->LoadZKey(key))
|
if (!pwallet->LoadZKey(key))
|
||||||
|
@ -607,7 +607,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
|
||||||
}
|
}
|
||||||
else if (strType == "czkey")
|
else if (strType == "czkey")
|
||||||
{
|
{
|
||||||
libzcash::PaymentAddress addr;
|
libzcash::SproutPaymentAddress addr;
|
||||||
ssKey >> addr;
|
ssKey >> addr;
|
||||||
// Deserialization of a pair is just one item after another
|
// Deserialization of a pair is just one item after another
|
||||||
uint256 rkValue;
|
uint256 rkValue;
|
||||||
|
@ -641,7 +641,7 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
|
||||||
}
|
}
|
||||||
else if (strType == "zkeymeta")
|
else if (strType == "zkeymeta")
|
||||||
{
|
{
|
||||||
libzcash::PaymentAddress addr;
|
libzcash::SproutPaymentAddress addr;
|
||||||
ssKey >> addr;
|
ssKey >> addr;
|
||||||
CKeyMetadata keyMeta;
|
CKeyMetadata keyMeta;
|
||||||
ssValue >> keyMeta;
|
ssValue >> keyMeta;
|
||||||
|
|
|
@ -133,14 +133,14 @@ public:
|
||||||
static bool Recover(CDBEnv& dbenv, const std::string& filename);
|
static bool Recover(CDBEnv& dbenv, const std::string& filename);
|
||||||
|
|
||||||
/// Write spending key to wallet database, where key is payment address and value is spending key.
|
/// Write spending key to wallet database, where key is payment address and value is spending key.
|
||||||
bool WriteZKey(const libzcash::PaymentAddress& addr, const libzcash::SpendingKey& key, const CKeyMetadata &keyMeta);
|
bool WriteZKey(const libzcash::SproutPaymentAddress& addr, const libzcash::SproutSpendingKey& key, const CKeyMetadata &keyMeta);
|
||||||
bool WriteCryptedZKey(const libzcash::PaymentAddress & addr,
|
bool WriteCryptedZKey(const libzcash::SproutPaymentAddress & addr,
|
||||||
const libzcash::ReceivingKey & rk,
|
const libzcash::ReceivingKey & rk,
|
||||||
const std::vector<unsigned char>& vchCryptedSecret,
|
const std::vector<unsigned char>& vchCryptedSecret,
|
||||||
const CKeyMetadata &keyMeta);
|
const CKeyMetadata &keyMeta);
|
||||||
|
|
||||||
bool WriteViewingKey(const libzcash::ViewingKey &vk);
|
bool WriteViewingKey(const libzcash::SproutViewingKey &vk);
|
||||||
bool EraseViewingKey(const libzcash::ViewingKey &vk);
|
bool EraseViewingKey(const libzcash::SproutViewingKey &vk);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CWalletDB(const CWalletDB&);
|
CWalletDB(const CWalletDB&);
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
namespace libzcash {
|
namespace libzcash {
|
||||||
|
|
||||||
uint256 PaymentAddress::GetHash() const {
|
uint256 SproutPaymentAddress::GetHash() const {
|
||||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||||
ss << *this;
|
ss << *this;
|
||||||
return Hash(ss.begin(), ss.end());
|
return Hash(ss.begin(), ss.end());
|
||||||
|
@ -16,24 +16,37 @@ uint256 ReceivingKey::pk_enc() const {
|
||||||
return ZCNoteEncryption::generate_pubkey(*this);
|
return ZCNoteEncryption::generate_pubkey(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
PaymentAddress ViewingKey::address() const {
|
SproutPaymentAddress SproutViewingKey::address() const {
|
||||||
return PaymentAddress(a_pk, sk_enc.pk_enc());
|
return SproutPaymentAddress(a_pk, sk_enc.pk_enc());
|
||||||
}
|
}
|
||||||
|
|
||||||
ReceivingKey SpendingKey::receiving_key() const {
|
ReceivingKey SproutSpendingKey::receiving_key() const {
|
||||||
return ReceivingKey(ZCNoteEncryption::generate_privkey(*this));
|
return ReceivingKey(ZCNoteEncryption::generate_privkey(*this));
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewingKey SpendingKey::viewing_key() const {
|
SproutViewingKey SproutSpendingKey::viewing_key() const {
|
||||||
return ViewingKey(PRF_addr_a_pk(*this), receiving_key());
|
return SproutViewingKey(PRF_addr_a_pk(*this), receiving_key());
|
||||||
}
|
}
|
||||||
|
|
||||||
SpendingKey SpendingKey::random() {
|
SproutSpendingKey SproutSpendingKey::random() {
|
||||||
return SpendingKey(random_uint252());
|
return SproutSpendingKey(random_uint252());
|
||||||
}
|
}
|
||||||
|
|
||||||
PaymentAddress SpendingKey::address() const {
|
SproutPaymentAddress SproutSpendingKey::address() const {
|
||||||
return viewing_key().address();
|
return viewing_key().address();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IsValidPaymentAddress(const libzcash::PaymentAddress& zaddr) {
|
||||||
|
return zaddr.which() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsValidViewingKey(const libzcash::ViewingKey& vk) {
|
||||||
|
return vk.which() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsValidSpendingKey(const libzcash::SpendingKey& zkey) {
|
||||||
|
return zkey.which() != 0;
|
||||||
|
}
|
||||||
|
|
|
@ -5,19 +5,26 @@
|
||||||
#include "uint252.h"
|
#include "uint252.h"
|
||||||
#include "serialize.h"
|
#include "serialize.h"
|
||||||
|
|
||||||
|
#include <boost/variant.hpp>
|
||||||
|
|
||||||
namespace libzcash {
|
namespace libzcash {
|
||||||
|
class InvalidEncoding {
|
||||||
|
public:
|
||||||
|
friend bool operator==(const InvalidEncoding &a, const InvalidEncoding &b) { return true; }
|
||||||
|
friend bool operator<(const InvalidEncoding &a, const InvalidEncoding &b) { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
const size_t SerializedPaymentAddressSize = 64;
|
const size_t SerializedPaymentAddressSize = 64;
|
||||||
const size_t SerializedViewingKeySize = 64;
|
const size_t SerializedViewingKeySize = 64;
|
||||||
const size_t SerializedSpendingKeySize = 32;
|
const size_t SerializedSpendingKeySize = 32;
|
||||||
|
|
||||||
class PaymentAddress {
|
class SproutPaymentAddress {
|
||||||
public:
|
public:
|
||||||
uint256 a_pk;
|
uint256 a_pk;
|
||||||
uint256 pk_enc;
|
uint256 pk_enc;
|
||||||
|
|
||||||
PaymentAddress() : a_pk(), pk_enc() { }
|
SproutPaymentAddress() : a_pk(), pk_enc() { }
|
||||||
PaymentAddress(uint256 a_pk, uint256 pk_enc) : a_pk(a_pk), pk_enc(pk_enc) { }
|
SproutPaymentAddress(uint256 a_pk, uint256 pk_enc) : a_pk(a_pk), pk_enc(pk_enc) { }
|
||||||
|
|
||||||
ADD_SERIALIZE_METHODS;
|
ADD_SERIALIZE_METHODS;
|
||||||
|
|
||||||
|
@ -30,10 +37,10 @@ public:
|
||||||
//! Get the 256-bit SHA256d hash of this payment address.
|
//! Get the 256-bit SHA256d hash of this payment address.
|
||||||
uint256 GetHash() const;
|
uint256 GetHash() const;
|
||||||
|
|
||||||
friend inline bool operator==(const PaymentAddress& a, const PaymentAddress& b) {
|
friend inline bool operator==(const SproutPaymentAddress& a, const SproutPaymentAddress& b) {
|
||||||
return a.a_pk == b.a_pk && a.pk_enc == b.pk_enc;
|
return a.a_pk == b.a_pk && a.pk_enc == b.pk_enc;
|
||||||
}
|
}
|
||||||
friend inline bool operator<(const PaymentAddress& a, const PaymentAddress& b) {
|
friend inline bool operator<(const SproutPaymentAddress& a, const SproutPaymentAddress& b) {
|
||||||
return (a.a_pk < b.a_pk ||
|
return (a.a_pk < b.a_pk ||
|
||||||
(a.a_pk == b.a_pk && a.pk_enc < b.pk_enc));
|
(a.a_pk == b.a_pk && a.pk_enc < b.pk_enc));
|
||||||
}
|
}
|
||||||
|
@ -47,13 +54,13 @@ public:
|
||||||
uint256 pk_enc() const;
|
uint256 pk_enc() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ViewingKey {
|
class SproutViewingKey {
|
||||||
public:
|
public:
|
||||||
uint256 a_pk;
|
uint256 a_pk;
|
||||||
ReceivingKey sk_enc;
|
ReceivingKey sk_enc;
|
||||||
|
|
||||||
ViewingKey() : a_pk(), sk_enc() { }
|
SproutViewingKey() : a_pk(), sk_enc() { }
|
||||||
ViewingKey(uint256 a_pk, ReceivingKey sk_enc) : a_pk(a_pk), sk_enc(sk_enc) { }
|
SproutViewingKey(uint256 a_pk, ReceivingKey sk_enc) : a_pk(a_pk), sk_enc(sk_enc) { }
|
||||||
|
|
||||||
ADD_SERIALIZE_METHODS;
|
ADD_SERIALIZE_METHODS;
|
||||||
|
|
||||||
|
@ -63,29 +70,42 @@ public:
|
||||||
READWRITE(sk_enc);
|
READWRITE(sk_enc);
|
||||||
}
|
}
|
||||||
|
|
||||||
PaymentAddress address() const;
|
SproutPaymentAddress address() const;
|
||||||
|
|
||||||
friend inline bool operator==(const ViewingKey& a, const ViewingKey& b) {
|
friend inline bool operator==(const SproutViewingKey& a, const SproutViewingKey& b) {
|
||||||
return a.a_pk == b.a_pk && a.sk_enc == b.sk_enc;
|
return a.a_pk == b.a_pk && a.sk_enc == b.sk_enc;
|
||||||
}
|
}
|
||||||
friend inline bool operator<(const ViewingKey& a, const ViewingKey& b) {
|
friend inline bool operator<(const SproutViewingKey& a, const SproutViewingKey& b) {
|
||||||
return (a.a_pk < b.a_pk ||
|
return (a.a_pk < b.a_pk ||
|
||||||
(a.a_pk == b.a_pk && a.sk_enc < b.sk_enc));
|
(a.a_pk == b.a_pk && a.sk_enc < b.sk_enc));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class SpendingKey : public uint252 {
|
class SproutSpendingKey : public uint252 {
|
||||||
public:
|
public:
|
||||||
SpendingKey() : uint252() { }
|
SproutSpendingKey() : uint252() { }
|
||||||
SpendingKey(uint252 a_sk) : uint252(a_sk) { }
|
SproutSpendingKey(uint252 a_sk) : uint252(a_sk) { }
|
||||||
|
|
||||||
static SpendingKey random();
|
static SproutSpendingKey random();
|
||||||
|
|
||||||
ReceivingKey receiving_key() const;
|
ReceivingKey receiving_key() const;
|
||||||
ViewingKey viewing_key() const;
|
SproutViewingKey viewing_key() const;
|
||||||
PaymentAddress address() const;
|
SproutPaymentAddress address() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef boost::variant<InvalidEncoding, SproutPaymentAddress> PaymentAddress;
|
||||||
|
typedef boost::variant<InvalidEncoding, SproutViewingKey> ViewingKey;
|
||||||
|
typedef boost::variant<InvalidEncoding, SproutSpendingKey> SpendingKey;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Check whether a PaymentAddress is not an InvalidEncoding. */
|
||||||
|
bool IsValidPaymentAddress(const libzcash::PaymentAddress& zaddr);
|
||||||
|
|
||||||
|
/** Check whether a ViewingKey is not an InvalidEncoding. */
|
||||||
|
bool IsValidViewingKey(const libzcash::ViewingKey& vk);
|
||||||
|
|
||||||
|
/** Check whether a SpendingKey is not an InvalidEncoding. */
|
||||||
|
bool IsValidSpendingKey(const libzcash::SpendingKey& zkey);
|
||||||
|
|
||||||
#endif // ZC_ADDRESS_H_
|
#endif // ZC_ADDRESS_H_
|
||||||
|
|
|
@ -370,12 +370,12 @@ SproutNote JSOutput::note(const uint252& phi, const uint256& r, size_t i, const
|
||||||
}
|
}
|
||||||
|
|
||||||
JSOutput::JSOutput() : addr(uint256(), uint256()), value(0) {
|
JSOutput::JSOutput() : addr(uint256(), uint256()), value(0) {
|
||||||
SpendingKey a_sk = SpendingKey::random();
|
SproutSpendingKey a_sk = SproutSpendingKey::random();
|
||||||
addr = a_sk.address();
|
addr = a_sk.address();
|
||||||
}
|
}
|
||||||
|
|
||||||
JSInput::JSInput() : witness(ZCIncrementalMerkleTree().witness()),
|
JSInput::JSInput() : witness(ZCIncrementalMerkleTree().witness()),
|
||||||
key(SpendingKey::random()) {
|
key(SproutSpendingKey::random()) {
|
||||||
note = SproutNote(key.address().a_pk, 0, random_uint256(), random_uint256());
|
note = SproutNote(key.address().a_pk, 0, random_uint256(), random_uint256());
|
||||||
ZCIncrementalMerkleTree dummy_tree;
|
ZCIncrementalMerkleTree dummy_tree;
|
||||||
dummy_tree.append(note.cm());
|
dummy_tree.append(note.cm());
|
||||||
|
|
|
@ -19,12 +19,12 @@ class JSInput {
|
||||||
public:
|
public:
|
||||||
ZCIncrementalWitness witness;
|
ZCIncrementalWitness witness;
|
||||||
SproutNote note;
|
SproutNote note;
|
||||||
SpendingKey key;
|
SproutSpendingKey key;
|
||||||
|
|
||||||
JSInput();
|
JSInput();
|
||||||
JSInput(ZCIncrementalWitness witness,
|
JSInput(ZCIncrementalWitness witness,
|
||||||
SproutNote note,
|
SproutNote note,
|
||||||
SpendingKey key) : witness(witness), note(note), key(key) { }
|
SproutSpendingKey key) : witness(witness), note(note), key(key) { }
|
||||||
|
|
||||||
uint256 nullifier() const {
|
uint256 nullifier() const {
|
||||||
return note.nullifier(key);
|
return note.nullifier(key);
|
||||||
|
@ -33,12 +33,12 @@ public:
|
||||||
|
|
||||||
class JSOutput {
|
class JSOutput {
|
||||||
public:
|
public:
|
||||||
PaymentAddress addr;
|
SproutPaymentAddress addr;
|
||||||
uint64_t value;
|
uint64_t value;
|
||||||
boost::array<unsigned char, ZC_MEMO_SIZE> memo = {{0xF6}}; // 0xF6 is invalid UTF8 as per spec, rest of array is 0x00
|
boost::array<unsigned char, ZC_MEMO_SIZE> memo = {{0xF6}}; // 0xF6 is invalid UTF8 as per spec, rest of array is 0x00
|
||||||
|
|
||||||
JSOutput();
|
JSOutput();
|
||||||
JSOutput(PaymentAddress addr, uint64_t value) : addr(addr), value(value) { }
|
JSOutput(SproutPaymentAddress addr, uint64_t value) : addr(addr), value(value) { }
|
||||||
|
|
||||||
SproutNote 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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -34,7 +34,7 @@ uint256 SproutNote::cm() const {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint256 SproutNote::nullifier(const SpendingKey& a_sk) const {
|
uint256 SproutNote::nullifier(const SproutSpendingKey& a_sk) const {
|
||||||
return PRF_nf(a_sk, rho);
|
return PRF_nf(a_sk, rho);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ SproutNotePlaintext::SproutNotePlaintext(
|
||||||
r = note.r;
|
r = note.r;
|
||||||
}
|
}
|
||||||
|
|
||||||
SproutNote SproutNotePlaintext::note(const PaymentAddress& addr) const
|
SproutNote SproutNotePlaintext::note(const SproutPaymentAddress& addr) const
|
||||||
{
|
{
|
||||||
return SproutNote(addr.a_pk, value_, rho, r);
|
return SproutNote(addr.a_pk, value_, rho, r);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ public:
|
||||||
|
|
||||||
virtual uint256 cm() const override;
|
virtual uint256 cm() const override;
|
||||||
|
|
||||||
uint256 nullifier(const SpendingKey& a_sk) const;
|
uint256 nullifier(const SproutSpendingKey& a_sk) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class BaseNotePlaintext {
|
class BaseNotePlaintext {
|
||||||
|
@ -61,7 +61,7 @@ public:
|
||||||
|
|
||||||
SproutNotePlaintext(const SproutNote& note, boost::array<unsigned char, ZC_MEMO_SIZE> memo);
|
SproutNotePlaintext(const SproutNote& note, boost::array<unsigned char, ZC_MEMO_SIZE> memo);
|
||||||
|
|
||||||
SproutNote note(const PaymentAddress& addr) const;
|
SproutNote note(const SproutPaymentAddress& addr) const;
|
||||||
|
|
||||||
virtual ~SproutNotePlaintext() {}
|
virtual ~SproutNotePlaintext() {}
|
||||||
|
|
||||||
|
|
|
@ -118,7 +118,7 @@ public:
|
||||||
|
|
||||||
void generate_r1cs_witness(
|
void generate_r1cs_witness(
|
||||||
const MerklePath& path,
|
const MerklePath& path,
|
||||||
const SpendingKey& key,
|
const SproutSpendingKey& key,
|
||||||
const SproutNote& note
|
const SproutNote& note
|
||||||
) {
|
) {
|
||||||
note_gadget<FieldT>::generate_r1cs_witness(note);
|
note_gadget<FieldT>::generate_r1cs_witness(note);
|
||||||
|
|
|
@ -281,11 +281,11 @@ double benchmark_try_decrypt_notes(size_t nAddrs)
|
||||||
{
|
{
|
||||||
CWallet wallet;
|
CWallet wallet;
|
||||||
for (int i = 0; i < nAddrs; i++) {
|
for (int i = 0; i < nAddrs; i++) {
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
wallet.AddSpendingKey(sk);
|
wallet.AddSpendingKey(sk);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
auto tx = GetValidReceive(*pzcashParams, sk, 10, true);
|
auto tx = GetValidReceive(*pzcashParams, sk, 10, true);
|
||||||
|
|
||||||
struct timeval tv_start;
|
struct timeval tv_start;
|
||||||
|
@ -299,7 +299,7 @@ double benchmark_increment_note_witnesses(size_t nTxs)
|
||||||
CWallet wallet;
|
CWallet wallet;
|
||||||
ZCIncrementalMerkleTree tree;
|
ZCIncrementalMerkleTree tree;
|
||||||
|
|
||||||
auto sk = libzcash::SpendingKey::random();
|
auto sk = libzcash::SproutSpendingKey::random();
|
||||||
wallet.AddSpendingKey(sk);
|
wallet.AddSpendingKey(sk);
|
||||||
|
|
||||||
// First block
|
// First block
|
||||||
|
|
Loading…
Reference in New Issue