scripted-diff: TxoutType C++11 scoped enum class

-BEGIN VERIFY SCRIPT-
 # General rename helper: $1 -> $2
 rename_global() { sed -i "s/\<$1\>/$2/g" $(git grep -l "$1"); }

 # Helper to rename TxoutType $1
 rename_value() {
   sed -i "s/    TX_$1,/    $1,/g" src/script/standard.h;  # First strip the prefix in the definition (header)
   rename_global TX_$1 "TxoutType::$1";                    # Then replace globally
 }

 # Change the type globally to bring it in line with the style-guide
 # (clsses are UpperCamelCase)
 rename_global 'enum txnouttype' 'enum class TxoutType'
 rename_global      'txnouttype'            'TxoutType'

 # Now rename each enum value
 rename_value 'NONSTANDARD'
 rename_value 'PUBKEY'
 rename_value 'PUBKEYHASH'
 rename_value 'SCRIPTHASH'
 rename_value 'MULTISIG'
 rename_value 'NULL_DATA'
 rename_value 'WITNESS_V0_KEYHASH'
 rename_value 'WITNESS_V0_SCRIPTHASH'
 rename_value 'WITNESS_UNKNOWN'

-END VERIFY SCRIPT-
This commit is contained in:
MarcoFalke 2020-05-30 09:16:05 -04:00
parent fa95a694c4
commit fa32adf9dc
No known key found for this signature in database
GPG key ID: CE2B75697E69A548
18 changed files with 208 additions and 208 deletions

View file

@ -135,8 +135,8 @@ bool CBloomFilter::IsRelevantAndUpdate(const CTransaction& tx)
else if ((nFlags & BLOOM_UPDATE_MASK) == BLOOM_UPDATE_P2PUBKEY_ONLY) else if ((nFlags & BLOOM_UPDATE_MASK) == BLOOM_UPDATE_P2PUBKEY_ONLY)
{ {
std::vector<std::vector<unsigned char> > vSolutions; std::vector<std::vector<unsigned char> > vSolutions;
txnouttype type = Solver(txout.scriptPubKey, vSolutions); TxoutType type = Solver(txout.scriptPubKey, vSolutions);
if (type == TX_PUBKEY || type == TX_MULTISIG) { if (type == TxoutType::PUBKEY || type == TxoutType::MULTISIG) {
insert(COutPoint(hash, i)); insert(COutPoint(hash, i));
} }
} }

View file

@ -140,11 +140,11 @@ void ScriptToUniv(const CScript& script, UniValue& out, bool include_address)
out.pushKV("hex", HexStr(script.begin(), script.end())); out.pushKV("hex", HexStr(script.begin(), script.end()));
std::vector<std::vector<unsigned char>> solns; std::vector<std::vector<unsigned char>> solns;
txnouttype type = Solver(script, solns); TxoutType type = Solver(script, solns);
out.pushKV("type", GetTxnOutputType(type)); out.pushKV("type", GetTxnOutputType(type));
CTxDestination address; CTxDestination address;
if (include_address && ExtractDestination(script, address) && type != TX_PUBKEY) { if (include_address && ExtractDestination(script, address) && type != TxoutType::PUBKEY) {
out.pushKV("address", EncodeDestination(address)); out.pushKV("address", EncodeDestination(address));
} }
} }
@ -152,7 +152,7 @@ void ScriptToUniv(const CScript& script, UniValue& out, bool include_address)
void ScriptPubKeyToUniv(const CScript& scriptPubKey, void ScriptPubKeyToUniv(const CScript& scriptPubKey,
UniValue& out, bool fIncludeHex) UniValue& out, bool fIncludeHex)
{ {
txnouttype type; TxoutType type;
std::vector<CTxDestination> addresses; std::vector<CTxDestination> addresses;
int nRequired; int nRequired;
@ -160,7 +160,7 @@ void ScriptPubKeyToUniv(const CScript& scriptPubKey,
if (fIncludeHex) if (fIncludeHex)
out.pushKV("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())); out.pushKV("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end()));
if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired) || type == TX_PUBKEY) { if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired) || type == TxoutType::PUBKEY) {
out.pushKV("type", GetTxnOutputType(type)); out.pushKV("type", GetTxnOutputType(type));
return; return;
} }

View file

@ -50,14 +50,14 @@ bool IsDust(const CTxOut& txout, const CFeeRate& dustRelayFeeIn)
return (txout.nValue < GetDustThreshold(txout, dustRelayFeeIn)); return (txout.nValue < GetDustThreshold(txout, dustRelayFeeIn));
} }
bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType) bool IsStandard(const CScript& scriptPubKey, TxoutType& whichType)
{ {
std::vector<std::vector<unsigned char> > vSolutions; std::vector<std::vector<unsigned char> > vSolutions;
whichType = Solver(scriptPubKey, vSolutions); whichType = Solver(scriptPubKey, vSolutions);
if (whichType == TX_NONSTANDARD) { if (whichType == TxoutType::NONSTANDARD) {
return false; return false;
} else if (whichType == TX_MULTISIG) { } else if (whichType == TxoutType::MULTISIG) {
unsigned char m = vSolutions.front()[0]; unsigned char m = vSolutions.front()[0];
unsigned char n = vSolutions.back()[0]; unsigned char n = vSolutions.back()[0];
// Support up to x-of-3 multisig txns as standard // Support up to x-of-3 multisig txns as standard
@ -65,7 +65,7 @@ bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType)
return false; return false;
if (m < 1 || m > n) if (m < 1 || m > n)
return false; return false;
} else if (whichType == TX_NULL_DATA && } else if (whichType == TxoutType::NULL_DATA &&
(!fAcceptDatacarrier || scriptPubKey.size() > nMaxDatacarrierBytes)) { (!fAcceptDatacarrier || scriptPubKey.size() > nMaxDatacarrierBytes)) {
return false; return false;
} }
@ -110,16 +110,16 @@ bool IsStandardTx(const CTransaction& tx, bool permit_bare_multisig, const CFeeR
} }
unsigned int nDataOut = 0; unsigned int nDataOut = 0;
txnouttype whichType; TxoutType whichType;
for (const CTxOut& txout : tx.vout) { for (const CTxOut& txout : tx.vout) {
if (!::IsStandard(txout.scriptPubKey, whichType)) { if (!::IsStandard(txout.scriptPubKey, whichType)) {
reason = "scriptpubkey"; reason = "scriptpubkey";
return false; return false;
} }
if (whichType == TX_NULL_DATA) if (whichType == TxoutType::NULL_DATA)
nDataOut++; nDataOut++;
else if ((whichType == TX_MULTISIG) && (!permit_bare_multisig)) { else if ((whichType == TxoutType::MULTISIG) && (!permit_bare_multisig)) {
reason = "bare-multisig"; reason = "bare-multisig";
return false; return false;
} else if (IsDust(txout, dust_relay_fee)) { } else if (IsDust(txout, dust_relay_fee)) {
@ -163,10 +163,10 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
const CTxOut& prev = mapInputs.AccessCoin(tx.vin[i].prevout).out; const CTxOut& prev = mapInputs.AccessCoin(tx.vin[i].prevout).out;
std::vector<std::vector<unsigned char> > vSolutions; std::vector<std::vector<unsigned char> > vSolutions;
txnouttype whichType = Solver(prev.scriptPubKey, vSolutions); TxoutType whichType = Solver(prev.scriptPubKey, vSolutions);
if (whichType == TX_NONSTANDARD) { if (whichType == TxoutType::NONSTANDARD) {
return false; return false;
} else if (whichType == TX_SCRIPTHASH) { } else if (whichType == TxoutType::SCRIPTHASH) {
std::vector<std::vector<unsigned char> > stack; std::vector<std::vector<unsigned char> > stack;
// convert the scriptSig into a stack, so we can inspect the redeemScript // convert the scriptSig into a stack, so we can inspect the redeemScript
if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), SigVersion::BASE)) if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), SigVersion::BASE))

View file

