mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-20 14:05:23 +01:00
Merge #19114: scripted-diff: TxoutType C++11 scoped enum class
fa32adf9dc
scripted-diff: TxoutType C++11 scoped enum class (MarcoFalke)fa95a694c4
doc: Update outdated txnouttype documentation (MarcoFalke)fa58469c77
rpc: Properly use underlying type in GetAllOutputTypes (MarcoFalke)fa41c65702
rpc: Simplify GetAllOutputTypes with the Join helper (MarcoFalke) Pull request description: Non-scoped enums can accidentally and silently decay into an integral type. Also, the symbol names of the keys are exported to the surrounding (usually global) namespace. Fix both issues by switching to an `enum class TxoutType` in a (mostly) scripted-diff. ACKs for top commit: practicalswift: ACKfa32adf9dc
-- patch looks correct hebasto: re-ACKfa32adf9dc
, since fa5997bd6fc82e16b597ea96e3c5c665f1f174ab (https://github.com/bitcoin/bitcoin/pull/19114#pullrequestreview-421425198) rebased only (verified with `git range-diff`). Tree-SHA512: f42a9db47f9be89fa4bdd8d2fb05a16726286d8b12e3d87327b67d723f91c7d5a57deb4b2ddae9e1d16fee7a5f8c00828b6dc8909c5db680fc5e0a3cf07cd465
This commit is contained in:
commit
d3a5dbfd1f
18 changed files with 211 additions and 212 deletions
|
@ -135,8 +135,8 @@ bool CBloomFilter::IsRelevantAndUpdate(const CTransaction& tx)
|
|||
else if ((nFlags & BLOOM_UPDATE_MASK) == BLOOM_UPDATE_P2PUBKEY_ONLY)
|
||||
{
|
||||
std::vector<std::vector<unsigned char> > vSolutions;
|
||||
txnouttype type = Solver(txout.scriptPubKey, vSolutions);
|
||||
if (type == TX_PUBKEY || type == TX_MULTISIG) {
|
||||
TxoutType type = Solver(txout.scriptPubKey, vSolutions);
|
||||
if (type == TxoutType::PUBKEY || type == TxoutType::MULTISIG) {
|
||||
insert(COutPoint(hash, i));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -140,11 +140,11 @@ void ScriptToUniv(const CScript& script, UniValue& out, bool include_address)
|
|||
out.pushKV("hex", HexStr(script));
|
||||
|
||||
std::vector<std::vector<unsigned char>> solns;
|
||||
txnouttype type = Solver(script, solns);
|
||||
TxoutType type = Solver(script, solns);
|
||||
out.pushKV("type", GetTxnOutputType(type));
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ void ScriptToUniv(const CScript& script, UniValue& out, bool include_address)
|
|||
void ScriptPubKeyToUniv(const CScript& scriptPubKey,
|
||||
UniValue& out, bool fIncludeHex)
|
||||
{
|
||||
txnouttype type;
|
||||
TxoutType type;
|
||||
std::vector<CTxDestination> addresses;
|
||||
int nRequired;
|
||||
|
||||
|
@ -160,7 +160,7 @@ void ScriptPubKeyToUniv(const CScript& scriptPubKey,
|
|||
if (fIncludeHex)
|
||||
out.pushKV("hex", HexStr(scriptPubKey));
|
||||
|
||||
if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired) || type == TX_PUBKEY) {
|
||||
if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired) || type == TxoutType::PUBKEY) {
|
||||
out.pushKV("type", GetTxnOutputType(type));
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -50,14 +50,14 @@ bool IsDust(const CTxOut& txout, const CFeeRate& 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;
|
||||
whichType = Solver(scriptPubKey, vSolutions);
|
||||
|
||||
if (whichType == TX_NONSTANDARD) {
|
||||
if (whichType == TxoutType::NONSTANDARD) {
|
||||
return false;
|
||||
} else if (whichType == TX_MULTISIG) {
|
||||
} else if (whichType == TxoutType::MULTISIG) {
|
||||
unsigned char m = vSolutions.front()[0];
|
||||
unsigned char n = vSolutions.back()[0];
|
||||
// Support up to x-of-3 multisig txns as standard
|
||||
|
@ -65,7 +65,7 @@ bool IsStandard(const CScript& scriptPubKey, txnouttype& whichType)
|
|||
return false;
|
||||
if (m < 1 || m > n)
|
||||
return false;
|
||||
} else if (whichType == TX_NULL_DATA &&
|
||||
} else if (whichType == TxoutType::NULL_DATA &&
|
||||
(!fAcceptDatacarrier || scriptPubKey.size() > nMaxDatacarrierBytes)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -110,16 +110,16 @@ bool IsStandardTx(const CTransaction& tx, bool permit_bare_multisig, const CFeeR
|
|||
}
|
||||
|
||||
unsigned int nDataOut = 0;
|
||||
txnouttype whichType;
|
||||
TxoutType whichType;
|
||||
for (const CTxOut& txout : tx.vout) {
|
||||
if (!::IsStandard(txout.scriptPubKey, whichType)) {
|
||||
reason = "scriptpubkey";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (whichType == TX_NULL_DATA)
|
||||
if (whichType == TxoutType::NULL_DATA)
|
||||
nDataOut++;
|
||||
else if ((whichType == TX_MULTISIG) && (!permit_bare_multisig)) {
|
||||
else if ((whichType == TxoutType::MULTISIG) && (!permit_bare_multisig)) {
|
||||
reason = "bare-multisig";
|
||||
return false;
|
||||
} 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;
|
||||
|
||||
std::vector<std::vector<unsigned char> > vSolutions;
|
||||
txnouttype whichType = Solver(prev.scriptPubKey, vSolutions);
|
||||
if (whichType == TX_NONSTANDARD) {
|
||||
TxoutType whichType = Solver(prev.scriptPubKey, vSolutions);
|
||||
if (whichType == TxoutType::NONSTANDARD) {
|
||||
return false;
|
||||
} else if (whichType == TX_SCRIPTHASH) {
|
||||
} else if (whichType == TxoutType::SCRIPTHASH) {
|
||||
std::vector<std::vector<unsigned char> > stack;
|
||||
// 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))
|
||||
|
|
|
@ -81,7 +81,7 @@ CAmount GetDustThreshold(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
|
||||
* @return True if all outputs (scriptPubKeys) use only standard transaction forms
|
||||
|
|
|
@ -511,12 +511,12 @@ static UniValue decoderawtransaction(const JSONRPCRequest& request)
|
|||
|
||||
static std::string GetAllOutputTypes()
|
||||
{
|
||||
std::string ret;
|
||||
for (int i = TX_NONSTANDARD; i <= TX_WITNESS_UNKNOWN; ++i) {
|
||||
if (i != TX_NONSTANDARD) ret += ", ";
|
||||
ret += GetTxnOutputType(static_cast<txnouttype>(i));
|
||||
std::vector<std::string> ret;
|
||||
using U = std::underlying_type<TxoutType>::type;
|
||||
for (U i = (U)TxoutType::NONSTANDARD; i <= (U)TxoutType::WITNESS_UNKNOWN; ++i) {
|
||||
ret.emplace_back(GetTxnOutputType(static_cast<TxoutType>(i)));
|
||||
}
|
||||
return ret;
|
||||
return Join(ret, ", ");
|
||||
}
|
||||
|
||||
static UniValue decodescript(const JSONRPCRequest& request)
|
||||
|
@ -580,10 +580,10 @@ static UniValue decodescript(const JSONRPCRequest& request)
|
|||
// 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") {
|
||||
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.
|
||||
// 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) {
|
||||
if ((solution.size() != 1) && !CPubKey(solution).IsCompressed()) {
|
||||
return r;
|
||||
|
@ -592,9 +592,9 @@ static UniValue decodescript(const JSONRPCRequest& request)
|
|||
}
|
||||
UniValue sr(UniValue::VOBJ);
|
||||
CScript segwitScr;
|
||||
if (which_type == TX_PUBKEY) {
|
||||
if (which_type == TxoutType::PUBKEY) {
|
||||
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]}));
|
||||
} else {
|
||||
// Scripts that are not fit for P2WPKH are encoded as P2WSH.
|
||||
|
|
|
@ -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::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());
|
||||
if (pubkey.IsValid()) {
|
||||
return MakeUnique<PKDescriptor>(InferPubkey(pubkey, ctx, provider));
|
||||
}
|
||||
}
|
||||
if (txntype == TX_PUBKEYHASH) {
|
||||
if (txntype == TxoutType::PUBKEYHASH) {
|
||||
uint160 hash(data[0]);
|
||||
CKeyID keyid(hash);
|
||||
CPubKey pubkey;
|
||||
|
@ -1001,7 +1001,7 @@ std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptCo
|
|||
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]);
|
||||
CKeyID keyid(hash);
|
||||
CPubKey pubkey;
|
||||
|
@ -1009,7 +1009,7 @@ std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptCo
|
|||
return MakeUnique<WPKHDescriptor>(InferPubkey(pubkey, ctx, provider));
|
||||
}
|
||||
}
|
||||
if (txntype == TX_MULTISIG) {
|
||||
if (txntype == TxoutType::MULTISIG) {
|
||||
std::vector<std::unique_ptr<PubkeyProvider>> providers;
|
||||
for (size_t i = 1; i + 1 < data.size(); ++i) {
|
||||
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));
|
||||
}
|
||||
if (txntype == TX_SCRIPTHASH && ctx == ParseScriptContext::TOP) {
|
||||
if (txntype == TxoutType::SCRIPTHASH && ctx == ParseScriptContext::TOP) {
|
||||
uint160 hash(data[0]);
|
||||
CScriptID scriptid(hash);
|
||||
CScript subscript;
|
||||
|
@ -1026,7 +1026,7 @@ std::unique_ptr<DescriptorImpl> InferScript(const CScript& script, ParseScriptCo
|
|||
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;
|
||||
CRIPEMD160().Write(data[0].data(), data[0].size()).Finalize(scriptid.begin());
|
||||
CScript subscript;
|
||||
|
|
|
@ -92,11 +92,11 @@ static bool CreateSig(const BaseSignatureCreator& creator, SignatureData& sigdat
|
|||
/**
|
||||
* Sign scriptPubKey using signature made with creator.
|
||||
* 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.
|
||||
*/
|
||||
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;
|
||||
uint160 h160;
|
||||
|
@ -108,15 +108,15 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator
|
|||
|
||||
switch (whichTypeRet)
|
||||
{
|
||||
case TX_NONSTANDARD:
|
||||
case TX_NULL_DATA:
|
||||
case TX_WITNESS_UNKNOWN:
|
||||
case TxoutType::NONSTANDARD:
|
||||
case TxoutType::NULL_DATA:
|
||||
case TxoutType::WITNESS_UNKNOWN:
|
||||
return false;
|
||||
case TX_PUBKEY:
|
||||
case TxoutType::PUBKEY:
|
||||
if (!CreateSig(creator, sigdata, provider, sig, CPubKey(vSolutions[0]), scriptPubKey, sigversion)) return false;
|
||||
ret.push_back(std::move(sig));
|
||||
return true;
|
||||
case TX_PUBKEYHASH: {
|
||||
case TxoutType::PUBKEYHASH: {
|
||||
CKeyID keyID = CKeyID(uint160(vSolutions[0]));
|
||||
CPubKey pubkey;
|
||||
if (!GetPubKey(provider, sigdata, keyID, pubkey)) {
|
||||
|
@ -129,7 +129,7 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator
|
|||
ret.push_back(ToByteVector(pubkey));
|
||||
return true;
|
||||
}
|
||||
case TX_SCRIPTHASH:
|
||||
case TxoutType::SCRIPTHASH:
|
||||
h160 = uint160(vSolutions[0]);
|
||||
if (GetCScript(provider, sigdata, CScriptID{h160}, scriptRet)) {
|
||||
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;
|
||||
return false;
|
||||
|
||||
case TX_MULTISIG: {
|
||||
case TxoutType::MULTISIG: {
|
||||
size_t required = vSolutions.front()[0];
|
||||
ret.push_back(valtype()); // workaround CHECKMULTISIG bug
|
||||
for (size_t i = 1; i < vSolutions.size() - 1; ++i) {
|
||||
|
@ -159,11 +159,11 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator
|
|||
}
|
||||
return ok;
|
||||
}
|
||||
case TX_WITNESS_V0_KEYHASH:
|
||||
case TxoutType::WITNESS_V0_KEYHASH:
|
||||
ret.push_back(vSolutions[0]);
|
||||
return true;
|
||||
|
||||
case TX_WITNESS_V0_SCRIPTHASH:
|
||||
case TxoutType::WITNESS_V0_SCRIPTHASH:
|
||||
CRIPEMD160().Write(&vSolutions[0][0], vSolutions[0].size()).Finalize(h160.begin());
|
||||
if (GetCScript(provider, sigdata, CScriptID{h160}, scriptRet)) {
|
||||
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;
|
||||
|
||||
std::vector<valtype> result;
|
||||
txnouttype whichType;
|
||||
TxoutType whichType;
|
||||
bool solved = SignStep(provider, creator, fromPubKey, result, whichType, SigVersion::BASE, sigdata);
|
||||
bool P2SH = false;
|
||||
CScript subscript;
|
||||
sigdata.scriptWitness.stack.clear();
|
||||
|
||||
if (solved && whichType == TX_SCRIPTHASH)
|
||||
if (solved && whichType == TxoutType::SCRIPTHASH)
|
||||
{
|
||||
// Solver returns the subscript that needs to be evaluated;
|
||||
// the final scriptSig is the signatures from that
|
||||
// and then the serialized subscript:
|
||||
subscript = CScript(result[0].begin(), result[0].end());
|
||||
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;
|
||||
}
|
||||
|
||||
if (solved && whichType == TX_WITNESS_V0_KEYHASH)
|
||||
if (solved && whichType == TxoutType::WITNESS_V0_KEYHASH)
|
||||
{
|
||||
CScript witnessscript;
|
||||
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);
|
||||
sigdata.scriptWitness.stack = result;
|
||||
sigdata.witness = true;
|
||||
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());
|
||||
sigdata.witness_script = witnessscript;
|
||||
txnouttype 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;
|
||||
TxoutType subType;
|
||||
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()));
|
||||
sigdata.scriptWitness.stack = result;
|
||||
sigdata.witness = true;
|
||||
result.clear();
|
||||
} else if (solved && whichType == TX_WITNESS_UNKNOWN) {
|
||||
} else if (solved && whichType == TxoutType::WITNESS_UNKNOWN) {
|
||||
sigdata.witness = true;
|
||||
}
|
||||
|
||||
|
@ -301,11 +301,11 @@ SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nI
|
|||
|
||||
// Get scripts
|
||||
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;
|
||||
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
|
||||
CScript redeem_script(stack.script.back().begin(), stack.script.back().end());
|
||||
data.redeem_script = redeem_script;
|
||||
|
@ -315,7 +315,7 @@ SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nI
|
|||
script_type = Solver(next_script, solutions);
|
||||
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
|
||||
CScript witness_script(stack.witness.back().begin(), stack.witness.back().end());
|
||||
data.witness_script = witness_script;
|
||||
|
@ -328,7 +328,7 @@ SignatureData DataFromTransaction(const CMutableTransaction& tx, unsigned int nI
|
|||
stack.witness.clear();
|
||||
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:
|
||||
assert(solutions.size() > 1);
|
||||
unsigned int num_pubkeys = solutions.size()-2;
|
||||
|
@ -454,13 +454,13 @@ bool IsSegWitOutput(const SigningProvider& provider, const CScript& script)
|
|||
{
|
||||
std::vector<valtype> 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 == TX_SCRIPTHASH) {
|
||||
if (whichtype == TxoutType::WITNESS_V0_SCRIPTHASH || whichtype == TxoutType::WITNESS_V0_KEYHASH || whichtype == TxoutType::WITNESS_UNKNOWN) return true;
|
||||
if (whichtype == TxoutType::SCRIPTHASH) {
|
||||
auto h160 = uint160(solutions[0]);
|
||||
CScript subscript;
|
||||
if (provider.GetCScript(CScriptID{h160}, subscript)) {
|
||||
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;
|
||||
|
|
|
@ -43,20 +43,20 @@ WitnessV0ScriptHash::WitnessV0ScriptHash(const CScript& in)
|
|||
CSHA256().Write(in.data(), in.size()).Finalize(begin());
|
||||
}
|
||||
|
||||
std::string GetTxnOutputType(txnouttype t)
|
||||
std::string GetTxnOutputType(TxoutType t)
|
||||
{
|
||||
switch (t)
|
||||
{
|
||||
case TX_NONSTANDARD: return "nonstandard";
|
||||
case TX_PUBKEY: return "pubkey";
|
||||
case TX_PUBKEYHASH: return "pubkeyhash";
|
||||
case TX_SCRIPTHASH: return "scripthash";
|
||||
case TX_MULTISIG: return "multisig";
|
||||
case TX_NULL_DATA: return "nulldata";
|
||||
case TX_WITNESS_V0_KEYHASH: return "witness_v0_keyhash";
|
||||
case TX_WITNESS_V0_SCRIPTHASH: return "witness_v0_scripthash";
|
||||
case TX_WITNESS_UNKNOWN: return "witness_unknown";
|
||||
}
|
||||
case TxoutType::NONSTANDARD: return "nonstandard";
|
||||
case TxoutType::PUBKEY: return "pubkey";
|
||||
case TxoutType::PUBKEYHASH: return "pubkeyhash";
|
||||
case TxoutType::SCRIPTHASH: return "scripthash";
|
||||
case TxoutType::MULTISIG: return "multisig";
|
||||
case TxoutType::NULL_DATA: return "nulldata";
|
||||
case TxoutType::WITNESS_V0_KEYHASH: return "witness_v0_keyhash";
|
||||
case TxoutType::WITNESS_V0_SCRIPTHASH: return "witness_v0_scripthash";
|
||||
case TxoutType::WITNESS_UNKNOWN: return "witness_unknown";
|
||||
} // no default case, so the compiler can warn about missing cases
|
||||
assert(false);
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ static bool MatchMultisig(const CScript& script, unsigned int& required, std::ve
|
|||
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();
|
||||
|
||||
|
@ -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);
|
||||
vSolutionsRet.push_back(hashBytes);
|
||||
return TX_SCRIPTHASH;
|
||||
return TxoutType::SCRIPTHASH;
|
||||
}
|
||||
|
||||
int witnessversion;
|
||||
|
@ -124,18 +124,18 @@ txnouttype Solver(const CScript& scriptPubKey, std::vector<std::vector<unsigned
|
|||
if (scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {
|
||||
if (witnessversion == 0 && witnessprogram.size() == WITNESS_V0_KEYHASH_SIZE) {
|
||||
vSolutionsRet.push_back(witnessprogram);
|
||||
return TX_WITNESS_V0_KEYHASH;
|
||||
return TxoutType::WITNESS_V0_KEYHASH;
|
||||
}
|
||||
if (witnessversion == 0 && witnessprogram.size() == WITNESS_V0_SCRIPTHASH_SIZE) {
|
||||
vSolutionsRet.push_back(witnessprogram);
|
||||
return TX_WITNESS_V0_SCRIPTHASH;
|
||||
return TxoutType::WITNESS_V0_SCRIPTHASH;
|
||||
}
|
||||
if (witnessversion != 0) {
|
||||
vSolutionsRet.push_back(std::vector<unsigned char>{(unsigned char)witnessversion});
|
||||
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
|
||||
|
@ -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
|
||||
// script.
|
||||
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;
|
||||
if (MatchPayToPubkey(scriptPubKey, data)) {
|
||||
vSolutionsRet.push_back(std::move(data));
|
||||
return TX_PUBKEY;
|
||||
return TxoutType::PUBKEY;
|
||||
}
|
||||
|
||||
if (MatchPayToPubkeyHash(scriptPubKey, data)) {
|
||||
vSolutionsRet.push_back(std::move(data));
|
||||
return TX_PUBKEYHASH;
|
||||
return TxoutType::PUBKEYHASH;
|
||||
}
|
||||
|
||||
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.insert(vSolutionsRet.end(), keys.begin(), keys.end());
|
||||
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();
|
||||
return TX_NONSTANDARD;
|
||||
return TxoutType::NONSTANDARD;
|
||||
}
|
||||
|
||||
bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
|
||||
{
|
||||
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]);
|
||||
if (!pubKey.IsValid())
|
||||
return false;
|
||||
|
@ -184,26 +184,26 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
|
|||
addressRet = PKHash(pubKey);
|
||||
return true;
|
||||
}
|
||||
else if (whichType == TX_PUBKEYHASH)
|
||||
else if (whichType == TxoutType::PUBKEYHASH)
|
||||
{
|
||||
addressRet = PKHash(uint160(vSolutions[0]));
|
||||
return true;
|
||||
}
|
||||
else if (whichType == TX_SCRIPTHASH)
|
||||
else if (whichType == TxoutType::SCRIPTHASH)
|
||||
{
|
||||
addressRet = ScriptHash(uint160(vSolutions[0]));
|
||||
return true;
|
||||
} else if (whichType == TX_WITNESS_V0_KEYHASH) {
|
||||
} else if (whichType == TxoutType::WITNESS_V0_KEYHASH) {
|
||||
WitnessV0KeyHash hash;
|
||||
std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin());
|
||||
addressRet = hash;
|
||||
return true;
|
||||
} else if (whichType == TX_WITNESS_V0_SCRIPTHASH) {
|
||||
} else if (whichType == TxoutType::WITNESS_V0_SCRIPTHASH) {
|
||||
WitnessV0ScriptHash hash;
|
||||
std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin());
|
||||
addressRet = hash;
|
||||
return true;
|
||||
} else if (whichType == TX_WITNESS_UNKNOWN) {
|
||||
} else if (whichType == TxoutType::WITNESS_UNKNOWN) {
|
||||
WitnessUnknown unk;
|
||||
unk.version = vSolutions[0][0];
|
||||
std::copy(vSolutions[1].begin(), vSolutions[1].end(), unk.program);
|
||||
|
@ -215,19 +215,19 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
|
|||
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();
|
||||
std::vector<valtype> vSolutions;
|
||||
typeRet = Solver(scriptPubKey, vSolutions);
|
||||
if (typeRet == TX_NONSTANDARD) {
|
||||
if (typeRet == TxoutType::NONSTANDARD) {
|
||||
return false;
|
||||
} else if (typeRet == TX_NULL_DATA) {
|
||||
} else if (typeRet == TxoutType::NULL_DATA) {
|
||||
// This is data, not addresses
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeRet == TX_MULTISIG)
|
||||
if (typeRet == TxoutType::MULTISIG)
|
||||
{
|
||||
nRequiredRet = vSolutions.front()[0];
|
||||
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)
|
||||
{
|
||||
std::vector<std::vector<unsigned char> > vSolutions;
|
||||
txnouttype typ = Solver(redeemscript, vSolutions);
|
||||
if (typ == TX_PUBKEY) {
|
||||
TxoutType typ = Solver(redeemscript, vSolutions);
|
||||
if (typ == TxoutType::PUBKEY) {
|
||||
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(WitnessV0ScriptHash(redeemscript));
|
||||
|
|
|
@ -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
|
||||
* type is designated as TX_NULL_DATA.
|
||||
* type is designated as TxoutType::NULL_DATA.
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
|
@ -116,18 +116,17 @@ extern unsigned nMaxDatacarrierBytes;
|
|||
*/
|
||||
static const unsigned int MANDATORY_SCRIPT_VERIFY_FLAGS = SCRIPT_VERIFY_P2SH;
|
||||
|
||||
enum txnouttype
|
||||
{
|
||||
TX_NONSTANDARD,
|
||||
enum class TxoutType {
|
||||
NONSTANDARD,
|
||||
// 'standard' transaction types:
|
||||
TX_PUBKEY,
|
||||
TX_PUBKEYHASH,
|
||||
TX_SCRIPTHASH,
|
||||
TX_MULTISIG,
|
||||
TX_NULL_DATA, //!< unspendable OP_RETURN script that carries data
|
||||
TX_WITNESS_V0_SCRIPTHASH,
|
||||
TX_WITNESS_V0_KEYHASH,
|
||||
TX_WITNESS_UNKNOWN, //!< Only for Witness versions not already defined above
|
||||
PUBKEY,
|
||||
PUBKEYHASH,
|
||||
SCRIPTHASH,
|
||||
MULTISIG,
|
||||
NULL_DATA, //!< unspendable OP_RETURN script that carries data
|
||||
WITNESS_V0_SCRIPTHASH,
|
||||
WITNESS_V0_KEYHASH,
|
||||
WITNESS_UNKNOWN, //!< Only for Witness versions not already defined above
|
||||
};
|
||||
|
||||
class CNoDestination {
|
||||
|
@ -200,11 +199,11 @@ struct WitnessUnknown
|
|||
/**
|
||||
* A txout script template with a specific destination. It is either:
|
||||
* * CNoDestination: no destination set
|
||||
* * PKHash: TX_PUBKEYHASH destination (P2PKH)
|
||||
* * ScriptHash: TX_SCRIPTHASH destination (P2SH)
|
||||
* * WitnessV0ScriptHash: TX_WITNESS_V0_SCRIPTHASH destination (P2WSH)
|
||||
* * WitnessV0KeyHash: TX_WITNESS_V0_KEYHASH destination (P2WPKH)
|
||||
* * WitnessUnknown: TX_WITNESS_UNKNOWN destination (P2W???)
|
||||
* * PKHash: TxoutType::PUBKEYHASH destination (P2PKH)
|
||||
* * ScriptHash: TxoutType::SCRIPTHASH destination (P2SH)
|
||||
* * WitnessV0ScriptHash: TxoutType::WITNESS_V0_SCRIPTHASH destination (P2WSH)
|
||||
* * WitnessV0KeyHash: TxoutType::WITNESS_V0_KEYHASH destination (P2WPKH)
|
||||
* * WitnessUnknown: TxoutType::WITNESS_UNKNOWN destination (P2W???)
|
||||
* A CTxDestination is the internal data type encoded in a bitcoin address
|
||||
*/
|
||||
typedef boost::variant<CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessUnknown> CTxDestination;
|
||||
|
@ -212,8 +211,8 @@ typedef boost::variant<CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash,
|
|||
/** Check whether a CTxDestination is a CNoDestination. */
|
||||
bool IsValidDestination(const CTxDestination& dest);
|
||||
|
||||
/** Get the name of a txnouttype as a C string, or nullptr if unknown. */
|
||||
std::string GetTxnOutputType(txnouttype t);
|
||||
/** Get the name of a TxoutType as a string */
|
||||
std::string GetTxnOutputType(TxoutType t);
|
||||
|
||||
/**
|
||||
* Parse a scriptPubKey and identify script type for standard scripts. If
|
||||
|
@ -223,9 +222,9 @@ std::string GetTxnOutputType(txnouttype t);
|
|||
*
|
||||
* @param[in] scriptPubKey Script to parse
|
||||
* @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
|
||||
|
@ -246,7 +245,7 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
|
|||
* encodable as an address) with key identifiers (of keys involved in a
|
||||
* 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
|
||||
|
|
|
@ -157,25 +157,25 @@ void test_one_input(const std::vector<uint8_t>& buffer)
|
|||
assert(ok_add_key_pubkey);
|
||||
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);
|
||||
assert(is_standard_tx_pubkey);
|
||||
assert(which_type_tx_pubkey == txnouttype::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);
|
||||
assert(is_standard_tx_multisig);
|
||||
assert(which_type_tx_multisig == txnouttype::TX_MULTISIG);
|
||||
assert(which_type_tx_multisig == TxoutType::MULTISIG);
|
||||
|
||||
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);
|
||||
assert(outtype_tx_pubkey == txnouttype::TX_PUBKEY);
|
||||
const TxoutType outtype_tx_pubkey = Solver(tx_pubkey_script, v_solutions_ret_tx_pubkey);
|
||||
assert(outtype_tx_pubkey == TxoutType::PUBKEY);
|
||||
assert(v_solutions_ret_tx_pubkey.size() == 1);
|
||||
assert(v_solutions_ret_tx_pubkey[0].size() == 33);
|
||||
|
||||
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);
|
||||
assert(outtype_tx_multisig == txnouttype::TX_MULTISIG);
|
||||
const TxoutType outtype_tx_multisig = Solver(tx_multisig_script, v_solutions_ret_tx_multisig);
|
||||
assert(outtype_tx_multisig == TxoutType::MULTISIG);
|
||||
assert(v_solutions_ret_tx_multisig.size() == 3);
|
||||
assert(v_solutions_ret_tx_multisig[0].size() == 1);
|
||||
assert(v_solutions_ret_tx_multisig[1].size() == 33);
|
||||
|
|
|
@ -58,7 +58,7 @@ void test_one_input(const std::vector<uint8_t>& buffer)
|
|||
CTxDestination address;
|
||||
(void)ExtractDestination(script, address);
|
||||
|
||||
txnouttype type_ret;
|
||||
TxoutType type_ret;
|
||||
std::vector<CTxDestination> addresses;
|
||||
int 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);
|
||||
|
||||
txnouttype which_type;
|
||||
TxoutType which_type;
|
||||
(void)IsStandard(script, which_type);
|
||||
|
||||
(void)RecursiveDynamicUsage(script);
|
||||
|
|
|
@ -141,7 +141,7 @@ BOOST_AUTO_TEST_CASE(multisig_IsStandard)
|
|||
for (int i = 0; i < 4; i++)
|
||||
key[i].MakeNewKey(true);
|
||||
|
||||
txnouttype whichType;
|
||||
TxoutType whichType;
|
||||
|
||||
CScript a_and_b;
|
||||
a_and_b << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
|
||||
|
|
|
@ -31,35 +31,35 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success)
|
|||
CScript s;
|
||||
std::vector<std::vector<unsigned char> > solutions;
|
||||
|
||||
// TX_PUBKEY
|
||||
// TxoutType::PUBKEY
|
||||
s.clear();
|
||||
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(solutions[0] == ToByteVector(pubkeys[0]));
|
||||
|
||||
// TX_PUBKEYHASH
|
||||
// TxoutType::PUBKEYHASH
|
||||
s.clear();
|
||||
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(solutions[0] == ToByteVector(pubkeys[0].GetID()));
|
||||
|
||||
// TX_SCRIPTHASH
|
||||
// TxoutType::SCRIPTHASH
|
||||
CScript redeemScript(s); // initialize with leftover P2PKH script
|
||||
s.clear();
|
||||
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(solutions[0] == ToByteVector(CScriptID(redeemScript)));
|
||||
|
||||
// TX_MULTISIG
|
||||
// TxoutType::MULTISIG
|
||||
s.clear();
|
||||
s << OP_1 <<
|
||||
ToByteVector(pubkeys[0]) <<
|
||||
ToByteVector(pubkeys[1]) <<
|
||||
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(solutions[0] == std::vector<unsigned char>({1}));
|
||||
BOOST_CHECK(solutions[1] == ToByteVector(pubkeys[0]));
|
||||
|
@ -72,7 +72,7 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_success)
|
|||
ToByteVector(pubkeys[1]) <<
|
||||
ToByteVector(pubkeys[2]) <<
|
||||
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(solutions[0] == std::vector<unsigned char>({2}));
|
||||
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[4] == std::vector<unsigned char>({3}));
|
||||
|
||||
// TX_NULL_DATA
|
||||
// TxoutType::NULL_DATA
|
||||
s.clear();
|
||||
s << OP_RETURN <<
|
||||
std::vector<unsigned char>({0}) <<
|
||||
std::vector<unsigned char>({75}) <<
|
||||
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);
|
||||
|
||||
// TX_WITNESS_V0_KEYHASH
|
||||
// TxoutType::WITNESS_V0_KEYHASH
|
||||
s.clear();
|
||||
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(solutions[0] == ToByteVector(pubkeys[0].GetID()));
|
||||
|
||||
// TX_WITNESS_V0_SCRIPTHASH
|
||||
// TxoutType::WITNESS_V0_SCRIPTHASH
|
||||
uint256 scriptHash;
|
||||
CSHA256().Write(&redeemScript[0], redeemScript.size())
|
||||
.Finalize(scriptHash.begin());
|
||||
|
||||
s.clear();
|
||||
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(solutions[0] == ToByteVector(scriptHash));
|
||||
|
||||
// TX_NONSTANDARD
|
||||
// TxoutType::NONSTANDARD
|
||||
s.clear();
|
||||
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)
|
||||
|
@ -123,50 +123,50 @@ BOOST_AUTO_TEST_CASE(script_standard_Solver_failure)
|
|||
CScript s;
|
||||
std::vector<std::vector<unsigned char> > solutions;
|
||||
|
||||
// TX_PUBKEY with incorrectly sized pubkey
|
||||
// TxoutType::PUBKEY with incorrectly sized pubkey
|
||||
s.clear();
|
||||
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 << 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 << 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 << 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 << 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 << 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 << 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 << 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 with incorrect program size
|
||||
// TxoutType::WITNESS_UNKNOWN with incorrect program size
|
||||
s.clear();
|
||||
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)
|
||||
|
@ -179,21 +179,21 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestination)
|
|||
CScript s;
|
||||
CTxDestination address;
|
||||
|
||||
// TX_PUBKEY
|
||||
// TxoutType::PUBKEY
|
||||
s.clear();
|
||||
s << ToByteVector(pubkey) << OP_CHECKSIG;
|
||||
BOOST_CHECK(ExtractDestination(s, address));
|
||||
BOOST_CHECK(boost::get<PKHash>(&address) &&
|
||||
*boost::get<PKHash>(&address) == PKHash(pubkey));
|
||||
|
||||
// TX_PUBKEYHASH
|
||||
// TxoutType::PUBKEYHASH
|
||||
s.clear();
|
||||
s << OP_DUP << OP_HASH160 << ToByteVector(pubkey.GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
|
||||
BOOST_CHECK(ExtractDestination(s, address));
|
||||
BOOST_CHECK(boost::get<PKHash>(&address) &&
|
||||
*boost::get<PKHash>(&address) == PKHash(pubkey));
|
||||
|
||||
// TX_SCRIPTHASH
|
||||
// TxoutType::SCRIPTHASH
|
||||
CScript redeemScript(s); // initialize with leftover P2PKH script
|
||||
s.clear();
|
||||
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::get<ScriptHash>(&address) == ScriptHash(redeemScript));
|
||||
|
||||
// TX_MULTISIG
|
||||
// TxoutType::MULTISIG
|
||||
s.clear();
|
||||
s << OP_1 << ToByteVector(pubkey) << OP_1 << OP_CHECKMULTISIG;
|
||||
BOOST_CHECK(!ExtractDestination(s, address));
|
||||
|
||||
// TX_NULL_DATA
|
||||
// TxoutType::NULL_DATA
|
||||
s.clear();
|
||||
s << OP_RETURN << std::vector<unsigned char>({75});
|
||||
BOOST_CHECK(!ExtractDestination(s, address));
|
||||
|
||||
// TX_WITNESS_V0_KEYHASH
|
||||
// TxoutType::WITNESS_V0_KEYHASH
|
||||
s.clear();
|
||||
s << OP_0 << ToByteVector(pubkey.GetID());
|
||||
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());
|
||||
BOOST_CHECK(boost::get<WitnessV0KeyHash>(&address) && *boost::get<WitnessV0KeyHash>(&address) == keyhash);
|
||||
|
||||
// TX_WITNESS_V0_SCRIPTHASH
|
||||
// TxoutType::WITNESS_V0_SCRIPTHASH
|
||||
s.clear();
|
||||
WitnessV0ScriptHash scripthash;
|
||||
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(boost::get<WitnessV0ScriptHash>(&address) && *boost::get<WitnessV0ScriptHash>(&address) == scripthash);
|
||||
|
||||
// TX_WITNESS with unknown version
|
||||
// TxoutType::WITNESS_UNKNOWN with unknown version
|
||||
s.clear();
|
||||
s << OP_1 << ToByteVector(pubkey);
|
||||
BOOST_CHECK(ExtractDestination(s, address));
|
||||
|
@ -248,49 +248,49 @@ BOOST_AUTO_TEST_CASE(script_standard_ExtractDestinations)
|
|||
}
|
||||
|
||||
CScript s;
|
||||
txnouttype whichType;
|
||||
TxoutType whichType;
|
||||
std::vector<CTxDestination> addresses;
|
||||
int nRequired;
|
||||
|
||||
// TX_PUBKEY
|
||||
// TxoutType::PUBKEY
|
||||
s.clear();
|
||||
s << ToByteVector(pubkeys[0]) << OP_CHECKSIG;
|
||||
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(nRequired, 1);
|
||||
BOOST_CHECK(boost::get<PKHash>(&addresses[0]) &&
|
||||
*boost::get<PKHash>(&addresses[0]) == PKHash(pubkeys[0]));
|
||||
|
||||
// TX_PUBKEYHASH
|
||||
// TxoutType::PUBKEYHASH
|
||||
s.clear();
|
||||
s << OP_DUP << OP_HASH160 << ToByteVector(pubkeys[0].GetID()) << OP_EQUALVERIFY << OP_CHECKSIG;
|
||||
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(nRequired, 1);
|
||||
BOOST_CHECK(boost::get<PKHash>(&addresses[0]) &&
|
||||
*boost::get<PKHash>(&addresses[0]) == PKHash(pubkeys[0]));
|
||||
|
||||
// TX_SCRIPTHASH
|
||||
// TxoutType::SCRIPTHASH
|
||||
CScript redeemScript(s); // initialize with leftover P2PKH script
|
||||
s.clear();
|
||||
s << OP_HASH160 << ToByteVector(CScriptID(redeemScript)) << OP_EQUAL;
|
||||
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(nRequired, 1);
|
||||
BOOST_CHECK(boost::get<ScriptHash>(&addresses[0]) &&
|
||||
*boost::get<ScriptHash>(&addresses[0]) == ScriptHash(redeemScript));
|
||||
|
||||
// TX_MULTISIG
|
||||
// TxoutType::MULTISIG
|
||||
s.clear();
|
||||
s << OP_2 <<
|
||||
ToByteVector(pubkeys[0]) <<
|
||||
ToByteVector(pubkeys[1]) <<
|
||||
OP_2 << OP_CHECKMULTISIG;
|
||||
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(nRequired, 2);
|
||||
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::get<PKHash>(&addresses[1]) == PKHash(pubkeys[1]));
|
||||
|
||||
// TX_NULL_DATA
|
||||
// TxoutType::NULL_DATA
|
||||
s.clear();
|
||||
s << OP_RETURN << std::vector<unsigned char>({75});
|
||||
BOOST_CHECK(!ExtractDestinations(s, whichType, addresses, nRequired));
|
||||
|
|
|
@ -716,12 +716,12 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
|
|||
BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
|
||||
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");
|
||||
BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY, t.vout[0].scriptPubKey.size());
|
||||
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");
|
||||
BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY + 1, t.vout[0].scriptPubKey.size());
|
||||
reason.clear();
|
||||
|
@ -745,12 +745,12 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
|
|||
BOOST_CHECK(!IsStandardTx(CTransaction(t), reason));
|
||||
BOOST_CHECK_EQUAL(reason, "scriptpubkey");
|
||||
|
||||
// TX_NULL_DATA w/o PUSHDATA
|
||||
// TxoutType::NULL_DATA w/o PUSHDATA
|
||||
t.vout.resize(1);
|
||||
t.vout[0].scriptPubKey = CScript() << OP_RETURN;
|
||||
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[0].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38");
|
||||
t.vout[1].scriptPubKey = CScript() << OP_RETURN << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38");
|
||||
|
|
|
@ -22,8 +22,8 @@ CMutableTransaction BuildCreditingTransaction(const CScript& scriptPubKey, int n
|
|||
CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CScriptWitness& scriptWitness, const CTransaction& txCredit);
|
||||
|
||||
// Helper: create two dummy transactions, each with two outputs.
|
||||
// The first has nValues[0] and nValues[1] outputs paid to a TX_PUBKEY,
|
||||
// the second nValues[2] and nValues[3] outputs paid to a TX_PUBKEYHASH.
|
||||
// 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 TxoutType::PUBKEYHASH.
|
||||
std::vector<CMutableTransaction> SetupDummyInputs(FillableSigningProvider& keystoreRet, CCoinsViewCache& coinsRet, const std::array<CAmount,4>& nValues);
|
||||
|
||||
#endif // BITCOIN_TEST_UTIL_TRANSACTION_UTILS_H
|
||||
|
|
|
@ -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:
|
||||
std::vector<std::vector<unsigned char>> solverdata;
|
||||
txnouttype script_type = Solver(script, solverdata);
|
||||
TxoutType script_type = Solver(script, solverdata);
|
||||
|
||||
switch (script_type) {
|
||||
case TX_PUBKEY: {
|
||||
case TxoutType::PUBKEY: {
|
||||
CPubKey pubkey(solverdata[0].begin(), solverdata[0].end());
|
||||
import_data.used_keys.emplace(pubkey.GetID(), false);
|
||||
return "";
|
||||
}
|
||||
case TX_PUBKEYHASH: {
|
||||
case TxoutType::PUBKEYHASH: {
|
||||
CKeyID id = CKeyID(uint160(solverdata[0]));
|
||||
import_data.used_keys[id] = true;
|
||||
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::WITNESS_V0) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Trying to nest P2SH inside a P2WSH");
|
||||
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);
|
||||
return RecurseImportData(*subscript, import_data, ScriptContext::P2SH);
|
||||
}
|
||||
case TX_MULTISIG: {
|
||||
case TxoutType::MULTISIG: {
|
||||
for (size_t i = 1; i + 1< solverdata.size(); ++i) {
|
||||
CPubKey pubkey(solverdata[i].begin(), solverdata[i].end());
|
||||
import_data.used_keys.emplace(pubkey.GetID(), false);
|
||||
}
|
||||
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");
|
||||
uint256 fullid(solverdata[0]);
|
||||
CScriptID id;
|
||||
|
@ -901,7 +901,7 @@ static std::string RecurseImportData(const CScript& script, ImportData& import_d
|
|||
import_data.import_scripts.emplace(*subscript);
|
||||
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");
|
||||
CKeyID id = CKeyID(uint160(solverdata[0]));
|
||||
import_data.used_keys[id] = true;
|
||||
|
@ -910,10 +910,10 @@ static std::string RecurseImportData(const CScript& script, ImportData& import_d
|
|||
}
|
||||
return "";
|
||||
}
|
||||
case TX_NULL_DATA:
|
||||
case TxoutType::NULL_DATA:
|
||||
return "unspendable script";
|
||||
case TX_NONSTANDARD:
|
||||
case TX_WITNESS_UNKNOWN:
|
||||
case TxoutType::NONSTANDARD:
|
||||
case TxoutType::WITNESS_UNKNOWN:
|
||||
default:
|
||||
return "unrecognized script";
|
||||
}
|
||||
|
|
|
@ -3503,7 +3503,7 @@ public:
|
|||
{
|
||||
// Always present: script type and redeemscript
|
||||
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("hex", HexStr(subscript));
|
||||
|
||||
|
@ -3520,7 +3520,7 @@ public:
|
|||
// Always report the pubkey at the top level, so that `getnewaddress()['pubkey']` always works.
|
||||
if (subobj.exists("pubkey")) obj.pushKV("pubkey", subobj["pubkey"]);
|
||||
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).
|
||||
// TODO: abstract out the common functionality between this logic and ExtractDestinations.
|
||||
obj.pushKV("sigsrequired", solutions_data[0][0]);
|
||||
|
|
|
@ -88,16 +88,16 @@ IsMineResult IsMineInner(const LegacyScriptPubKeyMan& keystore, const CScript& s
|
|||
IsMineResult ret = IsMineResult::NO;
|
||||
|
||||
std::vector<valtype> vSolutions;
|
||||
txnouttype whichType = Solver(scriptPubKey, vSolutions);
|
||||
TxoutType whichType = Solver(scriptPubKey, vSolutions);
|
||||
|
||||
CKeyID keyID;
|
||||
switch (whichType)
|
||||
{
|
||||
case TX_NONSTANDARD:
|
||||
case TX_NULL_DATA:
|
||||
case TX_WITNESS_UNKNOWN:
|
||||
case TxoutType::NONSTANDARD:
|
||||
case TxoutType::NULL_DATA:
|
||||
case TxoutType::WITNESS_UNKNOWN:
|
||||
break;
|
||||
case TX_PUBKEY:
|
||||
case TxoutType::PUBKEY:
|
||||
keyID = CPubKey(vSolutions[0]).GetID();
|
||||
if (!PermitsUncompressed(sigversion) && vSolutions[0].size() != 33) {
|
||||
return IsMineResult::INVALID;
|
||||
|
@ -106,7 +106,7 @@ IsMineResult IsMineInner(const LegacyScriptPubKeyMan& keystore, const CScript& s
|
|||
ret = std::max(ret, IsMineResult::SPENDABLE);
|
||||
}
|
||||
break;
|
||||
case TX_WITNESS_V0_KEYHASH:
|
||||
case TxoutType::WITNESS_V0_KEYHASH:
|
||||
{
|
||||
if (sigversion == IsMineSigVersion::WITNESS_V0) {
|
||||
// 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));
|
||||
break;
|
||||
}
|
||||
case TX_PUBKEYHASH:
|
||||
case TxoutType::PUBKEYHASH:
|
||||
keyID = CKeyID(uint160(vSolutions[0]));
|
||||
if (!PermitsUncompressed(sigversion)) {
|
||||
CPubKey pubkey;
|
||||
|
@ -133,7 +133,7 @@ IsMineResult IsMineInner(const LegacyScriptPubKeyMan& keystore, const CScript& s
|
|||
ret = std::max(ret, IsMineResult::SPENDABLE);
|
||||
}
|
||||
break;
|
||||
case TX_SCRIPTHASH:
|
||||
case TxoutType::SCRIPTHASH:
|
||||
{
|
||||
if (sigversion != IsMineSigVersion::TOP) {
|
||||
// P2SH inside P2WSH or P2SH is invalid.
|
||||
|
@ -146,7 +146,7 @@ IsMineResult IsMineInner(const LegacyScriptPubKeyMan& keystore, const CScript& s
|
|||
}
|
||||
break;
|
||||
}
|
||||
case TX_WITNESS_V0_SCRIPTHASH:
|
||||
case TxoutType::WITNESS_V0_SCRIPTHASH:
|
||||
{
|
||||
if (sigversion == IsMineSigVersion::WITNESS_V0) {
|
||||
// P2WSH inside P2WSH is invalid.
|
||||
|
@ -165,7 +165,7 @@ IsMineResult IsMineInner(const LegacyScriptPubKeyMan& keystore, const CScript& s
|
|||
break;
|
||||
}
|
||||
|
||||
case TX_MULTISIG:
|
||||
case TxoutType::MULTISIG:
|
||||
{
|
||||
// Never treat bare multisig outputs as ours (they can still be made watchonly-though)
|
||||
if (sigversion == IsMineSigVersion::TOP) {
|
||||
|
@ -836,7 +836,7 @@ bool LegacyScriptPubKeyMan::HaveWatchOnly() const
|
|||
static bool ExtractPubKey(const CScript &dest, CPubKey& pubKeyOut)
|
||||
{
|
||||
std::vector<std::vector<unsigned char>> solutions;
|
||||
return Solver(dest, solutions) == TX_PUBKEY &&
|
||||
return Solver(dest, solutions) == TxoutType::PUBKEY &&
|
||||
(pubKeyOut = CPubKey(solutions[0])).IsFullyValid();
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue