Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] [wallet] [zk] Z: Wallet methods from zcash/zcash #35

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
f4d5072
[wallet] [zk] Add note locking methods, with EXCLUSIVE_LOCKS_REQUIRED
ch4ot1c Jul 15, 2018
eb0e666
[wallet] [zk] Add FindMyNotes and SetNoteData
ch4ot1c Jul 15, 2018
600ccd9
[wallet] [zk] Add mapNoteData and related
ch4ot1c Jul 15, 2018
f38e182
[wallet] [zk] Add GetNoteNullifier
ch4ot1c Jul 15, 2018
ab6dd54
[wallet] [zk] Add UpdateNullifierNoteMap(WithTx), TODO properly intro…
ch4ot1c Jul 15, 2018
a16d32b
[wallet] [zk] Add GenerateNewZKey + AddZKey
ch4ot1c Jul 15, 2018
7f60d38
[wallet] [zk] [keystore] Add SpendingKey and ViewingKey Add/Remove/Ge…
ch4ot1c Jul 15, 2018
e43dd4c
[wallet] [zk] [fixup] Add mapNullifiersToNotes, mapZKeyMetadata, cs_S…
ch4ot1c Jul 15, 2018
2747c73
[wallet] Remove fFileBacked
ch4ot1c Jul 15, 2018
c7138f2
[wallet] [zk] Add AddZKey(WithDB), WriteZKey
ch4ot1c Jul 15, 2018
ecfece6
[wallet] [zk] Add mapTxNullifiers and related
ch4ot1c Jul 15, 2018
193c8eb
[zk] [fixup] Explicitly reference libzcash::note_decryption_failed
ch4ot1c Jul 15, 2018
36d912b
[consensus] Finish consensus/joinsplit.cpp & h
ch4ot1c Jul 21, 2018
7804498
[serialization] Add std::list to Serialize / Unserialize options
ch4ot1c Jul 21, 2018
0d70d4c
[serialization] CNoteData and JSOutPoint serialization, Add nWitnessC…
ch4ot1c Jul 21, 2018
cadc68d
[txdb] Use WriteWitnessCacheSize when using WriteTx
ch4ot1c Jul 21, 2018
89b912c
[wallet] [zk] #48 - Unwrap CWalletTx
Oct 1, 2018
07b8b59
[wallet] [zk] Add ViewingKey method impls
Oct 1, 2018
9ff3614
Merge branch 'master' into wallet/z_wallet
ch4ot1c Oct 1, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 21 additions & 6 deletions src/consensus/joinsplit.cpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,33 @@
bool CheckTransactionJoinsplits(const CTransaction& tx, CValidationState &state)

// Copyright (c) 2018 The Bitcoin Private Developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <consensus/joinsplit.h>

#include <init.h>
#include <primitives/transaction.h>
#include <consensus/validation.h>
#include <script/interpreter.h>
#include <script/script.h>
#include <zcash/Zcash.h>
#include <zcash/Proof.hpp>