@ -81,7 +81,7 @@ CAmount GetDustThreshold(const CTxOut& txout, const CFeeRate& dustRelayFee);
bool IsDust(const CTxOut& txout, const CFeeRate& dustRelayFee); bool IsDust(const CTxOut& txout, const CFeeRate& dustRelayFee);
bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType); bool IsStandard(const CScript& scriptPubKey, TxoutType& whichType);
/** /**
* Check for standard transaction types * Check for standard transaction types
* @return True if all outputs (scriptPubKeys) use only standard transaction forms * @return True if all outputs (scriptPubKeys) use only standard transaction forms

View file

@ -512,9 +512,9 @@ static UniValue decoderawtransaction(const JSONRPCRequest& request)
static std::string GetAllOutputTypes() static std::string GetAllOutputTypes()
{ {
std::vector<std::string> ret; std::vector<std::string> ret;
using U = std::underlying_type<txnouttype>::type; using U = std::underlying_type<TxoutType>::type;
for (U i = (U)TX_NONSTANDARD; i <= (U)TX_WITNESS_UNKNOWN; ++i) { for (U i = (U)TxoutType::NONSTANDARD; i <= (U)TxoutType::WITNESS_UNKNOWN; ++i) {
ret.emplace_back(GetTxnOutputType(static_cast<txnouttype>(i))); ret.emplace_back(GetTxnOutputType(static_cast<TxoutType>(i)));
} }
return Join(ret, ", "); return Join(ret, ", ");
} }
@ -580,10 +580,10 @@ static UniValue decodescript(const JSONRPCRequest& request)
// is a witness program, don't return addresses for a segwit programs. // is a witness program, don't return addresses for a segwit programs.
if (type.get_str() == "pubkey" || type.get_str() == "pubkeyhash" || type.get_str() == "multisig" || type.get_str() == "nonstandard") { if (type.get_str() == "pubkey" || type.get_str() == "pubkeyhash" || type.get_str() == "multisig" || type.get_str() == "nonstandard") {
std::vector<std::vector<unsigned char>> solutions_data; std::vector<std::vector<unsigned char>> solutions_data;
txnouttype which_type = Solver(script, solutions_data); TxoutType which_type = Solver(script, solutions_data);
// Uncompressed pubkeys cannot be used with segwit checksigs. // Uncompressed pubkeys cannot be used with segwit checksigs.
// If the script contains an uncompressed pubkey, skip encoding of a segwit program. // If the script contains an uncompressed pubkey, skip encoding of a segwit program.
if ((which_type == TX_PUBKEY) || (which_type == TX_MULTISIG)) { if ((which_type == TxoutType::PUBKEY) || (which_type == TxoutType::MULTISIG)) {
for (const auto& solution : solutions_data) { for (const auto& solution : solutions_data) {
if ((solution.size() != 1) && !CPubKey(solution).IsCompressed()) { if ((solution.size() != 1) && !CPubKey(solution).IsCompressed()) {
return r; return r;
@ -592,9 +592,9 @@ static UniValue decodescript(const JSONRPCRequest& request)
} }
UniValue sr(UniValue::VOBJ); UniValue sr(UniValue::VOBJ);
CScript segwitScr; CScript segwitScr;
if (which_type == TX_PUBKEY) { if (which_type == TxoutType::PUBKEY) {
segwitScr = GetScriptForDestination(WitnessV0KeyHash(Hash160(solutions_data[0].begin(), solutions_data[0].end()))); segwitScr = GetScriptForDestination(WitnessV0KeyHash(Hash160(solutions_data[0].begin(), solutions_data[0].end())));
} else if (which_type == TX_PUBKEYHASH) { } else if (which_type == TxoutType::PUBKEYHASH) {
segwitScr = GetScriptForDestination(WitnessV0KeyHash(uint160{solutions_data[0]})); segwitScr = GetScriptForDestination(WitnessV0KeyHash(uint160{solutions_data[0]}));
} else { } else {
// Scripts that are not fit for P2WPKH are encoded as P2WSH. // Scripts that are not fit for P2WPKH are encoded as P2WSH.

View file

@ -985,15 +985,15 @@ std::unique_ptr<PubkeyProvider> InferPubkey(const CPubKey& pubkey, ParseScriptCo
std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptContext ctx, const SigningProvider& provider) std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptContext ctx, const SigningProvider& provider)
{ {
std::vector<std::vector<unsigned char>> data; std::vector<std::vector<unsigned char>> data;
txnouttype txntype = Solver(script, data); TxoutType txntype = Solver(script, data);
if (txntype == TX_PUBKEY) { if (txntype == TxoutType::PUBKEY) {
CPubKey pubkey(data[0].begin(), data[0].end()); CPubKey pubkey(data[0].begin(), data[0].end());
if (pubkey.IsValid()) { if (pubkey.IsValid()) {
return MakeUnique<PKDescriptor>(InferPubkey(pubkey, ctx, provider)); return MakeUnique<PKDescriptor>(InferPubkey(pubkey, ctx, provider));
} }
} }
if (txntype == TX_PUBKEYHASH) { if (txntype == TxoutType::PUBKEYHASH) {
uint160 hash(data[0]); uint160 hash(data[0]);
CKeyID keyid(hash); CKeyID keyid(hash);
CPubKey pubkey; CPubKey pubkey;
@ -1001,7 +1001,7 @@ std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptCo
return MakeUnique<PKHDescriptor>(InferPubkey(pubkey, ctx, provider)); return MakeUnique<PKHDescriptor>(InferPubkey(pubkey, ctx, provider));
} }
} }
if (txntype == TX_WITNESS_V0_KEYHASH && ctx != ParseScriptContext::P2WSH) { if (txntype == TxoutType::WITNESS_V0_KEYHASH && ctx != ParseScriptContext::P2WSH) {
uint160 hash(data[0]); uint160 hash(data[0]);
CKeyID keyid(hash); CKeyID keyid(hash);
CPubKey pubkey; CPubKey pubkey;
@ -1009,7 +1009,7 @@ std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptCo
return MakeUnique<WPKHDescriptor>(InferPubkey(pubkey, ctx, provider)); return MakeUnique<WPKHDescriptor>(InferPubkey(pubkey, ctx, provider));
} }
} }
if (txntype == TX_MULTISIG) { if (txntype == TxoutType::MULTISIG) {
std::vector<std::unique_ptr<PubkeyProvider>> providers; std::vector<std::unique_ptr<PubkeyProvider>> providers;
for (size_t i = 1; i + 1 < data.size(); ++i) { for (size_t i = 1; i + 1 < data.size(); ++i) {
CPubKey pubkey(data[i].begin(), data[i].end()); CPubKey pubkey(data[i].begin(), data[i].end());
@ -1017,7 +1017,7 @@ std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptCo
} }
return MakeUnique<MultisigDescriptor>((int)data[0][0], std::move(providers)); return MakeUnique<MultisigDescriptor>((int)data[0][0], std::move(providers));
} }
if (txntype == TX_SCRIPTHASH && ctx == ParseScriptContext::TOP) { if (txntype == TxoutType::SCRIPTHASH && ctx == ParseScriptContext::TOP) {
uint160 hash(data[0]); uint160 hash(data[0]);
CScriptID scriptid(hash); CScriptID scriptid(hash);
CScript subscript; CScript subscript;
@ -1026,7 +1026,7 @@ std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptCo
if (sub) return MakeUnique<SHDescriptor>(std::move(sub)); if (sub) return MakeUnique<SHDescriptor>(std::move(sub));
} }
} }
if (txntype == TX_WITNESS_V0_SCRIPTHASH && ctx != ParseScriptContext::P2WSH) { if (txntype == TxoutType::WITNESS_V0_SCRIPTHASH && ctx != ParseScriptContext::P2WSH) {
CScriptID scriptid; CScriptID scriptid;
CRIPEMD160().Write(data[0].data(), data[0].size()).Finalize(scriptid.begin()); CRIPEMD160().Write(data[0].data(), data[0].size()).Finalize(scriptid.begin());
CScript subscript; CScript subscript;

View file

@ -92,11 +92,11 @@ static bool CreateSig(const BaseSignatureCreator& creator, SignatureData& sigdat
/** /**
* Sign scriptPubKey using signature made with creator. * Sign scriptPubKey using signature made with creator.
* Signatures are returned in scriptSigRet (or returns false if scriptPubKey can't be signed), * Signatures are returned in scriptSigRet (or returns false if scriptPubKey can't be signed),
* unless whichTypeRet is TX_SCRIPTHASH, in which case scriptSigRet is the redemption script. * unless whichTypeRet is TxoutType::SCRIPTHASH, in which case scriptSigRet is the redemption script.
* Returns false if scriptPubKey could not be completely satisfied. * Returns false if scriptPubKey could not be completely satisfied.
*/ */
static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& scriptPubKey, static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator& creator, const CScript& scriptPubKey,
std::vector<valtype>& ret, txnouttype& whichTypeRet, SigVersion sigversion, SignatureData& sigdata) std::vector<valtype>& ret, TxoutType& whichTypeRet, SigVersion sigversion, SignatureData& sigdata)
{ {
CScript scriptRet; CScript scriptRet;
uint160 h160; uint160 h160;
@ -108,15 +108,15 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator
switch (whichTypeRet) switch (whichTypeRet)
{ {
case TX_NONSTANDARD: case TxoutType::NONSTANDARD:
case TX_NULL_DATA: case TxoutType::NULL_DATA:
case TX_WITNESS_UNKNOWN: case TxoutType::WITNESS_UNKNOWN:
return false; return false;
case TX_PUBKEY: case TxoutType::PUBKEY:
if (!CreateSig(creator, sigdata, provider, sig, CPubKey(vSolutions[0]), scriptPubKey, sigversion)) return false; if (!CreateSig(creator, sigdata, provider, sig, CPubKey(vSolutions[0]), scriptPubKey, sigversion)) return false;
ret.push_back(std::move(sig)); ret.push_back(std::move(sig));
return true; return true;
case TX_PUBKEYHASH: { case TxoutType::PUBKEYHASH: {
CKeyID keyID = CKeyID(uint160(vSolutions[0])); CKeyID keyID = CKeyID(uint160(vSolutions[0]));
CPubKey pubkey; CPubKey pubkey;
if (!GetPubKey(provider, sigdata, keyID, pubkey)) { if (!GetPubKey(provider, sigdata, keyID, pubkey)) {
@ -129,7 +129,7 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator
ret.push_back(ToByteVector(pubkey)); ret.push_back(ToByteVector(pubkey));
return true; return true;
} }
case TX_SCRIPTHASH: case TxoutType::SCRIPTHASH:
h160 = uint160(vSolutions[0]); h160 = uint160(vSolutions[0]);
if (GetCScript(provider, sigdata, CScriptID{h160}, scriptRet)) { if (GetCScript(provider, sigdata, CScriptID{h160}, scriptRet)) {
ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end())); ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end()));
@ -139,7 +139,7 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator
sigdata.missing_redeem_script = h160; sigdata.missing_redeem_script = h160;
return false; return false;
case TX_MULTISIG: { case TxoutType::MULTISIG: {
size_t required = vSolutions.front()[0]; size_t required = vSolutions.front()[0];
ret.push_back(valtype()); // workaround CHECKMULTISIG bug ret.push_back(valtype()); // workaround CHECKMULTISIG bug
for (size_t i = 1; i < vSolutions.size() - 1; ++i) { for (size_t i = 1; i < vSolutions.size() - 1; ++i) {
@ -159,11 +159,11 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator
} }
return ok; return ok;
} }
case TX_WITNESS_V0_KEYHASH: case TxoutType::WITNESS_V0_KEYHASH:
ret.push_back(vSolutions[0]); ret.push_back(vSolutions[0]);
return true; return true;
case TX_WITNESS_V0_SCRIPTHASH: case TxoutType::WITNESS_V0_SCRIPTHASH:
CRIPEMD160().Write(&vSolutions[0][0], vSolutions[0].size()).Finalize(h160.begin()); CRIPEMD160().Write(&vSolutions[0][0], vSolutions[0].size()).Finalize(h160.begin());
if (GetCScript(provider, sigdata, CScriptID{h160}, scriptRet)) { if (GetCScript(provider, sigdata, CScriptID{h160}, scriptRet)) {
ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end())); ret.push_back(std::vector<unsigned char>(scriptRet.begin(), scriptRet.end()));
@ -198,44 +198,44 @@ bool ProduceSignature(const SigningProvider& provider, const BaseSignatureCreato
if (sigdata.complete) return true; if (sigdata.complete) return true;
std::vector<valtype> result; std::vector<valtype> result;
txnouttype whichType; TxoutType whichType;
bool solved = SignStep(provider, creator, fromPubKey, result, whichType, SigVersion::BASE, sigdata); bool solved = SignStep(provider, creator, fromPubKey, result, whichType, SigVersion::BASE, sigdata);
bool P2SH = false; bool P2SH = false;
CScript subscript; CScript subscript;
sigdata.scriptWitness.stack.clear(); sigdata.scriptWitness.stack.clear();
if (solved && whichType == TX_SCRIPTHASH) if (solved && whichType == TxoutType::SCRIPTHASH)
{ {
// Solver returns the subscript that needs to be evaluated; // Solver returns the subscript that needs to be evaluated;
// the final scriptSig is the signatures from that // the final scriptSig is the signatures from that
// and then the serialized subscript: // and then the serialized subscript:
subscript = CScript(result[0].begin(), result[0].end()); subscript = CScript(result[0].begin(), result[0].end());
sigdata.redeem_script = subscript; sigdata.redeem_script = subscript;
solved = solved && SignStep(provider, creator, subscript, result, whichType, SigVersion::BASE, sigdata) && whichType != TX_SCRIPTHASH; solved = solved && SignStep(provider, creator, subscript, result, whichType, SigVersion::BASE, sigdata) && whichType != TxoutType::SCRIPTHASH;
P2SH = true; P2SH = true;
} }
if (solved && whichType == TX_WITNESS_V0_KEYHASH) if (solved && whichType == TxoutType::WITNESS_V0_KEYHASH)
{ {
CScript witnessscript; CScript witnessscript;
witnessscript << OP_DUP << OP_HASH160 << ToByteVector(result[0]) << OP_EQUALVERIFY << OP_CHECKSIG; witnessscript << OP_DUP << OP_HASH160 << ToByteVector(result[0]) << OP_EQUALVERIFY << OP_CHECKSIG;
txnouttype subType; TxoutType subType;
solved = solved && SignStep(provider, creator, witnessscript, result, subType, SigVersion::WITNESS_V0, sigdata); solved = solved && SignStep(provider, creator, witnessscript, result, subType, SigVersion::WITNESS_V0, sigdata);
sigdata.scriptWitness.stack = result; sigdata.scriptWitness.stack = result;
sigdata.witness = true; sigdata.witness = true;
result.clear(); result.clear();
} }
else if (solved && whichType == TX_WITNESS_V0_SCRIPTHASH) else if (solved && whichType == TxoutType::WITNESS_V0_SCRIPTHASH)
{ {
CScript witnessscript(result[0].begin(), result[0].end()); CScript witnessscript(result[0].begin(), result[0].end());
sigdata.witness_script = witnessscript; sigdata.witness_script = witnessscript;
txnouttype subType; TxoutType subType;
solved = solved && SignStep(provider, creator, witnessscript, result, subType, SigVersion::WITNESS_V0, sigdata) && subType != TX_SCRIPTHASH && subType != TX_WITNESS_V0_SCRIPTHASH && subType != TX_WITNESS_V0_KEYHASH; solved = solved && SignStep(provider, creator, witnessscript, result, subType, SigVersion::WITNESS_V0, sigdata) && subType != TxoutType::SCRIPTHASH && subType != TxoutType::WITNESS_V0_SCRIPTHASH && subType != TxoutType::WITNESS_V0_KEYHASH;
result.push_back(std::vector<unsigned char>(witnessscript.begin(), witnessscript.end())); result.push_back(std::vector<unsigned char>(witnessscript.begin(), witnessscript.end()));
sigdata.scriptWitness.stack = result; sigdata.scriptWitness.stack = result;
sigdata.witness = true; sigdata.witness = true;
result.clear(); result.clear();
} else if (solved && whichType == TX_WITNESS_UNKNOWN) { } else if (solved && whichType == TxoutType::WITNESS_UNKNOWN) {
sigdata.witness = true; sigdata.witness = true;
} }
@ -301,11 +301,11 @@ SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nI
// Get scripts // Get scripts
std::vector<std::vector<unsigned char>> solutions; std::vector<std::vector<unsigned char>> solutions;
txnouttype script_type = Solver(txout.scriptPubKey, solutions); TxoutType script_type = Solver(txout.scriptPubKey, solutions);
SigVersion sigversion = SigVersion::BASE; SigVersion sigversion = SigVersion::BASE;
CScript next_script = txout.scriptPubKey; CScript next_script = txout.scriptPubKey;
if (script_type == TX_SCRIPTHASH && !stack.script.empty() && !stack.script.back().empty()) { if (script_type == TxoutType::SCRIPTHASH && !stack.script.empty() && !stack.script.back().empty()) {
// Get the redeemScript // Get the redeemScript
CScript redeem_script(stack.script.back().begin(), stack.script.back().end()); CScript redeem_script(stack.script.back().begin(), stack.script.back().end());
data.redeem_script = redeem_script; data.redeem_script = redeem_script;
@ -315,7 +315,7 @@ SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nI
script_type = Solver(next_script, solutions); script_type = Solver(next_script, solutions);
stack.script.pop_back(); stack.script.pop_back();
} }
if (script_type == TX_WITNESS_V0_SCRIPTHASH && !stack.witness.empty() && !stack.witness.back().empty()) { if (script_type == TxoutType::WITNESS_V0_SCRIPTHASH && !stack.witness.empty() && !stack.witness.back().empty()) {
// Get the witnessScript // Get the witnessScript
CScript witness_script(stack.witness.back().begin(), stack.witness.back().end()); CScript witness_script(stack.witness.back().begin(), stack.witness.back().end());
data.witness_script = witness_script; data.witness_script = witness_script;
@ -328,7 +328,7 @@ SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nI
stack.witness.clear(); stack.witness.clear();
sigversion = SigVersion::WITNESS_V0; sigversion = SigVersion::WITNESS_V0;
} }
if (script_type == TX_MULTISIG && !stack.script.empty()) { if (script_type == TxoutType::MULTISIG && !stack.script.empty()) {
// Build a map of pubkey -> signature by matching sigs to pubkeys: // Build a map of pubkey -> signature by matching sigs to pubkeys:
assert(solutions.size() > 1); assert(solutions.size() > 1);
unsigned int num_pubkeys = solutions.size()-2; unsigned int num_pubkeys = solutions.size()-2;
@ -454,13 +454,13 @@ bool IsSegWitOutput(const SigningProvider& provider, const CScript& script)
{ {
std::vector<valtype> solutions; std::vector<valtype> solutions;
auto whichtype = Solver(script, solutions); auto whichtype = Solver(script, solutions);
if (whichtype == TX_WITNESS_V0_SCRIPTHASH || whichtype == TX_WITNESS_V0_KEYHASH || whichtype == TX_WITNESS_UNKNOWN) return true; if (whichtype == TxoutType::WITNESS_V0_SCRIPTHASH || whichtype == TxoutType::WITNESS_V0_KEYHASH || whichtype == TxoutType::WITNESS_UNKNOWN) return true;
if (whichtype == TX_SCRIPTHASH) { if (whichtype == TxoutType::SCRIPTHASH) {
auto h160 = uint160(solutions[0]); auto h160 = uint160(solutions[0]);
CScript subscript; CScript subscript;
if (provider.GetCScript(CScriptID{h160}, subscript)) { if (provider.GetCScript(CScriptID{h160}, subscript)) {
whichtype = Solver(subscript, solutions); whichtype = Solver(subscript, solutions);
if (whichtype == TX_WITNESS_V0_SCRIPTHASH || whichtype == TX_WITNESS_V0_KEYHASH || whichtype == TX_WITNESS_UNKNOWN) return true; if (whichtype == TxoutType::WITNESS_V0_SCRIPTHASH || whichtype == TxoutType::WITNESS_V0_KEYHASH || whichtype == TxoutType::WITNESS_UNKNOWN) return true;
} }
} }
return false; return false;

View file

@ -43,19 +43,19 @@ WitnessV0ScriptHash::WitnessV0ScriptHash(const CScript& in)
CSHA256().Write(in.data(), in.size()).Finalize(begin()); CSHA256().Write(in.data(), in.size()).Finalize(begin());
} }
std::string GetTxnOutputType(txnouttype t) std::string GetTxnOutputType(TxoutType t)
{ {
switch (t) switch (t)
{ {
case TX_NONSTANDARD: return "nonstandard"; case TxoutType::NONSTANDARD: return "nonstandard";
case TX_PUBKEY: return "pubkey"; case TxoutType::PUBKEY: return "pubkey";
case TX_PUBKEYHASH: return "pubkeyhash"; case TxoutType::PUBKEYHASH: return "pubkeyhash";
case TX_SCRIPTHASH: return "scripthash"; case TxoutType::SCRIPTHASH: return "scripthash";
case TX_MULTISIG: return "multisig"; case TxoutType::MULTISIG: return "multisig";
case TX_NULL_DATA: return "nulldata"; case TxoutType::NULL_DATA: return "nulldata";
case TX_WITNESS_V0_KEYHASH: return "witness_v0_keyhash"; case TxoutType::WITNESS_V0_KEYHASH: return "witness_v0_keyhash";
case TX_WITNESS_V0_SCRIPTHASH: return "witness_v0_scripthash"; case TxoutType::WITNESS_V0_SCRIPTHASH: return "witness_v0_scripthash";
case TX_WITNESS_UNKNOWN: return "witness_unknown"; case TxoutType::WITNESS_UNKNOWN: return "witness_unknown";
} // no default case, so the compiler can warn about missing cases } // no default case, so the compiler can warn about missing cases
assert(false); assert(false);
} }
@ -106,7 +106,7 @@ static bool MatchMultisig(const CScript& script, unsigned int& required, std::ve
return (it + 1 == script.end()); return (it + 1 == script.end());
} }
txnouttype Solver(const CScript& scriptPubKey, std::vector<std::vector<unsigned char>>& vSolutionsRet) TxoutType Solver(const CScript& scriptPubKey, std::vector<std::vector<unsigned char>>& vSolutionsRet)
{ {
vSolutionsRet.clear(); vSolutionsRet.clear();
@ -116,7 +116,7 @@ txnouttype Solver(const CScript& scriptPubKey, std::vector<std::vector<unsigned
{ {
std::vector<unsigned char> hashBytes(scriptPubKey.begin()+2, scriptPubKey.begin()+22); std::vector<unsigned char> hashBytes(scriptPubKey.begin()+2, scriptPubKey.begin()+22);
vSolutionsRet.push_back(hashBytes); vSolutionsRet.push_back(hashBytes);
return TX_SCRIPTHASH; return TxoutType::SCRIPTHASH;
} }
int witnessversion; int witnessversion;
@ -124,18 +124,18 @@ txnouttype Solver(const CScript& scriptPubKey, std::vector<std::vector<unsigned
if (scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) { if (scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {
if (witnessversion == 0 && witnessprogram.size() == WITNESS_V0_KEYHASH_SIZE) { if (witnessversion == 0 && witnessprogram.size() == WITNESS_V0_KEYHASH_SIZE) {
vSolutionsRet.push_back(witnessprogram); vSolutionsRet.push_back(witnessprogram);
return TX_WITNESS_V0_KEYHASH; return TxoutType::WITNESS_V0_KEYHASH;
} }
if (witnessversion == 0 && witnessprogram.size() == WITNESS_V0_SCRIPTHASH_SIZE) { if (witnessversion == 0 && witnessprogram.size() == WITNESS_V0_SCRIPTHASH_SIZE) {
vSolutionsRet.push_back(witnessprogram); vSolutionsRet.push_back(witnessprogram);
return TX_WITNESS_V0_SCRIPTHASH; return TxoutType::WITNESS_V0_SCRIPTHASH;
} }
if (witnessversion != 0) { if (witnessversion != 0) {
vSolutionsRet.push_back(std::vector<unsigned char>{(unsigned char)witnessversion}); vSolutionsRet.push_back(std::vector<unsigned char>{(unsigned char)witnessversion});
vSolutionsRet.push_back(std::move(witnessprogram)); vSolutionsRet.push_back(std::move(witnessprogram));
return TX_WITNESS_UNKNOWN; return TxoutType::WITNESS_UNKNOWN;
} }
return TX_NONSTANDARD; return TxoutType::NONSTANDARD;
} }
// Provably prunable, data-carrying output // Provably prunable, data-carrying output
@ -144,18 +144,18 @@ txnouttype Solver(const CScript& scriptPubKey, std::vector<std::vector<unsigned
// byte passes the IsPushOnly() test we don't care what exactly is in the // byte passes the IsPushOnly() test we don't care what exactly is in the
// script. // script.
if (scriptPubKey.size() >= 1 && scriptPubKey[0] == OP_RETURN && scriptPubKey.IsPushOnly(scriptPubKey.begin()+1)) { if (scriptPubKey.size() >= 1 && scriptPubKey[0] == OP_RETURN && scriptPubKey.IsPushOnly(scriptPubKey.begin()+1)) {
return TX_NULL_DATA; return TxoutType::NULL_DATA;
} }
std::vector<unsigned char> data; std::vector<unsigned char> data;
if (MatchPayToPubkey(scriptPubKey, data)) { if (MatchPayToPubkey(scriptPubKey, data)) {
vSolutionsRet.push_back(std::move(data)); vSolutionsRet.push_back(std::move(data));
return TX_PUBKEY; return TxoutType::PUBKEY;
} }
if (MatchPayToPubkeyHash(scriptPubKey, data)) { if (MatchPayToPubkeyHash(scriptPubKey, data)) {
vSolutionsRet.push_back(std::move(data)); vSolutionsRet.push_back(std::move(data));
return TX_PUBKEYHASH; return TxoutType::PUBKEYHASH;
} }
unsigned int required; unsigned int required;
@ -164,19 +164,19 @@ txnouttype Solver(const CScript& scriptPubKey, std::vector<std::vector<unsigned
vSolutionsRet.push_back({static_cast<unsigned char>(required)}); // safe as required is in range 1..16 vSolutionsRet.push_back({static_cast<unsigned char>(required)}); // safe as required is in range 1..16
vSolutionsRet.insert(vSolutionsRet.end(), keys.begin(), keys.end()); vSolutionsRet.insert(vSolutionsRet.end(), keys.begin(), keys.end());
vSolutionsRet.push_back({static_cast<unsigned char>(keys.size())}); // safe as size is in range 1..16 vSolutionsRet.push_back({static_cast<unsigned char>(keys.size())}); // safe as size is in range 1..16
return TX_MULTISIG; return TxoutType::MULTISIG;
} }
vSolutionsRet.clear(); vSolutionsRet.clear();
return TX_NONSTANDARD; return TxoutType::NONSTANDARD;
} }
bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet) bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
{ {
std::vector<valtype> vSolutions; std::vector<valtype> vSolutions;
txnouttype whichType = Solver(scriptPubKey, vSolutions); TxoutType whichType = Solver(scriptPubKey, vSolutions);
if (whichType == TX_PUBKEY) { if (whichType == TxoutType::PUBKEY) {
CPubKey pubKey(vSolutions[0]); CPubKey pubKey(vSolutions[0]);
if (!pubKey.IsValid()) if (!pubKey.IsValid())
return false; return false;
@ -184,26 +184,26 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
addressRet = PKHash(pubKey); addressRet = PKHash(pubKey);
return true; return true;
} }
else if (whichType == TX_PUBKEYHASH) else if (whichType == TxoutType::PUBKEYHASH)
{ {
addressRet = PKHash(uint160(vSolutions[0])); addressRet = PKHash(uint160(vSolutions[0]));
return true; return true;
} }
else if (whichType == TX_SCRIPTHASH) else if (whichType == TxoutType::SCRIPTHASH)
{ {
addressRet = ScriptHash(uint160(vSolutions[0])); addressRet = ScriptHash(uint160(vSolutions[0]));
return true; return true;
} else if (whichType == TX_WITNESS_V0_KEYHASH) { } else if (whichType == TxoutType::WITNESS_V0_KEYHASH) {
WitnessV0KeyHash hash; WitnessV0KeyHash hash;
std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin()); std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin());
addressRet = hash; addressRet = hash;
return true; return true;
} else if (whichType == TX_WITNESS_V0_SCRIPTHASH) { } else if (whichType == TxoutType::WITNESS_V0_SCRIPTHASH) {
WitnessV0ScriptHash hash; WitnessV0ScriptHash hash;
std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin()); std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin());
addressRet = hash; addressRet = hash;
return true; return true;
} else if (whichType == TX_WITNESS_UNKNOWN) { } else if (whichType == TxoutType::WITNESS_UNKNOWN) {
WitnessUnknown unk; WitnessUnknown unk;
unk.version = vSolutions[0][0]; unk.version = vSolutions[0][0];
std::copy(vSolutions[1].begin(), vSolutions[1].end(), unk.program); std::copy(vSolutions[1].begin(), vSolutions[1].end(), unk.program);
@ -215,19 +215,19 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
return false; return false;
} }
bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet) bool ExtractDestinations(const CScript& scriptPubKey, TxoutType& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet)
{ {
addressRet.clear(); addressRet.clear();
std::vector<valtype> vSolutions; std::vector<valtype> vSolutions;
typeRet = Solver(scriptPubKey, vSolutions); typeRet = Solver(scriptPubKey, vSolutions);
if (typeRet == TX_NONSTANDARD) { if (typeRet == TxoutType::NONSTANDARD) {
return false; return false;
} else if (typeRet == TX_NULL_DATA) { } else if (typeRet == TxoutType::NULL_DATA) {
// This is data, not addresses // This is data, not addresses
return false; return false;
} }
if (typeRet == TX_MULTISIG) if (typeRet == TxoutType::MULTISIG)
{ {
nRequiredRet = vSolutions.front()[0]; nRequiredRet = vSolutions.front()[0];
for (unsigned int i = 1; i < vSolutions.size()-1; i++) for (unsigned int i = 1; i < vSolutions.size()-1; i++)
@ -319,10 +319,10 @@ CScript GetScriptForMultisig(int nRequired, const std::vector<CPubKey>& keys)
CScript GetScriptForWitness(const CScript& redeemscript) CScript GetScriptForWitness(const CScript& redeemscript)
{ {
std::vector<std::vector<unsigned char> > vSolutions; std::vector<std::vector<unsigned char> > vSolutions;
txnouttype typ = Solver(redeemscript, vSolutions); TxoutType typ = Solver(redeemscript, vSolutions);
if (typ == TX_PUBKEY) { if (typ == TxoutType::PUBKEY) {
return GetScriptForDestination(WitnessV0KeyHash(Hash160(vSolutions[0].begin(), vSolutions[0].end()))); return GetScriptForDestination(WitnessV0KeyHash(Hash160(vSolutions[0].begin(), vSolutions[0].end())));
} else if (typ == TX_PUBKEYHASH) { } else if (typ == TxoutType::PUBKEYHASH) {
return GetScriptForDestination(WitnessV0KeyHash(uint160{vSolutions[0]})); return GetScriptForDestination(WitnessV0KeyHash(uint160{vSolutions[0]}));
} }
return GetScriptForDestination(WitnessV0ScriptHash(redeemscript)); return GetScriptForDestination(WitnessV0ScriptHash(redeemscript));

View file

@ -99,11 +99,11 @@ static const unsigned int MAX_OP_RETURN_RELAY = 83;
/** /**
* A data carrying output is an unspendable output containing data. The script * A data carrying output is an unspendable output containing data. The script
* type is designated as TX_NULL_DATA. * type is designated as TxoutType::NULL_DATA.
*/ */
extern bool fAcceptDatacarrier; extern bool fAcceptDatacarrier;
/** Maximum size of TX_NULL_DATA scripts that this node considers standard. */ /** Maximum size of TxoutType::NULL_DATA scripts that this node considers standard. */
extern unsigned nMaxDatacarrierBytes; extern unsigned nMaxDatacarrierBytes;
/** /**
@ -116,17 +116,17 @@ extern unsigned nMaxDatacarrierBytes;
*/ */
static const unsigned int MANDATORY_SCRIPT_VERIFY_FLAGS = SCRIPT_VERIFY_P2SH; static const unsigned int MANDATORY_SCRIPT_VERIFY_FLAGS = SCRIPT_VERIFY_P2SH;
enum txnouttype { enum class TxoutType {
TX_NONSTANDARD, NONSTANDARD,
// 'standard' transaction types: // 'standard' transaction types:
TX_PUBKEY, PUBKEY,
TX_PUBKEYHASH, PUBKEYHASH,
TX_SCRIPTHASH, SCRIPTHASH,
TX_MULTISIG, MULTISIG,
TX_NULL_DATA, //!< unspendable OP_RETURN script that carries data NULL_DATA, //!< unspendable OP_RETURN script that carries data
TX_WITNESS_V0_SCRIPTHASH, WITNESS_V0_SCRIPTHASH,
TX_WITNESS_V0_KEYHASH, WITNESS_V0_KEYHASH,
TX_WITNESS_UNKNOWN, //!< Only for Witness versions not already defined above WITNESS_UNKNOWN, //!< Only for Witness versions not already defined above
}; };
class CNoDestination { class CNoDestination {
@ -199,11 +199,11 @@ struct WitnessUnknown
/** /**
* A txout script template with a specific destination. It is either: * A txout script template with a specific destination. It is either:
* * CNoDestination: no destination set * * CNoDestination: no destination set
* * PKHash: TX_PUBKEYHASH destination (P2PKH) * * PKHash: TxoutType::PUBKEYHASH destination (P2PKH)
* * ScriptHash: TX_SCRIPTHASH destination (P2SH) * * ScriptHash: TxoutType::SCRIPTHASH destination (P2SH)
* * WitnessV0ScriptHash: TX_WITNESS_V0_SCRIPTHASH destination (P2WSH) * * WitnessV0ScriptHash: TxoutType::WITNESS_V0_SCRIPTHASH destination (P2WSH)
* * WitnessV0KeyHash: TX_WITNESS_V0_KEYHASH destination (P2WPKH) * * WitnessV0KeyHash: TxoutType::WITNESS_V0_KEYHASH destination (P2WPKH)
* * WitnessUnknown: TX_WITNESS_UNKNOWN destination (P2W???) * * WitnessUnknown: TxoutType::WITNESS_UNKNOWN destination (P2W???)
* A CTxDestination is the internal data type encoded in a bitcoin address * A CTxDestination is the internal data type encoded in a bitcoin address
*/ */
typedef boost::variant<CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessUnknown> CTxDestination; typedef boost::variant<CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessUnknown> CTxDestination;
@ -211,8 +211,8 @@ typedef boost::variant<CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash,
/** Check whether a CTxDestination is a CNoDestination. */ /** Check whether a CTxDestination is a CNoDestination. */
bool IsValidDestination(const CTxDestination& dest); bool IsValidDestination(const CTxDestination& dest);
/** Get the name of a txnouttype as a string */ /** Get the name of a TxoutType as a string */
std::string GetTxnOutputType(txnouttype t); std::string GetTxnOutputType(TxoutType t);
/** /**
* Parse a scriptPubKey and identify script type for standard scripts. If * Parse a scriptPubKey and identify script type for standard scripts. If
@ -222,9 +222,9 @@ std::string GetTxnOutputType(txnouttype t);
* *
* @param[in] scriptPubKey Script to parse * @param[in] scriptPubKey Script to parse
* @param[out] vSolutionsRet Vector of parsed pubkeys and hashes * @param[out] vSolutionsRet Vector of parsed pubkeys and hashes
* @return The script type. TX_NONSTANDARD represents a failed solve. * @return The script type. TxoutType::NONSTANDARD represents a failed solve.
*/ */
txnouttype Solver(const CScript& scriptPubKey, std::vector<std::vector<unsigned char>>& vSolutionsRet); TxoutType Solver(const CScript& scriptPubKey, std::vector<std::vector<unsigned char>>& vSolutionsRet);
/** /**
* Parse a standard scriptPubKey for the destination address. Assigns result to * Parse a standard scriptPubKey for the destination address. Assigns result to
@ -245,7 +245,7 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
* encodable as an address) with key identifiers (of keys involved in a * encodable as an address) with key identifiers (of keys involved in a
* CScript), and its use should be phased out. * CScript), and its use should be phased out.
*/ */
bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet); bool ExtractDestinations(const CScript& scriptPubKey, TxoutType& typeRet, std::vector<CTxDestination>& addressRet, int& nRequiredRet);
/** /**
* Generate a Bitcoin scriptPubKey for the given CTxDestination. Returns a P2PKH * Generate a Bitcoin scriptPubKey for the given CTxDestination. Returns a P2PKH

View file

@ -157,25 +157,25 @@ void test_one_input(const std::vector<uint8_t>& buffer)
assert(ok_add_key_pubkey); assert(ok_add_key_pubkey);
assert(fillable_signing_provider_pub.HaveKey(pubkey.GetID())); assert(fillable_signing_provider_pub.HaveKey(pubkey.GetID()));
txnouttype which_type_tx_pubkey; TxoutType which_type_tx_pubkey;
const bool is_standard_tx_pubkey = IsStandard(tx_pubkey_script, which_type_tx_pubkey); const bool is_standard_tx_pubkey = IsStandard(tx_pubkey_script, which_type_tx_pubkey);
assert(is_standard_tx_pubkey); assert(is_standard_tx_pubkey);
assert(which_type_tx_pubkey == TX_PUBKEY); assert(which_type_tx_pubkey == TxoutType::PUBKEY);
txnouttype which_type_tx_multisig; TxoutType which_type_tx_multisig;
const bool is_standard_tx_multisig = IsStandard(tx_multisig_script, which_type_tx_multisig); const bool is_standard_tx_multisig = IsStandard(tx_multisig_script, which_type_tx_multisig);
assert(is_standard_tx_multisig); assert(is_standard_tx_multisig);
assert(which_type_tx_multisig == TX_MULTISIG); assert(which_type_tx_multisig == TxoutType::MULTISIG);
std::vector<std::vector<unsigned char>> v_solutions_ret_tx_pubkey; std::vector<std::vector<unsigned char>> v_solutions_ret_tx_pubkey;
const txnouttype outtype_tx_pubkey = Solver(tx_pubkey_script, v_solutions_ret_tx_pubkey); const TxoutType outtype_tx_pubkey = Solver(tx_pubkey_script, v_solutions_ret_tx_pubkey);
assert(outtype_tx_pubkey == TX_PUBKEY); assert(outtype_tx_pubkey == TxoutType::PUBKEY);
assert(v_solutions_ret_tx_pubkey.size() == 1); assert(v_solutions_ret_tx_pubkey.size() == 1);
assert(v_solutions_ret_tx_pubkey[0].size() == 33); assert(v_solutions_ret_tx_pubkey[0].size() == 33);
std::vector<std::vector<unsigned char>> v_solutions_ret_tx_multisig; std::vector<std::vector<unsigned char>> v_solutions_ret_tx_multisig;
const txnouttype outtype_tx_multisig = Solver(tx_multisig_script, v_solutions_ret_tx_multisig); const TxoutType outtype_tx_multisig = Solver(tx_multisig_script, v_solutions_ret_tx_multisig);
assert(outtype_tx_multisig == TX_MULTISIG); assert(outtype_tx_multisig == TxoutType::MULTISIG);
assert(v_solutions_ret_tx_multisig.size() == 3); assert(v_solutions_ret_tx_multisig.size() == 3);
assert(v_solutions_ret_tx_multisig[0].size() == 1); assert(v_solutions_ret_tx_multisig[0].size() == 1);
assert(v_solutions_ret_tx_multisig[1].size() == 33); assert(v_solutions_ret_tx_multisig[1].size() == 33);

View file

@ -58,7 +58,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
CTxDestination address; CTxDestination address;
(void)ExtractDestination(script, address); (void)ExtractDestination(script, address);
txnouttype type_ret; TxoutType type_ret;
std::vector<CTxDestination> addresses; std::vector<CTxDestination> addresses;
int required_ret; int required_ret;
(void)ExtractDestinations(script, type_ret, addresses, required_ret); (void)ExtractDestinations(script, type_ret, addresses, required_ret);
@ -72,7 +72,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
(void)IsSolvable(signing_provider, script); (void)IsSolvable(signing_provider, script);
txnouttype which_type; TxoutType which_type;
(void)IsStandard(script, which_type); (void)IsStandard(script, which_type);
(void)RecursiveDynamicUsage(script); (void)RecursiveDynamicUsage(script);

View file

@ -141,7 +141,7 @@ BOOST_AUTO_TEST_CASE(multisig_IsStandard)
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
key[i].MakeNewKey(true); key[i].MakeNewKey(true);
txnouttype whichType; TxoutType whichType;
CScript a_and_b; CScript a_and_b;
a_and_b << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG; a_and_b << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;

View file

@ -31,35 +31,35 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success)
CScript s; CScript s;
std::vector<std::vector<unsigned char> > solutions; std::vector<std::vector<unsigned char> > solutions;
// TX_PUBKEY // TxoutType::PUBKEY
s.clear(); s.clear();
s << ToByteVector(pubkeys[0]) << OP_CHECKSIG; s << ToByteVector(pubkeys[0]) << OP_CHECKSIG;
BOOST_CHECK_EQUAL(Solver(s, solutions), TX_PUBKEY); BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::PUBKEY);
BOOST_CHECK_EQUAL(solutions.size(), 1U); BOOST_CHECK_EQUAL(solutions.size(), 1U);
BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0])); BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0]));
// TX_PUBKEYHASH // TxoutType::PUBKEYHASH
s.clear(); s.clear();
s << OP_DUP << OP_HASH160 << ToByteVector(pubkeys[0].GetID()) << OP_EQUALVERIFY << OP_CHECKSIG; s << OP_DUP << OP_HASH160 << ToByteVector(pubkeys[0].GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
BOOST_CHECK_EQUAL(Solver(s, solutions), TX_PUBKEYHASH); BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::PUBKEYHASH);
BOOST_CHECK_EQUAL(solutions.size(), 1U); BOOST_CHECK_EQUAL(solutions.size(), 1U);
BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0].GetID())); BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0].GetID()));
// TX_SCRIPTHASH // TxoutType::SCRIPTHASH
CScript redeemScript(s); // initialize with leftover P2PKH script CScript redeemScript(s); // initialize with leftover P2PKH script
s.clear(); s.clear();
s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL; s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
BOOST_CHECK_EQUAL(Solver(s, solutions), TX_SCRIPTHASH); BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::SCRIPTHASH);
BOOST_CHECK_EQUAL(solutions.size(), 1U); BOOST_CHECK_EQUAL(solutions.size(), 1U);
BOOST_CHECK(solutions[0] == ToByteVector(CScriptID(redeemScript))); BOOST_CHECK(solutions[0] == ToByteVector(CScriptID(redeemScript)));
// TX_MULTISIG // TxoutType::MULTISIG
s.clear(); s.clear();
s << OP_1 << s << OP_1 <<
ToByteVector(pubkeys[0]) << ToByteVector(pubkeys[0]) <<
ToByteVector(pubkeys[1]) << ToByteVector(pubkeys[1]) <<
OP_2 << OP_CHECKMULTISIG; OP_2 << OP_CHECKMULTISIG;
BOOST_CHECK_EQUAL(Solver(s, solutions), TX_MULTISIG); BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::MULTISIG);
BOOST_CHECK_EQUAL(solutions.size(), 4U); BOOST_CHECK_EQUAL(solutions.size(), 4U);
BOOST_CHECK(solutions[0] == std::vector<unsigned char>({1})); BOOST_CHECK(solutions[0] == std::vector<unsigned char>({1}));
BOOST_CHECK(solutions[1] == ToByteVector(pubkeys[0])); BOOST_CHECK(solutions[1] == ToByteVector(pubkeys[0]));
@ -72,7 +72,7 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success)
ToByteVector(pubkeys[1]) << ToByteVector(pubkeys[1]) <<
ToByteVector(pubkeys[2]) << ToByteVector(pubkeys[2]) <<
OP_3 << OP_CHECKMULTISIG; OP_3 << OP_CHECKMULTISIG;
BOOST_CHECK_EQUAL(Solver(s, solutions), TX_MULTISIG); BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::MULTISIG);
BOOST_CHECK_EQUAL(solutions.size(), 5U); BOOST_CHECK_EQUAL(solutions.size(), 5U);
BOOST_CHECK(solutions[0] == std::vector<unsigned char>({2})); BOOST_CHECK(solutions[0] == std::vector<unsigned char>({2}));
BOOST_CHECK(solutions[1] == ToByteVector(pubkeys[0])); BOOST_CHECK(solutions[1] == ToByteVector(pubkeys[0]));
@ -80,37 +80,37 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success)
BOOST_CHECK(solutions[3] == ToByteVector(pubkeys[2])); BOOST_CHECK(solutions[3] == ToByteVector(pubkeys[2]));
BOOST_CHECK(solutions[4] == std::vector<unsigned char>({3})); BOOST_CHECK(solutions[4] == std::vector<unsigned char>({3}));
// TX_NULL_DATA // TxoutType::NULL_DATA
s.clear(); s.clear();
s << OP_RETURN << s << OP_RETURN <<
std::vector<unsigned char>({0}) << std::vector<unsigned char>({0}) <<
std::vector<unsigned char>({75}) << std::vector<unsigned char>({75}) <<
std::vector<unsigned char>({255}); std::vector<unsigned char>({255});
BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NULL_DATA); BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NULL_DATA);
BOOST_CHECK_EQUAL(solutions.size(), 0U); BOOST_CHECK_EQUAL(solutions.size(), 0U);
// TX_WITNESS_V0_KEYHASH // TxoutType::WITNESS_V0_KEYHASH
s.clear(); s.clear();
s << OP_0 << ToByteVector(pubkeys[0].GetID()); s << OP_0 << ToByteVector(pubkeys[0].GetID());
BOOST_CHECK_EQUAL(Solver(s, solutions), TX_WITNESS_V0_KEYHASH); BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::WITNESS_V0_KEYHASH);
BOOST_CHECK_EQUAL(solutions.size(), 1U); BOOST_CHECK_EQUAL(solutions.size(), 1U);
BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0].GetID())); BOOST_CHECK(solutions[0] == ToByteVector(pubkeys[0].GetID()));
// TX_WITNESS_V0_SCRIPTHASH // TxoutType::WITNESS_V0_SCRIPTHASH
uint256 scriptHash; uint256 scriptHash;
CSHA256().Write(&redeemScript[0], redeemScript.size()) CSHA256().Write(&redeemScript[0], redeemScript.size())
.Finalize(scriptHash.begin()); .Finalize(scriptHash.begin());
s.clear(); s.clear();
s << OP_0 << ToByteVector(scriptHash); s << OP_0 << ToByteVector(scriptHash);
BOOST_CHECK_EQUAL(Solver(s, solutions), TX_WITNESS_V0_SCRIPTHASH); BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::WITNESS_V0_SCRIPTHASH);
BOOST_CHECK_EQUAL(solutions.size(), 1U); BOOST_CHECK_EQUAL(solutions.size(), 1U);
BOOST_CHECK(solutions[0] == ToByteVector(scriptHash)); BOOST_CHECK(solutions[0] == ToByteVector(scriptHash));
// TX_NONSTANDARD // TxoutType::NONSTANDARD
s.clear(); s.clear();
s << OP_9 << OP_ADD << OP_11 << OP_EQUAL; s << OP_9 << OP_ADD << OP_11 << OP_EQUAL;
BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD); BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
} }
BOOST_AUTO_TEST_CASE(script_standard_Solver_failure) BOOST_AUTO_TEST_CASE(script_standard_Solver_failure)
@ -123,50 +123,50 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_failure)
CScript s; CScript s;
std::vector<std::vector<unsigned char> > solutions; std::vector<std::vector<unsigned char> > solutions;
// TX_PUBKEY with incorrectly sized pubkey // TxoutType::PUBKEY with incorrectly sized pubkey
s.clear(); s.clear();
s << std::vector<unsigned char>(30, 0x01) << OP_CHECKSIG; s << std::vector<unsigned char>(30, 0x01) << OP_CHECKSIG;
BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD); BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
// TX_PUBKEYHASH with incorrectly sized key hash // TxoutType::PUBKEYHASH with incorrectly sized key hash
s.clear(); s.clear();
s << OP_DUP << OP_HASH160 << ToByteVector(pubkey) << OP_EQUALVERIFY << OP_CHECKSIG; s << OP_DUP << OP_HASH160 << ToByteVector(pubkey) << OP_EQUALVERIFY << OP_CHECKSIG;
BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD); BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
// TX_SCRIPTHASH with incorrectly sized script hash // TxoutType::SCRIPTHASH with incorrectly sized script hash
s.clear(); s.clear();
s << OP_HASH160 << std::vector<unsigned char>(21, 0x01) << OP_EQUAL; s << OP_HASH160 << std::vector<unsigned char>(21, 0x01) << OP_EQUAL;
BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD); BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
// TX_MULTISIG 0/2 // TxoutType::MULTISIG 0/2
s.clear(); s.clear();
s << OP_0 << ToByteVector(pubkey) << OP_1 << OP_CHECKMULTISIG; s << OP_0 << ToByteVector(pubkey) << OP_1 << OP_CHECKMULTISIG;
BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD); BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
// TX_MULTISIG 2/1 // TxoutType::MULTISIG 2/1
s.clear(); s.clear();
s << OP_2 << ToByteVector(pubkey) << OP_1 << OP_CHECKMULTISIG; s << OP_2 << ToByteVector(pubkey) << OP_1 << OP_CHECKMULTISIG;
BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD); BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
// TX_MULTISIG n = 2 with 1 pubkey // TxoutType::MULTISIG n = 2 with 1 pubkey
s.clear(); s.clear();
s << OP_1 << ToByteVector(pubkey) << OP_2 << OP_CHECKMULTISIG; s << OP_1 << ToByteVector(pubkey) << OP_2 << OP_CHECKMULTISIG;
BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD); BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
// TX_MULTISIG n = 1 with 0 pubkeys // TxoutType::MULTISIG n = 1 with 0 pubkeys
s.clear(); s.clear();
s << OP_1 << OP_1 << OP_CHECKMULTISIG; s << OP_1 << OP_1 << OP_CHECKMULTISIG;
BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD); BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
// TX_NULL_DATA with other opcodes // TxoutType::NULL_DATA with other opcodes
s.clear(); s.clear();
s << OP_RETURN << std::vector<unsigned char>({75}) << OP_ADD; s << OP_RETURN << std::vector<unsigned char>({75}) << OP_ADD;
BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD); BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
// TX_WITNESS_UNKNOWN with incorrect program size // TxoutType::WITNESS_UNKNOWN with incorrect program size
s.clear(); s.clear();
s << OP_0 << std::vector<unsigned char>(19, 0x01); s << OP_0 << std::vector<unsigned char>(19, 0x01);
BOOST_CHECK_EQUAL(Solver(s, solutions), TX_NONSTANDARD); BOOST_CHECK_EQUAL(Solver(s, solutions), TxoutType::NONSTANDARD);
} }
BOOST_AUTO_TEST_CASE(script_standard_ExtractDestination) BOOST_AUTO_TEST_CASE(script_standard_ExtractDestination)
@ -179,21 +179,21 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestination)
CScript s; CScript s;
CTxDestination address; CTxDestination address;
// TX_PUBKEY // TxoutType::PUBKEY
s.clear(); s.clear();
s << ToByteVector(pubkey) << OP_CHECKSIG; s << ToByteVector(pubkey) << OP_CHECKSIG;
BOOST_CHECK(ExtractDestination(s, address)); BOOST_CHECK(ExtractDestination(s, address));
BOOST_CHECK(boost::get<PKHash>(&address) && BOOST_CHECK(boost::get<PKHash>(&address) &&
*boost::get<PKHash>(&address) == PKHash(pubkey)); *boost::get<PKHash>(&address) == PKHash(pubkey));
// TX_PUBKEYHASH // TxoutType::PUBKEYHASH
s.clear(); s.clear();
s << OP_DUP << OP_HASH160 << ToByteVector(pubkey.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG; s << OP_DUP << OP_HASH160 << ToByteVector(pubkey.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
BOOST_CHECK(ExtractDestination(s, address)); BOOST_CHECK(ExtractDestination(s, address));
BOOST_CHECK(boost::get<PKHash>(&address) && BOOST_CHECK(boost::get<PKHash>(&address) &&
*boost::get<PKHash>(&address) == PKHash(pubkey)); *boost::get<PKHash>(&address) == PKHash(pubkey));
// TX_SCRIPTHASH // TxoutType::SCRIPTHASH
CScript redeemScript(s); // initialize with leftover P2PKH script CScript redeemScript(s); // initialize with leftover P2PKH script
s.clear(); s.clear();
s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL; s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
@ -201,17 +201,17 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestination)
BOOST_CHECK(boost::get<ScriptHash>(&address) && BOOST_CHECK(boost::get<ScriptHash>(&address) &&
*boost::get<ScriptHash>(&address) == ScriptHash(redeemScript)); *boost::get<ScriptHash>(&address) == ScriptHash(redeemScript));
// TX_MULTISIG // TxoutType::MULTISIG
s.clear(); s.clear();
s << OP_1 << ToByteVector(pubkey) << OP_1 << OP_CHECKMULTISIG; s << OP_1 << ToByteVector(pubkey) << OP_1 << OP_CHECKMULTISIG;
BOOST_CHECK(!ExtractDestination(s, address)); BOOST_CHECK(!ExtractDestination(s, address));
// TX_NULL_DATA // TxoutType::NULL_DATA
s.clear(); s.clear();
s << OP_RETURN << std::vector<unsigned char>({75}); s << OP_RETURN << std::vector<unsigned char>({75});
BOOST_CHECK(!ExtractDestination(s, address)); BOOST_CHECK(!ExtractDestination(s, address));
// TX_WITNESS_V0_KEYHASH // TxoutType::WITNESS_V0_KEYHASH
s.clear(); s.clear();
s << OP_0 << ToByteVector(pubkey.GetID()); s << OP_0 << ToByteVector(pubkey.GetID());
BOOST_CHECK(ExtractDestination(s, address)); BOOST_CHECK(ExtractDestination(s, address));
@ -219,7 +219,7 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestination)
CHash160().Write(pubkey.begin(), pubkey.size()).Finalize(keyhash.begin()); CHash160().Write(pubkey.begin(), pubkey.size()).Finalize(keyhash.begin());
BOOST_CHECK(boost::get<WitnessV0KeyHash>(&address) && *boost::get<WitnessV0KeyHash>(&address) == keyhash); BOOST_CHECK(boost::get<WitnessV0KeyHash>(&address) && *boost::get<WitnessV0KeyHash>(&address) == keyhash);
// TX_WITNESS_V0_SCRIPTHASH // TxoutType::WITNESS_V0_SCRIPTHASH
s.clear(); s.clear();
WitnessV0ScriptHash scripthash; WitnessV0ScriptHash scripthash;
CSHA256().Write(redeemScript.data(), redeemScript.size()).Finalize(scripthash.begin()); CSHA256().Write(redeemScript.data(), redeemScript.size()).Finalize(scripthash.begin());
@ -227,7 +227,7 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestination)
BOOST_CHECK(ExtractDestination(s, address)); BOOST_CHECK(ExtractDestination(s, address));
BOOST_CHECK(boost::get<WitnessV0ScriptHash>(&address) && *boost::get<WitnessV0ScriptHash>(&address) == scripthash); BOOST_CHECK(boost::get<WitnessV0ScriptHash>(&address) && *boost::get<WitnessV0ScriptHash>(&address) == scripthash);
// TX_WITNESS_UNKNOWN with unknown version // TxoutType::WITNESS_UNKNOWN with unknown version
s.clear(); s.clear();
s << OP_1 << ToByteVector(pubkey); s << OP_1 << ToByteVector(pubkey);
BOOST_CHECK(ExtractDestination(s, address)); BOOST_CHECK(ExtractDestination(s, address));
@ -248,49 +248,49 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestinations)
} }
CScript s; CScript s;
txnouttype whichType; TxoutType whichType;
std::vector<CTxDestination> addresses; std::vector<CTxDestination> addresses;
int nRequired; int nRequired;
// TX_PUBKEY // TxoutType::PUBKEY
s.clear(); s.clear();
s << ToByteVector(pubkeys[0]) << OP_CHECKSIG; s << ToByteVector(pubkeys[0]) << OP_CHECKSIG;
BOOST_CHECK(ExtractDestinations(s, whichType, addresses, nRequired)); BOOST_CHECK(ExtractDestinations(s, whichType, addresses, nRequired));
BOOST_CHECK_EQUAL(whichType, TX_PUBKEY); BOOST_CHECK_EQUAL(whichType, TxoutType::PUBKEY);
BOOST_CHECK_EQUAL(addresses.size(), 1U); BOOST_CHECK_EQUAL(addresses.size(), 1U);
BOOST_CHECK_EQUAL(nRequired, 1); BOOST_CHECK_EQUAL(nRequired, 1);
BOOST_CHECK(boost::get<PKHash>(&addresses[0]) && BOOST_CHECK(boost::get<PKHash>(&addresses[0]) &&
*boost::get<PKHash>(&addresses[0]) == PKHash(pubkeys[0])); *boost::get<PKHash>(&addresses[0]) == PKHash(pubkeys[0]));
// TX_PUBKEYHASH // TxoutType::PUBKEYHASH
s.clear(); s.clear();
s << OP_DUP << OP_HASH160 << ToByteVector(pubkeys[0].GetID()) << OP_EQUALVERIFY << OP_CHECKSIG; s << OP_DUP << OP_HASH160 << ToByteVector(pubkeys[0].GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
BOOST_CHECK(ExtractDestinations(s, whichType, addresses, nRequired)); BOOST_CHECK(ExtractDestinations(s, whichType, addresses, nRequired));
BOOST_CHECK_EQUAL(whichType, TX_PUBKEYHASH); BOOST_CHECK_EQUAL(whichType, TxoutType::PUBKEYHASH);
BOOST_CHECK_EQUAL(addresses.size(), 1U); BOOST_CHECK_EQUAL(addresses.size(), 1U);
BOOST_CHECK_EQUAL(nRequired, 1); BOOST_CHECK_EQUAL(nRequired, 1);
BOOST_CHECK(boost::get<PKHash>(&addresses[0]) && BOOST_CHECK(boost::get<PKHash>(&addresses[0]) &&
*boost::get<PKHash>(&addresses[0]) == PKHash(pubkeys[0])); *boost::get<PKHash>(&addresses[0]) == PKHash(pubkeys[0]));
// TX_SCRIPTHASH // TxoutType::SCRIPTHASH
CScript redeemScript(s); // initialize with leftover P2PKH script CScript redeemScript(s); // initialize with leftover P2PKH script
s.clear(); s.clear();
s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL; s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
BOOST_CHECK(ExtractDestinations(s, whichType, addresses, nRequired)); BOOST_CHECK(ExtractDestinations(s, whichType, addresses, nRequired));
BOOST_CHECK_EQUAL(whichType, TX_SCRIPTHASH); BOOST_CHECK_EQUAL(whichType, TxoutType::SCRIPTHASH);
BOOST_CHECK_EQUAL(addresses.size(), 1U); BOOST_CHECK_EQUAL(addresses.size(), 1U);
BOOST_CHECK_EQUAL(nRequired, 1); BOOST_CHECK_EQUAL(nRequired, 1);
BOOST_CHECK(boost::get<ScriptHash>(&addresses[0]) && BOOST_CHECK(boost::get<ScriptHash>(&addresses[0]) &&
*boost::get<ScriptHash>(&addresses[0]) == ScriptHash(redeemScript)); *boost::get<ScriptHash>(&addresses[0]) == ScriptHash(redeemScript));
// TX_MULTISIG // TxoutType::MULTISIG
s.clear(); s.clear();
s << OP_2 << s << OP_2 <<
ToByteVector(pubkeys[0]) << ToByteVector(pubkeys[0]) <<
ToByteVector(pubkeys[1]) << ToByteVector(pubkeys[1]) <<
OP_2 << OP_CHECKMULTISIG; OP_2 << OP_CHECKMULTISIG;
BOOST_CHECK(ExtractDestinations(s, whichType, addresses, nRequired)); BOOST_CHECK(ExtractDestinations(s, whichType, addresses, nRequired));
BOOST_CHECK_EQUAL(whichType, TX_MULTISIG); BOOST_CHECK_EQUAL(whichType, TxoutType::MULTISIG);
BOOST_CHECK_EQUAL(addresses.size(), 2U); BOOST_CHECK_EQUAL(addresses.size(), 2U);
BOOST_CHECK_EQUAL(nRequired, 2); BOOST_CHECK_EQUAL(nRequired, 2);
BOOST_CHECK(boost::get<PKHash>(&addresses[0]) && BOOST_CHECK(boost::get<PKHash>(&addresses[0]) &&
@ -298,7 +298,7 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestinations)
BOOST_CHECK(boost::get<PKHash>(&addresses[1]) && BOOST_CHECK(boost::get<PKHash>(&addresses[1]) &&
*boost::get<PKHash>(&addresses[1]) == PKHash(pubkeys[1])); *boost::get<PKHash>(&addresses[1]) == PKHash(pubkeys[1]));
// TX_NULL_DATA // TxoutType::NULL_DATA
s.clear(); s.clear();
s << OP_RETURN << std::vector<unsigned char>({75}); s << OP_RETURN << std::vector<unsigned char>({75});
BOOST_CHECK(!ExtractDestinations(s, whichType, addresses, nRequired)); BOOST_CHECK(!ExtractDestinations(s, whichType, addresses, nRequired));

View file

@ -716,12 +716,12 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
BOOST_CHECK(!IsStandardTx(CTransaction(t), reason)); BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
BOOST_CHECK_EQUAL(reason, "scriptpubkey"); BOOST_CHECK_EQUAL(reason, "scriptpubkey");
// MAX_OP_RETURN_RELAY-byte TX_NULL_DATA (standard) // MAX_OP_RETURN_RELAY-byte TxoutType::NULL_DATA (standard)
t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"); t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38");
BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY, t.vout[0].scriptPubKey.size()); BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY, t.vout[0].scriptPubKey.size());
BOOST_CHECK(IsStandardTx(CTransaction(t), reason)); BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
// MAX_OP_RETURN_RELAY+1-byte TX_NULL_DATA (non-standard) // MAX_OP_RETURN_RELAY+1-byte TxoutType::NULL_DATA (non-standard)
t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3800"); t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3800");
BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY + 1, t.vout[0].scriptPubKey.size()); BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY + 1, t.vout[0].scriptPubKey.size());
reason.clear(); reason.clear();
@ -745,12 +745,12 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
BOOST_CHECK(!IsStandardTx(CTransaction(t), reason)); BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
BOOST_CHECK_EQUAL(reason, "scriptpubkey"); BOOST_CHECK_EQUAL(reason, "scriptpubkey");
// TX_NULL_DATA w/o PUSHDATA // TxoutType::NULL_DATA w/o PUSHDATA
t.vout.resize(1); t.vout.resize(1);
t.vout[0].scriptPubKey = CScript() << OP_RETURN; t.vout[0].scriptPubKey = CScript() << OP_RETURN;
BOOST_CHECK(IsStandardTx(CTransaction(t), reason)); BOOST_CHECK(IsStandardTx(CTransaction(t), reason));
// Only one TX_NULL_DATA permitted in all cases // Only one TxoutType::NULL_DATA permitted in all cases
t.vout.resize(2); t.vout.resize(2);
t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"); t.vout[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38");
t.vout[1].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"); t.vout[1].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38");

View file

@ -22,8 +22,8 @@ CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey, int n
CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CScriptWitness& scriptWitness, const CTransaction& txCredit); CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CScriptWitness& scriptWitness, const CTransaction& txCredit);
// Helper: create two dummy transactions, each with two outputs. // Helper: create two dummy transactions, each with two outputs.
// The first has nValues[0] and nValues[1] outputs paid to a TX_PUBKEY, // The first has nValues[0] and nValues[1] outputs paid to a TxoutType::PUBKEY,
// the second nValues[2] and nValues[3] outputs paid to a TX_PUBKEYHASH. // the second nValues[2] and nValues[3] outputs paid to a TxoutType::PUBKEYHASH.
std::vector<CMutableTransaction> SetupDummyInputs(FillableSigningProvider& keystoreRet, CCoinsViewCache& coinsRet, const std::array<CAmount,4>& nValues); std::vector<CMutableTransaction> SetupDummyInputs(FillableSigningProvider& keystoreRet, CCoinsViewCache& coinsRet, const std::array<CAmount,4>& nValues);
#endif // BITCOIN_TEST_UTIL_TRANSACTION_UTILS_H #endif // BITCOIN_TEST_UTIL_TRANSACTION_UTILS_H

View file

@ -856,20 +856,20 @@ static std::string RecurseImportData(const CScript& script, ImportData& import_d
{ {
// Use Solver to obtain script type and parsed pubkeys or hashes: // Use Solver to obtain script type and parsed pubkeys or hashes:
std::vector<std::vector<unsigned char>> solverdata; std::vector<std::vector<unsigned char>> solverdata;
txnouttype script_type = Solver(script, solverdata); TxoutType script_type = Solver(script, solverdata);
switch (script_type) { switch (script_type) {
case TX_PUBKEY: { case TxoutType::PUBKEY: {
CPubKey pubkey(solverdata[0].begin(), solverdata[0].end()); CPubKey pubkey(solverdata[0].begin(), solverdata[0].end());
import_data.used_keys.emplace(pubkey.GetID(), false); import_data.used_keys.emplace(pubkey.GetID(), false);
return ""; return "";
} }
case TX_PUBKEYHASH: { case TxoutType::PUBKEYHASH: {
CKeyID id = CKeyID(uint160(solverdata[0])); CKeyID id = CKeyID(uint160(solverdata[0]));
import_data.used_keys[id] = true; import_data.used_keys[id] = true;
return ""; return "";
} }
case TX_SCRIPTHASH: { case TxoutType::SCRIPTHASH: {
if (script_ctx == ScriptContext::P2SH) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Trying to nest P2SH inside another P2SH"); if (script_ctx == ScriptContext::P2SH) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Trying to nest P2SH inside another P2SH");
if (script_ctx == ScriptContext::WITNESS_V0) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Trying to nest P2SH inside a P2WSH"); if (script_ctx == ScriptContext::WITNESS_V0) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Trying to nest P2SH inside a P2WSH");
CHECK_NONFATAL(script_ctx == ScriptContext::TOP); CHECK_NONFATAL(script_ctx == ScriptContext::TOP);
@ -880,14 +880,14 @@ static std::string RecurseImportData(const CScript& script, ImportData& import_d
import_data.import_scripts.emplace(*subscript); import_data.import_scripts.emplace(*subscript);
return RecurseImportData(*subscript, import_data, ScriptContext::P2SH); return RecurseImportData(*subscript, import_data, ScriptContext::P2SH);
} }
case TX_MULTISIG: { case TxoutType::MULTISIG: {
for (size_t i = 1; i + 1< solverdata.size(); ++i) { for (size_t i = 1; i + 1< solverdata.size(); ++i) {
CPubKey pubkey(solverdata[i].begin(), solverdata[i].end()); CPubKey pubkey(solverdata[i].begin(), solverdata[i].end());
import_data.used_keys.emplace(pubkey.GetID(), false); import_data.used_keys.emplace(pubkey.GetID(), false);
} }
return ""; return "";
} }
case TX_WITNESS_V0_SCRIPTHASH: { case TxoutType::WITNESS_V0_SCRIPTHASH: {
if (script_ctx == ScriptContext::WITNESS_V0) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Trying to nest P2WSH inside another P2WSH"); if (script_ctx == ScriptContext::WITNESS_V0) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Trying to nest P2WSH inside another P2WSH");
uint256 fullid(solverdata[0]); uint256 fullid(solverdata[0]);
CScriptID id; CScriptID id;
@ -901,7 +901,7 @@ static std::string RecurseImportData(const CScript& script, ImportData& import_d
import_data.import_scripts.emplace(*subscript); import_data.import_scripts.emplace(*subscript);
return RecurseImportData(*subscript, import_data, ScriptContext::WITNESS_V0); return RecurseImportData(*subscript, import_data, ScriptContext::WITNESS_V0);
} }
case TX_WITNESS_V0_KEYHASH: { case TxoutType::WITNESS_V0_KEYHASH: {
if (script_ctx == ScriptContext::WITNESS_V0) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Trying to nest P2WPKH inside P2WSH"); if (script_ctx == ScriptContext::WITNESS_V0) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Trying to nest P2WPKH inside P2WSH");
CKeyID id = CKeyID(uint160(solverdata[0])); CKeyID id = CKeyID(uint160(solverdata[0]));
import_data.used_keys[id] = true; import_data.used_keys[id] = true;
@ -910,10 +910,10 @@ static std::string RecurseImportData(const CScript& script, ImportData& import_d
} }
return ""; return "";
} }
case TX_NULL_DATA: case TxoutType::NULL_DATA:
return "unspendable script"; return "unspendable script";
case TX_NONSTANDARD: case TxoutType::NONSTANDARD:
case TX_WITNESS_UNKNOWN: case TxoutType::WITNESS_UNKNOWN:
default: default:
return "unrecognized script"; return "unrecognized script";
} }

View file

@ -3489,7 +3489,7 @@ public:
{ {
// Always present: script type and redeemscript // Always present: script type and redeemscript
std::vector<std::vector<unsigned char>> solutions_data; std::vector<std::vector<unsigned char>> solutions_data;
txnouttype which_type = Solver(subscript, solutions_data); TxoutType which_type = Solver(subscript, solutions_data);
obj.pushKV("script", GetTxnOutputType(which_type)); obj.pushKV("script", GetTxnOutputType(which_type));
obj.pushKV("hex", HexStr(subscript.begin(), subscript.end())); obj.pushKV("hex", HexStr(subscript.begin(), subscript.end()));
@ -3506,7 +3506,7 @@ public:
// Always report the pubkey at the top level, so that `getnewaddress()['pubkey']` always works. // Always report the pubkey at the top level, so that `getnewaddress()['pubkey']` always works.
if (subobj.exists("pubkey")) obj.pushKV("pubkey", subobj["pubkey"]); if (subobj.exists("pubkey")) obj.pushKV("pubkey", subobj["pubkey"]);
obj.pushKV("embedded", std::move(subobj)); obj.pushKV("embedded", std::move(subobj));
} else if (which_type == TX_MULTISIG) { } else if (which_type == TxoutType::MULTISIG) {
// Also report some information on multisig scripts (which do not have a corresponding address). // Also report some information on multisig scripts (which do not have a corresponding address).
// TODO: abstract out the common functionality between this logic and ExtractDestinations. // TODO: abstract out the common functionality between this logic and ExtractDestinations.
obj.pushKV("sigsrequired", solutions_data[0][0]); obj.pushKV("sigsrequired", solutions_data[0][0]);

View file

@ -88,16 +88,16 @@ IsMineResult IsMineInner(const LegacyScriptPubKeyMan& keystore, const CScript& s
IsMineResult ret = IsMineResult::NO; IsMineResult ret = IsMineResult::NO;
std::vector<valtype> vSolutions; std::vector<valtype> vSolutions;
txnouttype whichType = Solver(scriptPubKey, vSolutions); TxoutType whichType = Solver(scriptPubKey, vSolutions);
CKeyID keyID; CKeyID keyID;
switch (whichType) switch (whichType)
{ {
case TX_NONSTANDARD: case TxoutType::NONSTANDARD:
case TX_NULL_DATA: case TxoutType::NULL_DATA:
case TX_WITNESS_UNKNOWN: case TxoutType::WITNESS_UNKNOWN:
break; break;
case TX_PUBKEY: case TxoutType::PUBKEY:
keyID = CPubKey(vSolutions[0]).GetID(); keyID = CPubKey(vSolutions[0]).GetID();
if (!PermitsUncompressed(sigversion) && vSolutions[0].size() != 33) { if (!PermitsUncompressed(sigversion) && vSolutions[0].size() != 33) {
return IsMineResult::INVALID; return IsMineResult::INVALID;
@ -106,7 +106,7 @@ IsMineResult IsMineInner(const LegacyScriptPubKeyMan& keystore, const CScript& s
ret = std::max(ret, IsMineResult::SPENDABLE); ret = std::max(ret, IsMineResult::SPENDABLE);
} }
break; break;
case TX_WITNESS_V0_KEYHASH: case TxoutType::WITNESS_V0_KEYHASH:
{ {
if (sigversion == IsMineSigVersion::WITNESS_V0) { if (sigversion == IsMineSigVersion::WITNESS_V0) {
// P2WPKH inside P2WSH is invalid. // P2WPKH inside P2WSH is invalid.
@ -121,7 +121,7 @@ IsMineResult IsMineInner(const LegacyScriptPubKeyMan& keystore, const CScript& s
ret = std::max(ret, IsMineInner(keystore, GetScriptForDestination(PKHash(uint160(vSolutions[0]))), IsMineSigVersion::WITNESS_V0)); ret = std::max(ret, IsMineInner(keystore, GetScriptForDestination(PKHash(uint160(vSolutions[0]))), IsMineSigVersion::WITNESS_V0));
break; break;
} }
case TX_PUBKEYHASH: case TxoutType::PUBKEYHASH:
keyID = CKeyID(uint160(vSolutions[0])); keyID = CKeyID(uint160(vSolutions[0]));
if (!PermitsUncompressed(sigversion)) { if (!PermitsUncompressed(sigversion)) {
CPubKey pubkey; CPubKey pubkey;
@ -133,7 +133,7 @@ IsMineResult IsMineInner(const LegacyScriptPubKeyMan& keystore, const CScript& s
ret = std::max(ret, IsMineResult::SPENDABLE); ret = std::max(ret, IsMineResult::SPENDABLE);
} }
break; break;
case TX_SCRIPTHASH: case TxoutType::SCRIPTHASH:
{ {
if (sigversion != IsMineSigVersion::TOP) { if (sigversion != IsMineSigVersion::TOP) {
// P2SH inside P2WSH or P2SH is invalid. // P2SH inside P2WSH or P2SH is invalid.
@ -146,7 +146,7 @@ IsMineResult IsMineInner(const LegacyScriptPubKeyMan& keystore, const CScript& s
} }
break; break;
} }
case TX_WITNESS_V0_SCRIPTHASH: case TxoutType::WITNESS_V0_SCRIPTHASH:
{ {
if (sigversion == IsMineSigVersion::WITNESS_V0) { if (sigversion == IsMineSigVersion::WITNESS_V0) {
// P2WSH inside P2WSH is invalid. // P2WSH inside P2WSH is invalid.
@ -165,7 +165,7 @@ IsMineResult IsMineInner(const LegacyScriptPubKeyMan& keystore, const CScript& s
break; break;
} }
case TX_MULTISIG: case TxoutType::MULTISIG:
{ {
// Never treat bare multisig outputs as ours (they can still be made watchonly-though) // Never treat bare multisig outputs as ours (they can still be made watchonly-though)
if (sigversion == IsMineSigVersion::TOP) { if (sigversion == IsMineSigVersion::TOP) {
@ -825,7 +825,7 @@ bool LegacyScriptPubKeyMan::HaveWatchOnly() const
static bool ExtractPubKey(const CScript &dest, CPubKey& pubKeyOut) static bool ExtractPubKey(const CScript &dest, CPubKey& pubKeyOut)
{ {
std::vector<std::vector<unsigned char>> solutions; std::vector<std::vector<unsigned char>> solutions;
return Solver(dest, solutions) == TX_PUBKEY && return Solver(dest, solutions) == TxoutType::PUBKEY &&
(pubKeyOut = CPubKey(solutions[0])).IsFullyValid(); (pubKeyOut = CPubKey(solutions[0])).IsFullyValid();
} }