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

@@ -191,7 +191,7 @@ bool static IsDefinedHashtypeSignature(const valtype &vchSig) {
return true;
}
bool static CheckSignatureEncoding(const valtype &vchSig, unsigned int flags, ScriptError* serror) {
bool CheckSignatureEncoding(const vector<unsigned char> &vchSig, unsigned int flags, ScriptError* serror) {
// Empty signature. Not strictly DER encoded, but allowed to provide a
// compact way to provide an invalid signature for use with CHECK(MULTI)SIG
if (vchSig.size() == 0) {
@@ -1018,7 +1018,7 @@ public:
/** Serialize the passed scriptCode */
template<typename S>
void SerializeScriptCode(S &s, int nType, int nVersion) const {
void SerializeScriptCode(S &s) const {
auto size = scriptCode.size();
::WriteCompactSize(s, size);
s.write((char*)&scriptCode.begin()[0], size);
@@ -1026,54 +1026,54 @@ public:
/** Serialize an input of txTo */
template<typename S>
void SerializeInput(S &s, unsigned int nInput, int nType, int nVersion) const {
void SerializeInput(S &s, unsigned int nInput) const {
// In case of SIGHASH_ANYONECANPAY, only the input being signed is serialized
if (fAnyoneCanPay)
nInput = nIn;
// Serialize the prevout
::Serialize(s, txTo.vin[nInput].prevout, nType, nVersion);
::Serialize(s, txTo.vin[nInput].prevout);
// Serialize the script
assert(nInput != NOT_AN_INPUT);
if (nInput != nIn)
// Blank out other inputs' signatures
::Serialize(s, CScript(), nType, nVersion);
::Serialize(s, CScriptBase());
else
SerializeScriptCode(s, nType, nVersion);
SerializeScriptCode(s);
// Serialize the nSequence
if (nInput != nIn && (fHashSingle || fHashNone))
// let the others update at will
::Serialize(s, (int)0, nType, nVersion);
::Serialize(s, (int)0);
else
::Serialize(s, txTo.vin[nInput].nSequence, nType, nVersion);
::Serialize(s, txTo.vin[nInput].nSequence);
}
/** Serialize an output of txTo */
template<typename S>
void SerializeOutput(S &s, unsigned int nOutput, int nType, int nVersion) const {
void SerializeOutput(S &s, unsigned int nOutput) const {
if (fHashSingle && nOutput != nIn)
// Do not lock-in the txout payee at other indices as txin
::Serialize(s, CTxOut(), nType, nVersion);
::Serialize(s, CTxOut());
else
::Serialize(s, txTo.vout[nOutput], nType, nVersion);
::Serialize(s, txTo.vout[nOutput]);
}
/** Serialize txTo */
template<typename S>
void Serialize(S &s, int nType, int nVersion) const {
void Serialize(S &s) const {
// Serialize nVersion
::Serialize(s, txTo.nVersion, nType, nVersion);
::Serialize(s, txTo.nVersion);
// Serialize vin
unsigned int nInputs = fAnyoneCanPay ? 1 : txTo.vin.size();
::WriteCompactSize(s, nInputs);
for (unsigned int nInput = 0; nInput < nInputs; nInput++)
SerializeInput(s, nInput, nType, nVersion);
SerializeInput(s, nInput);
// Serialize vout
unsigned int nOutputs = fHashNone ? 0 : (fHashSingle ? nIn+1 : txTo.vout.size());
::WriteCompactSize(s, nOutputs);
for (unsigned int nOutput = 0; nOutput < nOutputs; nOutput++)
SerializeOutput(s, nOutput, nType, nVersion);
SerializeOutput(s, nOutput);
// Serialize nLockTime
::Serialize(s, txTo.nLockTime, nType, nVersion);
::Serialize(s, txTo.nLockTime);
// Serialize vjoinsplit
if (txTo.nVersion >= 2) {
@@ -1083,12 +1083,12 @@ public:
// keeps the JoinSplit cryptographically bound
// to the transaction.
//
::Serialize(s, txTo.vjoinsplit, nType, nVersion);
::Serialize(s, txTo.vjoinsplit);
if (txTo.vjoinsplit.size() > 0) {
::Serialize(s, txTo.joinSplitPubKey, nType, nVersion);
::Serialize(s, txTo.joinSplitPubKey);
CTransaction::joinsplit_sig_t nullSig = {};
::Serialize(s, nullSig, nType, nVersion);
::Serialize(s, nullSig);
}
}
}
@@ -1102,6 +1102,10 @@ const unsigned char ZCASH_OUTPUTS_HASH_PERSONALIZATION[crypto_generichash_blake2
{'Z','c','a','s','h','O','u','t','p','u','t','s','H','a','s','h'};
const unsigned char ZCASH_JOINSPLITS_HASH_PERSONALIZATION[crypto_generichash_blake2b_PERSONALBYTES] =
{'Z','c','a','s','h','J','S','p','l','i','t','s','H','a','s','h'};
const unsigned char ZCASH_SHIELDED_SPENDS_HASH_PERSONALIZATION[crypto_generichash_blake2b_PERSONALBYTES] =
{'Z','c','a','s','h','S','S','p','e','n','d','s','H','a','s','h'};
const unsigned char ZCASH_SHIELDED_OUTPUTS_HASH_PERSONALIZATION[crypto_generichash_blake2b_PERSONALBYTES] =
{'Z','c','a','s','h','S','O','u','t','p','u','t','H','a','s','h'};
uint256 GetPrevoutHash(const CTransaction& txTo) {
CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_PREVOUTS_HASH_PERSONALIZATION);
@@ -1128,7 +1132,7 @@ uint256 GetOutputsHash(const CTransaction& txTo) {
}
uint256 GetJoinSplitsHash(const CTransaction& txTo) {
CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_JOINSPLITS_HASH_PERSONALIZATION);
CBLAKE2bWriter ss(SER_GETHASH, static_cast<int>(txTo.GetHeader()), ZCASH_JOINSPLITS_HASH_PERSONALIZATION);
for (unsigned int n = 0; n < txTo.vjoinsplit.size(); n++) {
ss << txTo.vjoinsplit[n];
}
@@ -1136,6 +1140,26 @@ uint256 GetJoinSplitsHash(const CTransaction& txTo) {
return ss.GetHash();
}
uint256 GetShieldedSpendsHash(const CTransaction& txTo) {
CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_SHIELDED_SPENDS_HASH_PERSONALIZATION);
for (unsigned int n = 0; n < txTo.vShieldedSpend.size(); n++) {
ss << txTo.vShieldedSpend[n].cv;
ss << txTo.vShieldedSpend[n].anchor;
ss << txTo.vShieldedSpend[n].nullifier;
ss << txTo.vShieldedSpend[n].rk;
ss << txTo.vShieldedSpend[n].zkproof;
}
return ss.GetHash();
}
uint256 GetShieldedOutputsHash(const CTransaction& txTo) {
CBLAKE2bWriter ss(SER_GETHASH, 0, ZCASH_SHIELDED_OUTPUTS_HASH_PERSONALIZATION);
for (unsigned int n = 0; n < txTo.vShieldedOutput.size(); n++) {
ss << txTo.vShieldedOutput[n];
}
return ss.GetHash();
}
} // anon namespace
PrecomputedTransactionData::PrecomputedTransactionData(const CTransaction& txTo)
@@ -1144,12 +1168,18 @@ PrecomputedTransactionData::PrecomputedTransactionData(const CTransaction& txTo)
hashSequence = GetSequenceHash(txTo);
hashOutputs = GetOutputsHash(txTo);
hashJoinSplits = GetJoinSplitsHash(txTo);
hashShieldedSpends = GetShieldedSpendsHash(txTo);
hashShieldedOutputs = GetShieldedOutputsHash(txTo);
}
SigVersion SignatureHashVersion(const CTransaction& txTo)
{
if (txTo.fOverwintered) {
return SIGVERSION_OVERWINTER;
if (txTo.nVersionGroupId == SAPLING_VERSION_GROUP_ID) {
return SIGVERSION_SAPLING;
} else {
return SIGVERSION_OVERWINTER;
}
} else {
return SIGVERSION_SPROUT;
}
@@ -1171,11 +1201,13 @@ uint256 SignatureHash(
auto sigversion = SignatureHashVersion(txTo);
if (sigversion == SIGVERSION_OVERWINTER) {
if (sigversion == SIGVERSION_OVERWINTER || sigversion == SIGVERSION_SAPLING) {
uint256 hashPrevouts;
uint256 hashSequence;
uint256 hashOutputs;
uint256 hashJoinSplits;
uint256 hashShieldedSpends;
uint256 hashShieldedOutputs;
if (!(nHashType & SIGHASH_ANYONECANPAY)) {
hashPrevouts = cache ? cache->hashPrevouts : GetPrevoutHash(txTo);
@@ -1197,6 +1229,14 @@ uint256 SignatureHash(
hashJoinSplits = cache ? cache->hashJoinSplits : GetJoinSplitsHash(txTo);
}
if (!txTo.vShieldedSpend.empty()) {
hashShieldedSpends = cache ? cache->hashShieldedSpends : GetShieldedSpendsHash(txTo);
}
if (!txTo.vShieldedOutput.empty()) {
hashShieldedOutputs = cache ? cache->hashShieldedOutputs : GetShieldedOutputsHash(txTo);
}
uint32_t leConsensusBranchId = htole32(consensusBranchId);
unsigned char personalization[16] = {};
memcpy(personalization, "ZcashSigHash", 12);
@@ -1214,10 +1254,20 @@ uint256 SignatureHash(
ss << hashOutputs;
// JoinSplits
ss << hashJoinSplits;
if (sigversion == SIGVERSION_SAPLING) {
// Spend descriptions
ss << hashShieldedSpends;
// Output descriptions
ss << hashShieldedOutputs;
}
// Locktime
ss << txTo.nLockTime;
// Expiry height
ss << txTo.nExpiryHeight;
if (sigversion == SIGVERSION_SAPLING) {
// Sapling value balance
ss << txTo.valueBalance;
}
// Sighash type
ss << nHashType;
@@ -1228,7 +1278,7 @@ uint256 SignatureHash(
// The prevout may already be contained in hashPrevout, and the nSequence
// may already be contained in hashSequence.
ss << txTo.vin[nIn].prevout;
ss << scriptCode;
ss << static_cast<const CScriptBase&>(scriptCode);
ss << amount;
ss << txTo.vin[nIn].nSequence;
}

View File

@@ -89,9 +89,11 @@ enum
SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9),
};
bool CheckSignatureEncoding(const std::vector<unsigned char> &vchSig, unsigned int flags, ScriptError* serror);
struct PrecomputedTransactionData
{
uint256 hashPrevouts, hashSequence, hashOutputs, hashJoinSplits;
uint256 hashPrevouts, hashSequence, hashOutputs, hashJoinSplits, hashShieldedSpends, hashShieldedOutputs;
PrecomputedTransactionData(const CTransaction& tx);
};
@@ -100,6 +102,7 @@ enum SigVersion
{
SIGVERSION_SPROUT = 0,
SIGVERSION_OVERWINTER = 1,
SIGVERSION_SAPLING = 2,
};
uint256 SignatureHash(

View File

@@ -11,19 +11,18 @@
#include "cc/eval.h"
#include "cryptoconditions/include/cryptoconditions.h"
using namespace std;
namespace {
inline std::string ValueString(const std::vector<unsigned char>& vch)
{
if (vch.size() <= 4)
return strprintf("%d", CScriptNum(vch, false).getint());
else
return HexStr(vch);
}
inline std::string ValueString(const std::vector<unsigned char>& vch)
{
if (vch.size() <= 4)
return strprintf("%d", CScriptNum(vch, false).getint());
else
return HexStr(vch);
}
} // anon namespace
using namespace std;
const char* GetOpName(opcodetype opcode)
{
switch (opcode)
@@ -241,9 +240,9 @@ bool CScript::IsPayToScriptHash() const
{
// Extra-fast test for pay-to-script-hash CScripts:
return (this->size() == 23 &&
this->at(0) == OP_HASH160 &&
this->at(1) == 0x14 &&
this->at(22) == OP_EQUAL);
(*this)[0] == OP_HASH160 &&
(*this)[1] == 0x14 &&
(*this)[22] == OP_EQUAL);
}
bool CScript::IsPayToCryptoCondition() const
@@ -316,7 +315,7 @@ bool CScript::IsCheckLockTimeVerify(int64_t *unlockTime) const
if (this->GetOp2(it, op, &unlockTimeParam))
{
if (unlockTimeParam.size() >= 0 && unlockTimeParam.size() < 6 &&
*(this->data() + unlockTimeParam.size() + 1) == OP_CHECKLOCKTIMEVERIFY)
(*this)[unlockTimeParam.size() + 1] == OP_CHECKLOCKTIMEVERIFY)
{
int i = unlockTimeParam.size() - 1;
for (*unlockTime = 0; i >= 0; i--)

View File

@@ -7,6 +7,7 @@
#define BITCOIN_SCRIPT_SCRIPT_H
#include "crypto/common.h"
#include "prevector.h"
#include <assert.h>
#include <climits>
@@ -358,8 +359,10 @@ private:
int64_t m_value;
};
typedef prevector<28, unsigned char> CScriptBase;
/** Serialized script, used inside transaction inputs and outputs */
class CScript : public std::vector<unsigned char>
class CScript : public CScriptBase
{
protected:
CScript& push_int64(int64_t n)
@@ -380,9 +383,10 @@ protected:
}
public:
CScript() { }
CScript(const CScript& b) : std::vector<unsigned char>(b.begin(), b.end()) { }
CScript(const_iterator pbegin, const_iterator pend) : std::vector<unsigned char>(pbegin, pend) { }
CScript(const unsigned char* pbegin, const unsigned char* pend) : std::vector<unsigned char>(pbegin, pend) { }
CScript(const CScript& b) : CScriptBase(b.begin(), b.end()) { }
CScript(const_iterator pbegin, const_iterator pend) : CScriptBase(pbegin, pend) { }
CScript(std::vector<unsigned char>::const_iterator pbegin, std::vector<unsigned char>::const_iterator pend) : CScriptBase(pbegin, pend) { }
CScript(const unsigned char* pbegin, const unsigned char* pend) : CScriptBase(pbegin, pend) { }
CScript& operator+=(const CScript& b)
{
@@ -398,12 +402,10 @@ public:
}
CScript(int64_t b) { operator<<(b); }
explicit CScript(opcodetype b) { operator<<(b); }
explicit CScript(const CScriptNum& b) { operator<<(b); }
explicit CScript(const std::vector<unsigned char>& b) { operator<<(b); }
CScript& operator<<(int64_t b) { return push_int64(b); }
CScript& operator<<(opcodetype opcode)
@@ -597,10 +599,11 @@ public:
}
std::string ToString() const;
void clear()
{
// The default std::vector::clear() does not release memory.
std::vector<unsigned char>().swap(*this);
CScriptBase().swap(*this);
}
};

View File

@@ -43,6 +43,13 @@ const CScriptExt &CScriptExt::OpReturnScript(const vector<unsigned char> &data,
return *this;
}
// push data into an op_return script with an opret type indicator, fails if the op_return is too large
const CScriptExt &CScriptExt::OpReturnScript(const CScript &src, unsigned char opretType) const
{
vector<unsigned char> vch = vector<unsigned char>(src.begin(), src.end());
return OpReturnScript(vch, opretType);
}
// P2SH script, adds to whatever is already in the script (for example CLTV)
const CScriptExt &CScriptExt::PayToScriptHash(const CScriptID &scriptID) const
{
@@ -90,17 +97,17 @@ bool CScriptExt::ExtractVoutDestination(const CTransaction& tx, int32_t voutNum,
if (tx.IsCoinBase() && tx.vout.size() == 2 && voutNum == 0 &&
spk.IsPayToScriptHash(&scriptHash) &&
tx.vout[1].scriptPubKey.size() >= 7 && // minimum for any possible future to prevent out of bounds
tx.vout[1].scriptPubKey.data()[0] == OP_RETURN)
tx.vout[1].scriptPubKey[0] == OP_RETURN)
{
opcodetype op;
std::vector<uint8_t> opretData = std::vector<uint8_t>();
CScript::const_iterator it = tx.vout[1].scriptPubKey.begin() + 1;
if (tx.vout[1].scriptPubKey.GetOp2(it, op, &opretData))
{
if (opretData.size() > 0 && opretData.data()[0] == OPRETTYPE_TIMELOCK)
if (opretData.size() > 0 && opretData[0] == OPRETTYPE_TIMELOCK)
{
int64_t unlocktime;
CScriptExt se = CScriptExt(opretData.begin() + 1, opretData.end());
CScriptExt se = CScriptExt(&opretData[1], &opretData[opretData.size()]);
if (CScriptID(se) == scriptHash &&
se.IsCheckLockTimeVerify(&unlocktime))

View File

@@ -11,11 +11,13 @@
#include "standard.h"
#include "pubkey.h"
#include <vector>
class CScriptExt : public CScript
{
public:
CScriptExt() { }
CScriptExt(const CScript& b) : CScript(b.begin(), b.end()) { }
CScriptExt(const CScript& b) : CScript(b) { }
CScriptExt(const_iterator pbegin, const_iterator pend) : CScript(pbegin, pend) { }
CScriptExt(const unsigned char* pbegin, const unsigned char* pend) : CScript(pbegin, pend) { }
@@ -28,6 +30,9 @@ class CScriptExt : public CScript
// push data into an op_return script with an opret type indicator, fails if the op_return is too large
const CScriptExt &OpReturnScript(const std::vector<unsigned char> &data, unsigned char opretType) const;
// push data into an op_return script with an opret type indicator, fails if the op_return is too large
const CScriptExt &OpReturnScript(const CScript &src, unsigned char opretType) const;
// P2SH script
const CScriptExt &PayToScriptHash(const CScriptID &scriptID) const;

90
src/script/sigcache.cpp Normal file
View File

@@ -0,0 +1,90 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "sigcache.h"
#include "pubkey.h"
#include "random.h"
#include "uint256.h"
#include "util.h"
#include <boost/thread.hpp>
#include <boost/tuple/tuple_comparison.hpp>
namespace {
/**
* Valid signature cache, to avoid doing expensive ECDSA signature checking
* twice for every transaction (once when accepted into memory pool, and
* again when accepted into the block chain)
*/
class CSignatureCache
{
private:
//! sigdata_type is (signature hash, signature, public key):
typedef boost::tuple<uint256, std::vector<unsigned char>, CPubKey> sigdata_type;
std::set< sigdata_type> setValid;
boost::shared_mutex cs_sigcache;
public:
bool
Get(const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubKey)
{
boost::shared_lock<boost::shared_mutex> lock(cs_sigcache);
sigdata_type k(hash, vchSig, pubKey);
std::set<sigdata_type>::iterator mi = setValid.find(k);
if (mi != setValid.end())
return true;
return false;
}
void Set(const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubKey)
{
// DoS prevention: limit cache size to less than 10MB
// (~200 bytes per cache entry times 50,000 entries)
// Since there can be no more than 20,000 signature operations per block
// 50,000 is a reasonable default.
int64_t nMaxCacheSize = GetArg("-maxsigcachesize", 50000);
if (nMaxCacheSize <= 0) return;
boost::unique_lock<boost::shared_mutex> lock(cs_sigcache);
while (static_cast<int64_t>(setValid.size()) > nMaxCacheSize)
{
// Evict a random entry. Random because that helps
// foil would-be DoS attackers who might try to pre-generate
// and re-use a set of valid signatures just-slightly-greater
// than our cache size.
uint256 randomHash = GetRandHash();
std::vector<unsigned char> unused;
std::set<sigdata_type>::iterator it =
setValid.lower_bound(sigdata_type(randomHash, unused, unused));
if (it == setValid.end())
it = setValid.begin();
setValid.erase(*it);
}
sigdata_type k(hash, vchSig, pubKey);
setValid.insert(k);
}
};
}
bool CachingTransactionSignatureChecker::VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const
{
static CSignatureCache signatureCache;
if (signatureCache.Get(sighash, vchSig, pubkey))
return true;
if (!TransactionSignatureChecker::VerifySignature(vchSig, pubkey, sighash))
return false;
if (store)
signatureCache.Set(sighash, vchSig, pubkey);
return true;
}

26
src/script/sigcache.h Normal file
View File

@@ -0,0 +1,26 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_SCRIPT_SIGCACHE_H
#define BITCOIN_SCRIPT_SIGCACHE_H
#include "script/interpreter.h"
#include <vector>
class CPubKey;
class CachingTransactionSignatureChecker : public TransactionSignatureChecker
{
private:
bool store;
public:
CachingTransactionSignatureChecker(const CTransaction* txToIn, unsigned int nInIn, const CAmount& amount, bool storeIn, PrecomputedTransactionData& txdataIn) : TransactionSignatureChecker(txToIn, nInIn, amount, txdataIn), store(storeIn) {}
bool VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const;
};
#endif // BITCOIN_SCRIPT_SIGCACHE_H

View File

@@ -15,7 +15,7 @@
using namespace std;
typedef vector<unsigned char> valtype;
typedef std::vector<unsigned char> valtype;
TransactionSignatureCreator::TransactionSignatureCreator(const CKeyStore* keystoreIn, const CTransaction* txToIn, unsigned int nInIn, const CAmount& amountIn, int nHashTypeIn) : BaseSignatureCreator(keystoreIn), txTo(txToIn), nIn(nInIn), nHashType(nHashTypeIn), amount(amountIn), checker(txTo, nIn, amountIn) {}
@@ -81,7 +81,7 @@ static bool SignStep(const BaseSignatureCreator& creator, const CScript& scriptP
// if this is a CLTV script, solve for the destination after CLTV
if (scriptPubKey.IsCheckLockTimeVerify())
{
uint8_t pushOp = scriptPubKey.data()[0];
uint8_t pushOp = scriptPubKey[0];
uint32_t scriptStart = pushOp + 3;
// check post CLTV script

View File

@@ -243,7 +243,7 @@ bool ExtractDestination(const CScript& _scriptPubKey, CTxDestination& addressRet
// if this is a CLTV script, get the destination after CLTV
if (scriptPubKey.IsCheckLockTimeVerify())
{
uint8_t pushOp = scriptPubKey.data()[0];
uint8_t pushOp = scriptPubKey[0];
uint32_t scriptStart = pushOp + 3;
// check post CLTV script
@@ -294,7 +294,7 @@ bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, vecto
// if this is a CLTV script, get the destinations after CLTV
if (scriptPubKey.IsCheckLockTimeVerify())
{
uint8_t pushOp = scriptPubKey.data()[0];
uint8_t pushOp = scriptPubKey[0];
uint32_t scriptStart = pushOp + 3;
// check post CLTV script
@@ -387,3 +387,7 @@ CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys)
script << CScript::EncodeOP_N(keys.size()) << OP_CHECKMULTISIG;
return script;
}
bool IsValidDestination(const CTxDestination& dest) {
return dest.which() != 0;
}

View File

@@ -79,10 +79,13 @@ public:
* * CNoDestination: no destination set
* * CKeyID: TX_PUBKEYHASH destination
* * CScriptID: TX_SCRIPTHASH destination
* A CTxDestination is the internal data type encoded in a CBitcoinAddress
* A CTxDestination is the internal data type encoded in a bitcoin address
*/
typedef boost::variant<CNoDestination, CKeyID, CScriptID> CTxDestination;
/** Check whether a CTxDestination is a CNoDestination. */
bool IsValidDestination(const CTxDestination& dest);
const char* GetTxnOutputType(txnouttype t);
bool Solver(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<std::vector<unsigned char> >& vSolutionsRet);

View File

@@ -24,7 +24,7 @@ public:
m_remaining(txToLen)
{}
TxInputStream& read(char* pch, size_t nSize)
void read(char* pch, size_t nSize)
{
if (nSize > m_remaining)
throw std::ios_base::failure(std::string(__func__) + ": end of data");
@@ -38,16 +38,17 @@ public:
memcpy(pch, m_data, nSize);
m_remaining -= nSize;
m_data += nSize;
return *this;
}
template<typename T>
TxInputStream& operator>>(T& obj)
{
::Unserialize(*this, obj, m_type, m_version);
::Unserialize(*this, obj);
return *this;
}
int GetVersion() const { return m_version; }
int GetType() const { return m_type; }
private:
const int m_type;
const int m_version;
@@ -80,7 +81,7 @@ int zcashconsensus_verify_script(const unsigned char *scriptPubKey, unsigned int
stream >> tx;
if (nIn >= tx.vin.size())
return set_error(err, zcashconsensus_ERR_TX_INDEX);
if (tx.GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION) != txToLen)
if (GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION) != txToLen)
return set_error(err, zcashconsensus_ERR_TX_SIZE_MISMATCH);
// Regardless of the verification result, the tx did not error.