Major updates integration from all upstreams

This commit is contained in:
miketout
2018-09-18 14:33:53 -07:00
396 changed files with 25517 additions and 6854 deletions

View File

@@ -9,26 +9,31 @@
#include "tinyformat.h"
#include "utilstrencodings.h"
JSDescription::JSDescription(ZCJoinSplit& params,
const uint256& pubKeyHash,
const uint256& anchor,
const boost::array<libzcash::JSInput, ZC_NUM_JS_INPUTS>& inputs,
const boost::array<libzcash::JSOutput, ZC_NUM_JS_OUTPUTS>& outputs,
CAmount vpub_old,
CAmount vpub_new,
bool computeProof,
uint256 *esk // payment disclosure
) : vpub_old(vpub_old), vpub_new(vpub_new), anchor(anchor)
#include "librustzcash.h"
JSDescription::JSDescription(
bool makeGrothProof,
ZCJoinSplit& params,
const uint256& joinSplitPubKey,
const uint256& anchor,
const std::array<libzcash::JSInput, ZC_NUM_JS_INPUTS>& inputs,
const std::array<libzcash::JSOutput, ZC_NUM_JS_OUTPUTS>& outputs,
CAmount vpub_old,
CAmount vpub_new,
bool computeProof,
uint256 *esk // payment disclosure
) : vpub_old(vpub_old), vpub_new(vpub_new), anchor(anchor)
{
boost::array<libzcash::Note, ZC_NUM_JS_OUTPUTS> notes;
std::array<libzcash::SproutNote, ZC_NUM_JS_OUTPUTS> notes;
proof = params.prove(
makeGrothProof,
inputs,
outputs,
notes,
ciphertexts,
ephemeralKey,
pubKeyHash,
joinSplitPubKey,
randomSeed,
macs,
nullifiers,
@@ -42,24 +47,20 @@ JSDescription::JSDescription(ZCJoinSplit& params,
}
JSDescription JSDescription::Randomized(
ZCJoinSplit& params,
const uint256& pubKeyHash,
const uint256& anchor,
boost::array<libzcash::JSInput, ZC_NUM_JS_INPUTS>& inputs,
boost::array<libzcash::JSOutput, ZC_NUM_JS_OUTPUTS>& outputs,
#ifdef __LP64__
boost::array<uint64_t, ZC_NUM_JS_INPUTS>& inputMap,
boost::array<uint64_t, ZC_NUM_JS_OUTPUTS>& outputMap,
#else
boost::array<size_t, ZC_NUM_JS_INPUTS>& inputMap,
boost::array<size_t, ZC_NUM_JS_OUTPUTS>& outputMap,
#endif
CAmount vpub_old,
CAmount vpub_new,
bool computeProof,
uint256 *esk, // payment disclosure
std::function<int(int)> gen
)
bool makeGrothProof,
ZCJoinSplit& params,
const uint256& joinSplitPubKey,
const uint256& anchor,
std::array<libzcash::JSInput, ZC_NUM_JS_INPUTS>& inputs,
std::array<libzcash::JSOutput, ZC_NUM_JS_OUTPUTS>& outputs,
std::array<size_t, ZC_NUM_JS_INPUTS>& inputMap,
std::array<size_t, ZC_NUM_JS_OUTPUTS>& outputMap,
CAmount vpub_old,
CAmount vpub_new,
bool computeProof,
uint256 *esk, // payment disclosure
std::function<int(int)> gen
)
{
// Randomize the order of the inputs and outputs
inputMap = {0, 1};
@@ -71,34 +72,76 @@ JSDescription JSDescription::Randomized(
MappedShuffle(outputs.begin(), outputMap.begin(), ZC_NUM_JS_OUTPUTS, gen);
return JSDescription(
params, pubKeyHash, anchor, inputs, outputs,
makeGrothProof,
params, joinSplitPubKey, anchor, inputs, outputs,
vpub_old, vpub_new, computeProof,
esk // payment disclosure
);
}
class SproutProofVerifier : public boost::static_visitor<bool>
{
ZCJoinSplit& params;
libzcash::ProofVerifier& verifier;
const uint256& joinSplitPubKey;
const JSDescription& jsdesc;
public:
SproutProofVerifier(
ZCJoinSplit& params,
libzcash::ProofVerifier& verifier,
const uint256& joinSplitPubKey,
const JSDescription& jsdesc
) : params(params), jsdesc(jsdesc), verifier(verifier), joinSplitPubKey(joinSplitPubKey) {}
bool operator()(const libzcash::PHGRProof& proof) const
{
return params.verify(
proof,
verifier,
joinSplitPubKey,
jsdesc.randomSeed,
jsdesc.macs,
jsdesc.nullifiers,
jsdesc.commitments,
jsdesc.vpub_old,
jsdesc.vpub_new,
jsdesc.anchor
);
}
bool operator()(const libzcash::GrothProof& proof) const
{
uint256 h_sig = params.h_sig(jsdesc.randomSeed, jsdesc.nullifiers, joinSplitPubKey);
return librustzcash_sprout_verify(
proof.begin(),
jsdesc.anchor.begin(),
h_sig.begin(),
jsdesc.macs[0].begin(),
jsdesc.macs[1].begin(),
jsdesc.nullifiers[0].begin(),
jsdesc.nullifiers[1].begin(),
jsdesc.commitments[0].begin(),
jsdesc.commitments[1].begin(),
jsdesc.vpub_old,
jsdesc.vpub_new
);
}
};
bool JSDescription::Verify(
ZCJoinSplit& params,
libzcash::ProofVerifier& verifier,
const uint256& pubKeyHash
const uint256& joinSplitPubKey
) const {
return params.verify(
proof,
verifier,
pubKeyHash,
randomSeed,
macs,
nullifiers,
commitments,
vpub_old,
vpub_new,
anchor
);
auto pv = SproutProofVerifier(params, verifier, joinSplitPubKey, *this);
return boost::apply_visitor(pv, proof);
}
uint256 JSDescription::h_sig(ZCJoinSplit& params, const uint256& pubKeyHash) const
uint256 JSDescription::h_sig(ZCJoinSplit& params, const uint256& joinSplitPubKey) const
{
return params.h_sig(randomSeed, nullifiers, pubKeyHash);
return params.h_sig(randomSeed, nullifiers, joinSplitPubKey);
}
std::string COutPoint::ToString() const
@@ -106,6 +149,11 @@ std::string COutPoint::ToString() const
return strprintf("COutPoint(%s, %u)", hash.ToString().substr(0,10), n);
}
std::string SaplingOutPoint::ToString() const
{
return strprintf("SaplingOutPoint(%s, %u)", hash.ToString().substr(0, 10), n);
}
CTxIn::CTxIn(COutPoint prevoutIn, CScript scriptSigIn, uint32_t nSequenceIn)
{
prevout = prevoutIn;
@@ -128,7 +176,7 @@ std::string CTxIn::ToString() const
if (prevout.IsNull())
str += strprintf(", coinbase %s", HexStr(scriptSig));
else
str += strprintf(", scriptSig=%s", scriptSig.ToString().substr(0,24));
str += strprintf(", scriptSig=%s", HexStr(scriptSig).substr(0, 24));
if (nSequence != std::numeric_limits<unsigned int>::max())
str += strprintf(", nSequence=%u", nSequence);
str += ")";
@@ -148,13 +196,15 @@ uint256 CTxOut::GetHash() const
std::string CTxOut::ToString() const
{
return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, scriptPubKey.ToString().substr(0,30));
return strprintf("CTxOut(nValue=%d.%08d, scriptPubKey=%s)", nValue / COIN, nValue % COIN, HexStr(scriptPubKey).substr(0, 30));
}
CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::SPROUT_MIN_CURRENT_VERSION), fOverwintered(false), nVersionGroupId(0), nExpiryHeight(0), nLockTime(0) {}
CMutableTransaction::CMutableTransaction() : nVersion(CTransaction::SPROUT_MIN_CURRENT_VERSION), fOverwintered(false), nVersionGroupId(0), nExpiryHeight(0), nLockTime(0), valueBalance(0) {}
CMutableTransaction::CMutableTransaction(const CTransaction& tx) : nVersion(tx.nVersion), fOverwintered(tx.fOverwintered), nVersionGroupId(tx.nVersionGroupId), nExpiryHeight(tx.nExpiryHeight),
vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime),
vjoinsplit(tx.vjoinsplit), joinSplitPubKey(tx.joinSplitPubKey), joinSplitSig(tx.joinSplitSig)
valueBalance(tx.valueBalance), vShieldedSpend(tx.vShieldedSpend), vShieldedOutput(tx.vShieldedOutput),
vjoinsplit(tx.vjoinsplit), joinSplitPubKey(tx.joinSplitPubKey), joinSplitSig(tx.joinSplitSig),
bindingSig(tx.bindingSig)
{
}
@@ -169,11 +219,13 @@ void CTransaction::UpdateHash() const
*const_cast<uint256*>(&hash) = SerializeHash(*this);
}
CTransaction::CTransaction() : nVersion(CTransaction::SPROUT_MIN_CURRENT_VERSION), fOverwintered(false), nVersionGroupId(0), nExpiryHeight(0), vin(), vout(), nLockTime(0), vjoinsplit(), joinSplitPubKey(), joinSplitSig() { }
CTransaction::CTransaction() : nVersion(CTransaction::SPROUT_MIN_CURRENT_VERSION), fOverwintered(false), nVersionGroupId(0), nExpiryHeight(0), vin(), vout(), nLockTime(0), valueBalance(0), vShieldedSpend(), vShieldedOutput(), vjoinsplit(), joinSplitPubKey(), joinSplitSig(), bindingSig() { }
CTransaction::CTransaction(const CMutableTransaction &tx) : nVersion(tx.nVersion), fOverwintered(tx.fOverwintered), nVersionGroupId(tx.nVersionGroupId), nExpiryHeight(tx.nExpiryHeight),
vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime),
vjoinsplit(tx.vjoinsplit), joinSplitPubKey(tx.joinSplitPubKey), joinSplitSig(tx.joinSplitSig)
valueBalance(tx.valueBalance), vShieldedSpend(tx.vShieldedSpend), vShieldedOutput(tx.vShieldedOutput),
vjoinsplit(tx.vjoinsplit), joinSplitPubKey(tx.joinSplitPubKey), joinSplitSig(tx.joinSplitSig),
bindingSig(tx.bindingSig)
{
UpdateHash();
}
@@ -184,11 +236,23 @@ CTransaction::CTransaction(
const CMutableTransaction &tx,
bool evilDeveloperFlag) : nVersion(tx.nVersion), fOverwintered(tx.fOverwintered), nVersionGroupId(tx.nVersionGroupId), nExpiryHeight(tx.nExpiryHeight),
vin(tx.vin), vout(tx.vout), nLockTime(tx.nLockTime),
vjoinsplit(tx.vjoinsplit), joinSplitPubKey(tx.joinSplitPubKey), joinSplitSig(tx.joinSplitSig)
valueBalance(tx.valueBalance), vShieldedSpend(tx.vShieldedSpend), vShieldedOutput(tx.vShieldedOutput),
vjoinsplit(tx.vjoinsplit), joinSplitPubKey(tx.joinSplitPubKey), joinSplitSig(tx.joinSplitSig),
bindingSig(tx.bindingSig)
{
assert(evilDeveloperFlag);
}
CTransaction::CTransaction(CMutableTransaction &&tx) : nVersion(tx.nVersion), fOverwintered(tx.fOverwintered), nVersionGroupId(tx.nVersionGroupId),
vin(std::move(tx.vin)), vout(std::move(tx.vout)), nLockTime(tx.nLockTime), nExpiryHeight(tx.nExpiryHeight),
valueBalance(tx.valueBalance),
vShieldedSpend(std::move(tx.vShieldedSpend)), vShieldedOutput(std::move(tx.vShieldedOutput)),
vjoinsplit(std::move(tx.vjoinsplit)),
joinSplitPubKey(std::move(tx.joinSplitPubKey)), joinSplitSig(std::move(tx.joinSplitSig))
{
UpdateHash();
}
CTransaction& CTransaction::operator=(const CTransaction &tx) {
*const_cast<bool*>(&fOverwintered) = tx.fOverwintered;
*const_cast<int*>(&nVersion) = tx.nVersion;
@@ -197,9 +261,13 @@ CTransaction& CTransaction::operator=(const CTransaction &tx) {
*const_cast<std::vector<CTxOut>*>(&vout) = tx.vout;
*const_cast<unsigned int*>(&nLockTime) = tx.nLockTime;
*const_cast<uint32_t*>(&nExpiryHeight) = tx.nExpiryHeight;
*const_cast<CAmount*>(&valueBalance) = tx.valueBalance;
*const_cast<std::vector<SpendDescription>*>(&vShieldedSpend) = tx.vShieldedSpend;
*const_cast<std::vector<OutputDescription>*>(&vShieldedOutput) = tx.vShieldedOutput;
*const_cast<std::vector<JSDescription>*>(&vjoinsplit) = tx.vjoinsplit;
*const_cast<uint256*>(&joinSplitPubKey) = tx.joinSplitPubKey;
*const_cast<joinsplit_sig_t*>(&joinSplitSig) = tx.joinSplitSig;
*const_cast<binding_sig_t*>(&bindingSig) = tx.bindingSig;
*const_cast<uint256*>(&hash) = tx.hash;
return *this;
}
@@ -214,9 +282,18 @@ CAmount CTransaction::GetValueOut() const
throw std::runtime_error("CTransaction::GetValueOut(): value out of range");
}
if (valueBalance <= 0) {
// NB: negative valueBalance "takes" money from the transparent value pool just as outputs do
nValueOut += -valueBalance;
if (!MoneyRange(-valueBalance) || !MoneyRange(nValueOut)) {
throw std::runtime_error("CTransaction::GetValueOut(): value out of range");
}
}
for (std::vector<JSDescription>::const_iterator it(vjoinsplit.begin()); it != vjoinsplit.end(); ++it)
{
// NB: vpub_old "takes" money from the value pool just as outputs do
// NB: vpub_old "takes" money from the transparent value pool just as outputs do
nValueOut += it->vpub_old;
if (!MoneyRange(it->vpub_old) || !MoneyRange(nValueOut))
@@ -225,31 +302,26 @@ CAmount CTransaction::GetValueOut() const
return nValueOut;
}
CAmount CTransaction::GetJoinSplitValueIn() const
CAmount CTransaction::GetShieldedValueIn() const
{
CAmount nValue = 0;
if (valueBalance >= 0) {
// NB: positive valueBalance "gives" money to the transparent value pool just as inputs do
nValue += valueBalance;
if (!MoneyRange(valueBalance) || !MoneyRange(nValue)) {
throw std::runtime_error("CTransaction::GetShieldedValueIn(): value out of range");
}
}
for (std::vector<JSDescription>::const_iterator it(vjoinsplit.begin()); it != vjoinsplit.end(); ++it)
{
// NB: vpub_new "gives" money to the value pool just as inputs do
// NB: vpub_new "gives" money to the transparent value pool just as inputs do
nValue += it->vpub_new;
if (!MoneyRange(it->vpub_new) || !MoneyRange(nValue))
throw std::runtime_error("CTransaction::GetJoinSplitValueIn(): value out of range");
}
return nValue;
}
CAmount CTransaction::GetJoinSplitValueOut() const
{
CAmount nValue = 0;
for (std::vector<JSDescription>::const_iterator it(vjoinsplit.begin()); it != vjoinsplit.end(); ++it)
{
// NB: vpub_new "gives" money to the value pool just as inputs do
nValue += it->vpub_old;
if (!MoneyRange(it->vpub_old) || !MoneyRange(nValue))
throw std::runtime_error("CTransaction::GetJoinSplitValueOut(): value out of range");
throw std::runtime_error("CTransaction::GetShieldedValueIn(): value out of range");
}
return nValue;
@@ -321,6 +393,19 @@ std::string CTransaction::ToString() const
vin.size(),
vout.size(),
nLockTime);
} else if (nVersion >= SAPLING_MIN_TX_VERSION) {
str += strprintf("CTransaction(hash=%s, ver=%d, fOverwintered=%d, nVersionGroupId=%08x, vin.size=%u, vout.size=%u, nLockTime=%u, nExpiryHeight=%u, valueBalance=%u, vShieldedSpend.size=%u, vShieldedOutput.size=%u)\n",
GetHash().ToString().substr(0,10),
nVersion,
fOverwintered,
nVersionGroupId,
vin.size(),
vout.size(),
nLockTime,
nExpiryHeight,
valueBalance,
vShieldedSpend.size(),
vShieldedOutput.size());
} else if (nVersion >= 3) {
str += strprintf("CTransaction(hash=%s, ver=%d, fOverwintered=%d, nVersionGroupId=%08x, vin.size=%u, vout.size=%u, nLockTime=%u, nExpiryHeight=%u)\n",
GetHash().ToString().substr(0,10),