|
|
@ -24,8 +24,16 @@ |
|
|
|
#include <boost/assign/list_of.hpp> |
|
|
|
#include "json/json_spirit_writer_template.h" |
|
|
|
|
|
|
|
#include "libzerocash/ZerocashParams.h" |
|
|
|
#include "libzerocash/IncrementalMerkleTree.h" |
|
|
|
#include "libzerocash/PourInput.h" |
|
|
|
#include "libzerocash/PourOutput.h" |
|
|
|
#include "libzerocash/Address.h" |
|
|
|
#include "libzerocash/Coin.h" |
|
|
|
|
|
|
|
using namespace std; |
|
|
|
using namespace json_spirit; |
|
|
|
using namespace libzerocash; |
|
|
|
|
|
|
|
// In script_tests.cpp
|
|
|
|
extern Array read_json(const std::string& jsondata); |
|
|
@ -285,6 +293,95 @@ SetupDummyInputs(CBasicKeyStore& keystoreRet, CCoinsViewCache& coinsRet) |
|
|
|
return dummyTransactions; |
|
|
|
} |
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(test_basic_pour_verification) |
|
|
|
{ |
|
|
|
// We only check that pours are constructed properly
|
|
|
|
// and verify properly here. libsnark tends to segfault
|
|
|
|
// when our snarks or what-have-you are invalid, so
|
|
|
|
// we can't really catch everything here.
|
|
|
|
//
|
|
|
|
// See #471, #520, #459 and probably others.
|
|
|
|
//
|
|
|
|
// There may be ways to use boost tests to catch failing
|
|
|
|
// threads or processes (?) but they appear to not work
|
|
|
|
// on all platforms and would gently push us down an ugly
|
|
|
|
// path. We should just fix the assertions.
|
|
|
|
//
|
|
|
|
// Also, it's generally libzerocash's job to ensure
|
|
|
|
// the integrity of the scheme through its own tests.
|
|
|
|
|
|
|
|
static const unsigned int TEST_TREE_DEPTH = 3; |
|
|
|
|
|
|
|
// construct the r1cs keypair
|
|
|
|
auto keypair = ZerocashParams::GenerateNewKeyPair(TEST_TREE_DEPTH); |
|
|
|
ZerocashParams p( |
|
|
|
TEST_TREE_DEPTH, |
|
|
|
&keypair |
|
|
|
); |
|
|
|
|
|
|
|
// construct a merkle tree
|
|
|
|
IncrementalMerkleTree merkleTree(TEST_TREE_DEPTH); |
|
|
|
Address addr = Address::CreateNewRandomAddress(); |
|
|
|
Coin coin(addr.getPublicAddress(), 100); |
|
|
|
|
|
|
|
// commitment from coin
|
|
|
|
std::vector<bool> commitment(ZC_CM_SIZE * 8); |
|
|
|
convertBytesVectorToVector(coin.getCoinCommitment().getCommitmentValue(), commitment); |
|
|
|
|
|
|
|
// insert commitment into the merkle tree
|
|
|
|
std::vector<bool> index; |
|
|
|
merkleTree.insertElement(commitment, index); |
|
|
|
|
|
|
|
// compute the merkle root we will be working with
|
|
|
|
vector<unsigned char> rt(ZC_ROOT_SIZE); |
|
|
|
{ |
|
|
|
vector<bool> root_bv(ZC_ROOT_SIZE * 8); |
|
|
|
merkleTree.getRootValue(root_bv); |
|
|
|
convertVectorToBytesVector(root_bv, rt); |
|
|
|
} |
|
|
|
|
|
|
|
merkle_authentication_path path(TEST_TREE_DEPTH); |
|
|
|
merkleTree.getWitness(index, path); |
|
|
|
|
|
|
|
// create CPourTx
|
|
|
|
CScript scriptPubKey; |
|
|
|
boost::array<PourInput, 2> inputs = { |
|
|
|
PourInput(coin, addr, convertVectorToInt(index), path), |
|
|
|
PourInput(TEST_TREE_DEPTH) // dummy input of zero value
|
|
|
|
}; |
|
|
|
boost::array<PourOutput, 2> outputs = { |
|
|
|
PourOutput(50), |
|
|
|
PourOutput(50) |
|
|
|
}; |
|
|
|
|
|
|
|
{ |
|
|
|
CPourTx pourtx(p, scriptPubKey, uint256(rt), inputs, outputs, 0, 0); |
|
|
|
BOOST_CHECK(pourtx.Verify(p)); |
|
|
|
|
|
|
|
CDataStream ss(SER_DISK, CLIENT_VERSION); |
|
|
|
ss << pourtx; |
|
|
|
|
|
|
|
CPourTx pourtx_deserialized; |
|
|
|
ss >> pourtx_deserialized; |
|
|
|
|
|
|
|
BOOST_CHECK(pourtx_deserialized == pourtx); |
|
|
|
BOOST_CHECK(pourtx_deserialized.Verify(p)); |
|
|
|
} |
|
|
|
|
|
|
|
{ |
|
|
|
// Ensure that the balance equation is working.
|
|
|
|
BOOST_CHECK_THROW(CPourTx(p, scriptPubKey, uint256(rt), inputs, outputs, 10, 0), std::invalid_argument); |
|
|
|
BOOST_CHECK_THROW(CPourTx(p, scriptPubKey, uint256(rt), inputs, outputs, 0, 10), std::invalid_argument); |
|
|
|
} |
|
|
|
|
|
|
|
{ |
|
|
|
// Ensure that it won't verify if the root is changed.
|
|
|
|
auto test = CPourTx(p, scriptPubKey, uint256(rt), inputs, outputs, 0, 0); |
|
|
|
test.anchor = GetRandHash(); |
|
|
|
BOOST_CHECK(!test.Verify(p)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(test_simple_pour_invalidity) |
|
|
|
{ |
|
|
|
CMutableTransaction tx; |
|
|
|