bool CheckTransactionJoinSplits(const CTransaction& tx, CValidationState &state, unsigned int flags)
{
if (tx.vjoinsplit.size() > 0) {
// Empty output script.
CScript scriptCode;
uint256 dataToBeSigned;
int hashtype = SIGHASH_ALL;
if(flags & SCRIPT_VERIFY_FORKID)
if (flags & SCRIPT_VERIFY_FORKID)
hashtype |= SIGHASH_FORKID;

try {
dataToBeSigned = SignatureHash(scriptCode, tx, NOT_AN_INPUT,
hashtype, (flags & SCRIPT_VERIFY_FORKID) ? FORKID_IN_USE : FORKID_NONE);
} catch (std::logic_error ex) {
return state.DoS(100, error("CheckTransaction(): error computing signature hash"),
return state.DoS(100, error("CheckTransactionJoinSplits(): error computing signature hash"),
REJECT_INVALID, "error-computing-signature-hash");
}

Expand All @@ -25,15 +40,15 @@ bool CheckTransactionJoinsplits(const CTransaction& tx, CValidationState &state)
tx.joinSplitPubKey.begin()
) != 0) {

return state.DoS(100, error("CheckTransaction(): invalid joinsplit signature"),
return state.DoS(100, error("CheckTransactionJoinSplits(): invalid joinsplit signature"),
REJECT_INVALID, "bad-txns-invalid-joinsplit-signature");
}

// Ensure that zk-SNARKs verify
auto verifier = libzcash::ProofVerifier::Strict();
for(const JSDescription &joinsplit : tx.vjoinsplit) {
for (const JSDescription& joinsplit : tx.vjoinsplit) {
if (!joinsplit.Verify(pzcashParams.get(), verifier, tx.joinSplitPubKey)) {
return state.DoS(100, error("CheckTransaction(): joinsplit does not verify"),
return state.DoS(100, error("CheckTransactionJoinSplits(): joinsplit does not verify"),
REJECT_INVALID, "bad-txns-joinsplit-verification-failed");
}
}
Expand Down
5 changes: 4 additions & 1 deletion src/consensus/joinsplit.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
#ifndef BITCOIN_CONSENSUS_JOINSPLIT_H
#define BITCOIN_CONSENSUS_JOINSPLIT_H

bool CheckTransactionJoinsplits(const CTransaction& tx, CValidationState &state);
#include <primitives/transaction.h>
#include <consensus/validation.h>

bool CheckTransactionJoinSplits(const CTransaction& tx, CValidationState& state, unsigned int flags);

#endif // BITCOIN_CONSENSUS_JOINSPLIT_H
12 changes: 12 additions & 0 deletions src/consensus/reorg.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (c) 2018 The Bitcoin Private Developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BTCP_CONSENSUS_REORG_H
#define BTCP_CONSENSUS_REORG_H

/** Maximum reorg length we will accept before we shut down and alert the user. */
/** Note: Not a true consensus parameter, just a network-wide default. */
static const unsigned int MAX_REORG_LENGTH = COINBASE_MATURITY - 1;

#endif
45 changes: 45 additions & 0 deletions src/keystore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,48 @@ bool HaveKey(const CKeyStore& store, const CKey& key)
key2.Set(key.begin(), key.end(), !key.IsCompressed());
return store.HaveKey(key.GetPubKey().GetID()) || store.HaveKey(key2.GetPubKey().GetID());
}

// Z

bool CBasicKeyStore::AddSpendingKey(const libzcash::SpendingKey &sk)
{
LOCK(cs_SpendingKeyStore);
auto address = sk.address();
mapSpendingKeys[address] = sk;
mapNoteDecryptors.insert(std::make_pair(address, ZCNoteDecryption(sk.receiving_key())));
return true;
}

bool CBasicKeyStore::AddViewingKey(const libzcash::ViewingKey &vk)
{
LOCK(cs_SpendingKeyStore);
auto address = vk.address();
mapViewingKeys[address] = vk;
mapNoteDecryptors.insert(std::make_pair(address, ZCNoteDecryption(vk.sk_enc)));
return true;
}

bool CBasicKeyStore::RemoveViewingKey(const libzcash::ViewingKey &vk)
{
LOCK(cs_SpendingKeyStore);
mapViewingKeys.erase(vk.address());
return true;
}

bool CBasicKeyStore::HaveViewingKey(const libzcash::PaymentAddress &address) const
{
LOCK(cs_SpendingKeyStore);
return mapViewingKeys.count(address) > 0;
}

bool CBasicKeyStore::GetViewingKey(const libzcash::PaymentAddress &address,
libzcash::ViewingKey &vkOut) const
{
LOCK(cs_SpendingKeyStore);
ViewingKeyMap::const_iterator mi = mapViewingKeys.find(address);
if (mi != mapViewingKeys.end()) {
vkOut = mi->second;
return true;
}
return false;
}
78 changes: 78 additions & 0 deletions src/keystore.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,39 @@ class CKeyStore : public SigningProvider
virtual bool RemoveWatchOnly(const CScript &dest) =0;
virtual bool HaveWatchOnly(const CScript &dest) const =0;
virtual bool HaveWatchOnly() const =0;

//! Add a spending key to the store.
virtual bool AddSpendingKey(const libzcash::SpendingKey &sk) =0;

//! 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 GetSpendingKey(const libzcash::PaymentAddress &address, libzcash::SpendingKey& skOut) const =0;
virtual void GetPaymentAddresses(std::set<libzcash::PaymentAddress> &setAddress) const =0;
};

typedef std::map<CKeyID, CKey> KeyMap;
typedef std::map<CKeyID, CPubKey> WatchKeyMap;
typedef std::map<CScriptID, CScript > ScriptMap;
typedef std::set<CScript> WatchOnlySet;

typedef std::map<libzcash::PaymentAddress, libzcash::SpendingKey> SpendingKeyMap;
typedef std::map<libzcash::PaymentAddress, libzcash::ViewingKey> ViewingKeyMap;
typedef std::map<libzcash::PaymentAddress, ZCNoteDecryption> NoteDecryptorMap;

/** Basic key store, that keeps keys in an address->secret map */
class CBasicKeyStore : public CKeyStore
{
protected:
mutable CCriticalSection cs_KeyStore;
mutable CCriticalSection cs_SpendingKeyStore;

KeyMap mapKeys;
WatchKeyMap mapWatchKeys;
ScriptMap mapScripts;
WatchOnlySet setWatchOnly;
SpendingKeyMap mapSpendingKeys;
ViewingKeyMap mapViewingKeys;
NoteDecryptorMap mapNoteDecryptors;

void ImplicitlyLearnRelatedKeyScripts(const CPubKey& pubkey) EXCLUSIVE_LOCKS_REQUIRED(cs_KeyStore);

Expand All @@ -72,10 +88,72 @@ class CBasicKeyStore : public CKeyStore
bool RemoveWatchOnly(const CScript &dest) override;
bool HaveWatchOnly(const CScript &dest) const override;
bool HaveWatchOnly() const override;

bool AddSpendingKey(const libzcash::SpendingKey &sk);
bool HaveSpendingKey(const libzcash::PaymentAddress &address) const
{
bool result;
{
LOCK(cs_SpendingKeyStore);
result = (mapSpendingKeys.count(address) > 0);
}
return result;
}
bool GetSpendingKey(const libzcash::PaymentAddress &address, libzcash::SpendingKey &skOut) const
{
{
LOCK(cs_SpendingKeyStore);
SpendingKeyMap::const_iterator mi = mapSpendingKeys.find(address);
if (mi != mapSpendingKeys.end())
{
skOut = mi->second;
return true;
}
}
return false;
}
bool GetNoteDecryptor(const libzcash::PaymentAddress &address, ZCNoteDecryption &decOut) const
{
{
LOCK(cs_SpendingKeyStore);
NoteDecryptorMap::const_iterator mi = mapNoteDecryptors.find(address);
if (mi != mapNoteDecryptors.end())
{
decOut = mi->second;
return true;
}
}
return false;
}
void GetPaymentAddresses(std::set<libzcash::PaymentAddress> &setAddress) const
{
setAddress.clear();
{
LOCK(cs_SpendingKeyStore);
SpendingKeyMap::const_iterator mi = mapSpendingKeys.begin();
while (mi != mapSpendingKeys.end())
{
setAddress.insert((*mi).first);
mi++;
}
ViewingKeyMap::const_iterator mvi = mapViewingKeys.begin();
while (mvi != mapViewingKeys.end())
{
setAddress.insert((*mvi).first);
mvi++;
}
}
}

virtual bool AddViewingKey(const libzcash::ViewingKey &vk);
virtual bool RemoveViewingKey(const libzcash::ViewingKey &vk);
virtual bool HaveViewingKey(const libzcash::PaymentAddress &address) const;
virtual bool GetViewingKey(const libzcash::PaymentAddress &address, libzcash::ViewingKey& vkOut) const;
};

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<libzcash::PaymentAddress, std::vector<unsigned char> > CryptedSpendingKeyMap;

/** Return the CKeyID of the key involved in a script (if there is a unique one). */
CKeyID GetKeyForDestination(const CKeyStore& store, const CTxDestination& dest);
Expand Down
24 changes: 24 additions & 0 deletions src/serialize.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <string.h>
#include <utility>
#include <vector>
#include <list>

#include <prevector.h>
#include <span.h>
Expand Down Expand Up @@ -555,6 +556,11 @@ template<typename Stream, typename T, typename A> inline void Unserialize(Stream
template<typename Stream, typename T, std::size_t N> void Serialize(Stream& os, const std::array<T, N>& item);
template<typename Stream, typename T, std::size_t N> void Unserialize(Stream& is, std::array<T, N>& item);

/**
* list
*/
template<typename Stream, typename T> void Serialize(Stream& os, const std::list<T>& item);
template<typename Stream, typename T> void Unserialize(Stream& is, std::list<T>& item);
/**
* pair
*/
Expand Down Expand Up @@ -787,6 +793,24 @@ template<typename Stream, typename T, std::size_t N>
}
}

/**
* list
*/
template<typename Stream, typename T>
void Serialize(Stream& os, const std::list<T>& item)
{
for (auto& i : item) {
Serialize(os, i);
}
}

template<typename Stream, typename T>
void Unserialize(Stream& is, std::list<T>& item)
{
for (auto& i : item) {
Unserialize(is, i);
}
}

/**
* pair
Expand Down
14 changes: 8 additions & 6 deletions src/wallet/joinsplit.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ JSOutPoint(uint256 h, uint64_t js, uint8_t n) : hash {h}, js {js}, n {n} { }
ADD_SERIALIZE_METHODS;

template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
inline void SerializationOp(Stream& s, Operation ser_action) {
READWRITE(hash);
READWRITE(js);
READWRITE(n);
Expand All @@ -49,7 +49,9 @@ JSOutPoint(uint256 h, uint64_t js, uint8_t n) : hash {h}, js {js}, n {n} { }
return !(a == b);
}

std::string ToString() const;
std::string ToString() const {
return strprintf("JSOutPoint(%s, %d, %d)", hash.ToString().substr(0,10), js, n);
}
};

class CNoteData
Expand Down Expand Up @@ -88,16 +90,16 @@ class CNoteData
*/
int witnessHeight;

CNoteData() : address(), nullifier(), witnessHeight {-1} { }
CNoteData() : address(), nullifier(), witnesses {}, witnessHeight {-1} { }
CNoteData(libzcash::PaymentAddress a) :
address {a}, nullifier(), witnessHeight {-1} { }
address {a}, nullifier(), witnesses {}, witnessHeight {-1} { }
CNoteData(libzcash::PaymentAddress a, uint256 n) :
address {a}, nullifier {n}, witnessHeight {-1} { }
address {a}, nullifier {n}, witnesses {}, witnessHeight {-1} { }

ADD_SERIALIZE_METHODS;

template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
inline void SerializationOp(Stream& s, Operation ser_action) {
READWRITE(address);
READWRITE(nullifier);
READWRITE(witnesses);
Expand Down
Loading