Merge remote-tracking branch 'zcash/master' into dev
# Conflicts: # .gitignore # README.md # src/Makefile.gtest.include # src/gtest/test_checkblock.cpp # src/init.cpp # src/main.cpp # src/main.h # src/rpcserver.cpp # src/test/checkblock_tests.cpp # src/util.cpp
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "consensus/validation.h"
|
||||
#include "main.h"
|
||||
#include "zcash/Proof.hpp"
|
||||
|
||||
class MockCValidationState : public CValidationState {
|
||||
public:
|
||||
@@ -22,12 +23,14 @@ public:
|
||||
};
|
||||
|
||||
TEST(CheckBlock, VersionTooLow) {
|
||||
auto verifier = libzcash::ProofVerifier::Strict();
|
||||
|
||||
CBlock block;
|
||||
block.nVersion = 1;
|
||||
|
||||
MockCValidationState state;
|
||||
EXPECT_CALL(state, DoS(100, false, REJECT_INVALID, "version-too-low", false)).Times(1);
|
||||
EXPECT_FALSE(CheckBlock(0,0,block, state, false, false));
|
||||
EXPECT_FALSE(CheckBlock(0,0,block, state, verifier, false, false));
|
||||
}
|
||||
|
||||
TEST(ContextualCheckBlock, BadCoinbaseHeight) {
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
#include "keystore.h"
|
||||
#include "random.h"
|
||||
#ifdef ENABLE_WALLET
|
||||
#include "wallet/crypter.h"
|
||||
#endif
|
||||
#include "zcash/Address.hpp"
|
||||
|
||||
TEST(keystore_tests, store_and_retrieve_spending_key) {
|
||||
@@ -44,6 +46,7 @@ TEST(keystore_tests, store_and_retrieve_note_decryptor) {
|
||||
EXPECT_EQ(ZCNoteDecryption(sk.viewing_key()), decOut);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
class TestCCryptoKeyStore : public CCryptoKeyStore
|
||||
{
|
||||
public:
|
||||
@@ -125,3 +128,4 @@ TEST(keystore_tests, store_and_retrieve_spending_key_in_encrypted_store) {
|
||||
ASSERT_EQ(1, addrs.count(addr));
|
||||
ASSERT_EQ(1, addrs.count(addr2));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -79,6 +79,9 @@ void test_tree(
|
||||
// The tree doesn't have a 'last' element added since it's blank.
|
||||
ASSERT_THROW(tree.last(), std::runtime_error);
|
||||
|
||||
// The tree is empty.
|
||||
ASSERT_TRUE(tree.size() == 0);
|
||||
|
||||
// We need to witness at every single point in the tree, so
|
||||
// that the consistency of the tree and the merkle paths can
|
||||
// be checked.
|
||||
@@ -93,6 +96,9 @@ void test_tree(
|
||||
// Now append a commitment to the tree
|
||||
tree.append(test_commitment);
|
||||
|
||||
// Size incremented by one.
|
||||
ASSERT_TRUE(tree.size() == i+1);
|
||||
|
||||
// Last element added to the tree was `test_commitment`
|
||||
ASSERT_TRUE(tree.last() == test_commitment);
|
||||
|
||||
|
||||
@@ -22,6 +22,67 @@ typedef libsnark::default_r1cs_ppzksnark_pp::Fqe_type curve_Fq2;
|
||||
#include "version.h"
|
||||
#include "utilstrencodings.h"
|
||||
|
||||
TEST(proofs, g2_subgroup_check)
|
||||
{
|
||||
// all G2 elements are order r
|
||||
ASSERT_TRUE(libsnark::alt_bn128_modulus_r * curve_G2::random_element() == curve_G2::zero());
|
||||
|
||||
// but that doesn't mean all elements that satisfy the curve equation are in G2...
|
||||
curve_G2 p = curve_G2::one();
|
||||
|
||||
while (1) {
|
||||
// This will construct an order r(2q-r) point with high probability
|
||||
p.X = curve_Fq2::random_element();
|
||||
try {
|
||||
p.Y = ((p.X.squared() * p.X) + libsnark::alt_bn128_twist_coeff_b).sqrt();
|
||||
break;
|
||||
} catch(...) {}
|
||||
}
|
||||
|
||||
ASSERT_TRUE(p.is_well_formed()); // it's on the curve
|
||||
ASSERT_TRUE(libsnark::alt_bn128_modulus_r * p != curve_G2::zero()); // but not the order r subgroup..
|
||||
|
||||
{
|
||||
// libsnark unfortunately doesn't check, and the pairing will complete
|
||||
auto e = curve_Fr("149");
|
||||
auto a = curve_pp::reduced_pairing(curve_G1::one(), p);
|
||||
auto b = curve_pp::reduced_pairing(e * curve_G1::one(), p);
|
||||
|
||||
// though it will not preserve bilinearity
|
||||
ASSERT_TRUE((a^e) != b);
|
||||
}
|
||||
|
||||
{
|
||||
// so, our decompression API should not allow you to decompress G2 elements of that form!
|
||||
CompressedG2 badp(p);
|
||||
try {
|
||||
auto newp = badp.to_libsnark_g2<curve_G2>();
|
||||
FAIL() << "Expected std::runtime_error";
|
||||
} catch (std::runtime_error const & err) {
|
||||
EXPECT_EQ(err.what(), std::string("point is not in G2"));
|
||||
} catch(...) {
|
||||
FAIL() << "Expected std::runtime_error";
|
||||
}
|
||||
}
|
||||
|
||||
// educational purposes: showing that E'(Fp2) is of order r(2q-r),
|
||||
// by multiplying our random point in E' by (2q-r) = (q + q - r) to
|
||||
// get an element in G2
|
||||
{
|
||||
auto p1 = libsnark::alt_bn128_modulus_q * p;
|
||||
p1 = p1 + p1;
|
||||
p1 = p1 - (libsnark::alt_bn128_modulus_r * p);
|
||||
|
||||
ASSERT_TRUE(p1.is_well_formed());
|
||||
ASSERT_TRUE(libsnark::alt_bn128_modulus_r * p1 == curve_G2::zero());
|
||||
|
||||
CompressedG2 goodp(p1);
|
||||
auto newp = goodp.to_libsnark_g2<curve_G2>();
|
||||
|
||||
ASSERT_TRUE(newp == p1);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(proofs, sqrt_zero)
|
||||
{
|
||||
ASSERT_TRUE(curve_Fq::zero() == curve_Fq::zero().sqrt());
|
||||
|
||||
@@ -1,218 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "zcash/Address.hpp"
|
||||
#include "wallet/wallet.h"
|
||||
#include "wallet/walletdb.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
/**
|
||||
* This test covers methods on CWallet
|
||||
* GenerateNewZKey()
|
||||
* AddZKey()
|
||||
* LoadZKey()
|
||||
* LoadZKeyMetadata()
|
||||
*/
|
||||
TEST(wallet_zkeys_tests, store_and_load_zkeys) {
|
||||
SelectParams(CBaseChainParams::MAIN);
|
||||
|
||||
CWallet wallet;
|
||||
|
||||
// wallet should be empty
|
||||
std::set<libzcash::PaymentAddress> addrs;
|
||||
wallet.GetPaymentAddresses(addrs);
|
||||
ASSERT_EQ(0, addrs.size());
|
||||
|
||||
// wallet should have one key
|
||||
CZCPaymentAddress paymentAddress = wallet.GenerateNewZKey();
|
||||
wallet.GetPaymentAddresses(addrs);
|
||||
ASSERT_EQ(1, addrs.size());
|
||||
|
||||
// verify wallet has spending key for the address
|
||||
auto addr = paymentAddress.Get();
|
||||
ASSERT_TRUE(wallet.HaveSpendingKey(addr));
|
||||
|
||||
// manually add new spending key to wallet
|
||||
auto sk = libzcash::SpendingKey::random();
|
||||
ASSERT_TRUE(wallet.AddZKey(sk));
|
||||
|
||||
// verify wallet did add it
|
||||
addr = sk.address();
|
||||
ASSERT_TRUE(wallet.HaveSpendingKey(addr));
|
||||
|
||||
// verify spending key stored correctly
|
||||
libzcash::SpendingKey keyOut;
|
||||
wallet.GetSpendingKey(addr, keyOut);
|
||||
ASSERT_EQ(sk, keyOut);
|
||||
|
||||
// verify there are two keys
|
||||
wallet.GetPaymentAddresses(addrs);
|
||||
ASSERT_EQ(2, addrs.size());
|
||||
ASSERT_EQ(1, addrs.count(addr));
|
||||
|
||||
// Load a third key into the wallet
|
||||
sk = libzcash::SpendingKey::random();
|
||||
ASSERT_TRUE(wallet.LoadZKey(sk));
|
||||
|
||||
// attach metadata to this third key
|
||||
addr = sk.address();
|
||||
int64_t now = GetTime();
|
||||
CKeyMetadata meta(now);
|
||||
ASSERT_TRUE(wallet.LoadZKeyMetadata(addr, meta));
|
||||
|
||||
// check metadata is the same
|
||||
CKeyMetadata m= wallet.mapZKeyMetadata[addr];
|
||||
ASSERT_EQ(m.nCreateTime, now);
|
||||
}
|
||||
|
||||
/**
|
||||
* This test covers methods on CWalletDB
|
||||
* WriteZKey()
|
||||
*/
|
||||
TEST(wallet_zkeys_tests, write_zkey_direct_to_db) {
|
||||
SelectParams(CBaseChainParams::TESTNET);
|
||||
|
||||
// Get temporary and unique path for file.
|
||||
// Note: / operator to append paths
|
||||
boost::filesystem::path pathTemp = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path();
|
||||
boost::filesystem::create_directories(pathTemp);
|
||||
mapArgs["-datadir"] = pathTemp.string();
|
||||
|
||||
bool fFirstRun;
|
||||
CWallet wallet("wallet.dat");
|
||||
ASSERT_EQ(DB_LOAD_OK, wallet.LoadWallet(fFirstRun));
|
||||
|
||||
// No default CPubKey set
|
||||
ASSERT_TRUE(fFirstRun);
|
||||
|
||||
// wallet should be empty
|
||||
std::set<libzcash::PaymentAddress> addrs;
|
||||
wallet.GetPaymentAddresses(addrs);
|
||||
ASSERT_EQ(0, addrs.size());
|
||||
|
||||
// Add random key to the wallet
|
||||
auto paymentAddress = wallet.GenerateNewZKey();
|
||||
|
||||
// wallet should have one key
|
||||
wallet.GetPaymentAddresses(addrs);
|
||||
ASSERT_EQ(1, addrs.size());
|
||||
|
||||
// create random key and add it to database directly, bypassing wallet
|
||||
auto sk = libzcash::SpendingKey::random();
|
||||
auto addr = sk.address();
|
||||
int64_t now = GetTime();
|
||||
CKeyMetadata meta(now);
|
||||
CWalletDB db("wallet.dat");
|
||||
db.WriteZKey(addr, sk, meta);
|
||||
|
||||
// wallet should not be aware of key
|
||||
ASSERT_FALSE(wallet.HaveSpendingKey(addr));
|
||||
|
||||
// wallet sees one key
|
||||
wallet.GetPaymentAddresses(addrs);
|
||||
ASSERT_EQ(1, addrs.size());
|
||||
|
||||
// wallet should have default metadata for addr with null createtime
|
||||
CKeyMetadata m = wallet.mapZKeyMetadata[addr];
|
||||
ASSERT_EQ(m.nCreateTime, 0);
|
||||
ASSERT_NE(m.nCreateTime, now);
|
||||
|
||||
// load the wallet again
|
||||
ASSERT_EQ(DB_LOAD_OK, wallet.LoadWallet(fFirstRun));
|
||||
|
||||
// wallet can now see the spending key
|
||||
ASSERT_TRUE(wallet.HaveSpendingKey(addr));
|
||||
|
||||
// check key is the same
|
||||
libzcash::SpendingKey keyOut;
|
||||
wallet.GetSpendingKey(addr, keyOut);
|
||||
ASSERT_EQ(sk, keyOut);
|
||||
|
||||
// wallet should have two keys
|
||||
wallet.GetPaymentAddresses(addrs);
|
||||
ASSERT_EQ(2, addrs.size());
|
||||
|
||||
// check metadata is now the same
|
||||
m = wallet.mapZKeyMetadata[addr];
|
||||
ASSERT_EQ(m.nCreateTime, now);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This test covers methods on CWalletDB to load/save crypted z keys.
|
||||
*/
|
||||
TEST(wallet_zkeys_tests, write_cryptedzkey_direct_to_db) {
|
||||
ECC_Start();
|
||||
|
||||
SelectParams(CBaseChainParams::TESTNET);
|
||||
|
||||
// Get temporary and unique path for file.
|
||||
// Note: / operator to append paths
|
||||
boost::filesystem::path pathTemp = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path();
|
||||
boost::filesystem::create_directories(pathTemp);
|
||||
mapArgs["-datadir"] = pathTemp.string();
|
||||
|
||||
bool fFirstRun;
|
||||
CWallet wallet("wallet_crypted.dat");
|
||||
ASSERT_EQ(DB_LOAD_OK, wallet.LoadWallet(fFirstRun));
|
||||
|
||||
// No default CPubKey set
|
||||
ASSERT_TRUE(fFirstRun);
|
||||
|
||||
// wallet should be empty
|
||||
std::set<libzcash::PaymentAddress> addrs;
|
||||
wallet.GetPaymentAddresses(addrs);
|
||||
ASSERT_EQ(0, addrs.size());
|
||||
|
||||
// Add random key to the wallet
|
||||
auto paymentAddress = wallet.GenerateNewZKey();
|
||||
|
||||
// wallet should have one key
|
||||
wallet.GetPaymentAddresses(addrs);
|
||||
ASSERT_EQ(1, addrs.size());
|
||||
|
||||
// encrypt wallet
|
||||
SecureString strWalletPass;
|
||||
strWalletPass.reserve(100);
|
||||
strWalletPass = "hello";
|
||||
ASSERT_TRUE(wallet.EncryptWallet(strWalletPass));
|
||||
|
||||
// adding a new key will fail as the wallet is locked
|
||||
EXPECT_ANY_THROW(wallet.GenerateNewZKey());
|
||||
|
||||
// unlock wallet and then add
|
||||
wallet.Unlock(strWalletPass);
|
||||
auto paymentAddress2 = wallet.GenerateNewZKey();
|
||||
|
||||
// Create a new wallet from the existing wallet path
|
||||
CWallet wallet2("wallet_crypted.dat");
|
||||
ASSERT_EQ(DB_LOAD_OK, wallet2.LoadWallet(fFirstRun));
|
||||
|
||||
// Confirm it's not the same as the other wallet
|
||||
ASSERT_TRUE(&wallet != &wallet2);
|
||||
|
||||
// wallet should have two keys
|
||||
wallet2.GetPaymentAddresses(addrs);
|
||||
ASSERT_EQ(2, addrs.size());
|
||||
|
||||
// check we have entries for our payment addresses
|
||||
ASSERT_TRUE(addrs.count(paymentAddress.Get()));
|
||||
ASSERT_TRUE(addrs.count(paymentAddress2.Get()));
|
||||
|
||||
// spending key is crypted, so we can't extract valid payment address
|
||||
libzcash::SpendingKey keyOut;
|
||||
wallet2.GetSpendingKey(paymentAddress.Get(), keyOut);
|
||||
ASSERT_FALSE(paymentAddress.Get() == keyOut.address());
|
||||
|
||||
// unlock wallet to get spending keys and verify payment addresses
|
||||
wallet2.Unlock(strWalletPass);
|
||||
|
||||
wallet2.GetSpendingKey(paymentAddress.Get(), keyOut);
|
||||
ASSERT_EQ(paymentAddress.Get(), keyOut.address());
|
||||
|
||||
wallet2.GetSpendingKey(paymentAddress2.Get(), keyOut);
|
||||
ASSERT_EQ(paymentAddress2.Get(), keyOut.address());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user