forked from bitcoin/bitcoin
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge bitcoin#28244: Break up script/standard.{h/cpp}
91d924e Rename script/standard.{cpp/h} to script/solver.{cpp/h} (Andrew Chow) bacdb2e Clean up script/standard.{h/cpp} includes (Andrew Chow) f3c9078 Clean up things that include script/standard.h (Andrew Chow) 8bbe257 MOVEONLY: Move datacarrier defaults to policy.h (Andrew Chow) 7a172c7 Move CTxDestination to its own file (Andrew Chow) 145f36e Move Taproot{SpendData/Builder} to signingprovider.{h/cpp} (Andrew Chow) 86ea8be Move CScriptID to script.{h/cpp} (Andrew Chow) b81ebff Remove ScriptHash from CScriptID constructor (Andrew Chow) cba69dd Move MANDATORY_SCRIPT_VERIFY_FLAGS from script/standard.h to policy/policy.h (Anthony Towns) Pull request description: Some future work needs to touch things in script/standard.{h/cpp}, however it is unclear if it is safe to do so as they are included in several different places that could effect standardness and consensus. It contains a mix of policy parameters, consensus parameters, and utilities only used by the wallet. This PR breaks up the various components and renames the files to clearly separate everything. * `CTxDestination` is moved to a new file `src/addresstype.{cpp/h}` * `TaprootSpendData` and `TaprootBuilder` (and their utility functions and structs) are moved to `SigningProvider` as these are used only during signing. * `CScriptID` is moved to `script/script.h` to be next to `CScript`. * `MANDATORY_SCRIPT_VERIFY_FLAGS` is moved to `interpreter.h` * The parameters `DEFAULT_ACCEPT_DATACARRIER` and `MAX_OP_RETURN_RELAY` are moved to `policy.h` * `standard.{cpp/h}` is renamed to `solver.{cpp/h}` since that's all that's left in the file after the above moves ACKs for top commit: Sjors: ACK 91d924e ajtowns: ACK 91d924e MarcoFalke: ACK 91d924e 😇 murchandamus: ACK 91d924e darosior: Code review ACK 91d924e. theStack: Code-review ACK 91d924e Tree-SHA512: d347439890c652081f6a303d99b2bde6c371c96e7f4127c5db469764a17d39981f19884679ba883e28b733fde6142351dd8288c7bc61c379b7eefe7fa7acca1a
- Loading branch information
Showing
83 changed files
with
1,096 additions
and
1,053 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
// Copyright (c) 2023 The Bitcoin Core developers | ||
// Distributed under the MIT software license, see the accompanying | ||
// file COPYING or https://www.opensource.org/licenses/mit-license.php. | ||
|
||
#include <addresstype.h> | ||
#include <script/script.h> | ||
#include <script/solver.h> | ||
#include <hash.h> | ||
#include <pubkey.h> | ||
#include <uint256.h> | ||
#include <util/hash_type.h> | ||
|
||
#include <vector> | ||
|
||
typedef std::vector<unsigned char> valtype; | ||
|
||
ScriptHash::ScriptHash(const CScript& in) : BaseHash(Hash160(in)) {} | ||
ScriptHash::ScriptHash(const CScriptID& in) : BaseHash(static_cast<uint160>(in)) {} | ||
|
||
PKHash::PKHash(const CPubKey& pubkey) : BaseHash(pubkey.GetID()) {} | ||
PKHash::PKHash(const CKeyID& pubkey_id) : BaseHash(pubkey_id) {} | ||
|
||
WitnessV0KeyHash::WitnessV0KeyHash(const CPubKey& pubkey) : BaseHash(pubkey.GetID()) {} | ||
WitnessV0KeyHash::WitnessV0KeyHash(const PKHash& pubkey_hash) : BaseHash(static_cast<uint160>(pubkey_hash)) {} | ||
|
||
CKeyID ToKeyID(const PKHash& key_hash) | ||
{ | ||
return CKeyID{static_cast<uint160>(key_hash)}; | ||
} | ||
|
||
CKeyID ToKeyID(const WitnessV0KeyHash& key_hash) | ||
{ | ||
return CKeyID{static_cast<uint160>(key_hash)}; | ||
} | ||
|
||
CScriptID ToScriptID(const ScriptHash& script_hash) | ||
{ | ||
return CScriptID{static_cast<uint160>(script_hash)}; | ||
} | ||
|
||
WitnessV0ScriptHash::WitnessV0ScriptHash(const CScript& in) | ||
{ | ||
CSHA256().Write(in.data(), in.size()).Finalize(begin()); | ||
} | ||
|
||
bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet) | ||
{ | ||
std::vector<valtype> vSolutions; | ||
TxoutType whichType = Solver(scriptPubKey, vSolutions); | ||
|
||
switch (whichType) { | ||
case TxoutType::PUBKEY: { | ||
CPubKey pubKey(vSolutions[0]); | ||
if (!pubKey.IsValid()) | ||
return false; | ||
|
||
addressRet = PKHash(pubKey); | ||
return true; | ||
} | ||
case TxoutType::PUBKEYHASH: { | ||
addressRet = PKHash(uint160(vSolutions[0])); | ||
return true; | ||
} | ||
case TxoutType::SCRIPTHASH: { | ||
addressRet = ScriptHash(uint160(vSolutions[0])); | ||
return true; | ||
} | ||
case TxoutType::WITNESS_V0_KEYHASH: { | ||
WitnessV0KeyHash hash; | ||
std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin()); | ||
addressRet = hash; | ||
return true; | ||
} | ||
case TxoutType::WITNESS_V0_SCRIPTHASH: { | ||
WitnessV0ScriptHash hash; | ||
std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin()); | ||
addressRet = hash; | ||
return true; | ||
} | ||
case TxoutType::WITNESS_V1_TAPROOT: { | ||
WitnessV1Taproot tap; | ||
std::copy(vSolutions[0].begin(), vSolutions[0].end(), tap.begin()); | ||
addressRet = tap; | ||
return true; | ||
} | ||
case TxoutType::WITNESS_UNKNOWN: { | ||
WitnessUnknown unk; | ||
unk.version = vSolutions[0][0]; | ||
std::copy(vSolutions[1].begin(), vSolutions[1].end(), unk.program); | ||
unk.length = vSolutions[1].size(); | ||
addressRet = unk; | ||
return true; | ||
} | ||
case TxoutType::MULTISIG: | ||
case TxoutType::NULL_DATA: | ||
case TxoutType::NONSTANDARD: | ||
return false; | ||
} // no default case, so the compiler can warn about missing cases | ||
assert(false); | ||
} | ||
|
||
namespace { | ||
class CScriptVisitor | ||
{ | ||
public: | ||
CScript operator()(const CNoDestination& dest) const | ||
{ | ||
return CScript(); | ||
} | ||
|
||
CScript operator()(const PKHash& keyID) const | ||
{ | ||
return CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG; | ||
} | ||
|
||
CScript operator()(const ScriptHash& scriptID) const | ||
{ | ||
return CScript() << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL; | ||
} | ||
|
||
CScript operator()(const WitnessV0KeyHash& id) const | ||
{ | ||
return CScript() << OP_0 << ToByteVector(id); | ||
} | ||
|
||
CScript operator()(const WitnessV0ScriptHash& id) const | ||
{ | ||
return CScript() << OP_0 << ToByteVector(id); | ||
} | ||
|
||
CScript operator()(const WitnessV1Taproot& tap) const | ||
{ | ||
return CScript() << OP_1 << ToByteVector(tap); | ||
} | ||
|
||
CScript operator()(const WitnessUnknown& id) const | ||
{ | ||
return CScript() << CScript::EncodeOP_N(id.version) << std::vector<unsigned char>(id.program, id.program + id.length); | ||
} | ||
}; | ||
} // namespace | ||
|
||
CScript GetScriptForDestination(const CTxDestination& dest) | ||
{ | ||
return std::visit(CScriptVisitor(), dest); | ||
} | ||
|
||
bool IsValidDestination(const CTxDestination& dest) { | ||
return dest.index() != 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
// Copyright (c) 2023 The Bitcoin Core developers | ||
// Distributed under the MIT software license, see the accompanying | ||
// file COPYING or https://www.opensource.org/licenses/mit-license.php. | ||
|
||
#ifndef BITCOIN_ADDRESSTYPE_H | ||
#define BITCOIN_ADDRESSTYPE_H | ||
|
||
#include <pubkey.h> | ||
#include <script/script.h> | ||
#include <uint256.h> | ||
#include <util/hash_type.h> | ||
|
||
#include <variant> | ||
#include <algorithm> | ||
|
||
class CNoDestination { | ||
public: | ||
friend bool operator==(const CNoDestination &a, const CNoDestination &b) { return true; } | ||
friend bool operator<(const CNoDestination &a, const CNoDestination &b) { return true; } | ||
}; | ||
|
||
struct PKHash : public BaseHash<uint160> | ||
{ | ||
PKHash() : BaseHash() {} | ||
explicit PKHash(const uint160& hash) : BaseHash(hash) {} | ||
explicit PKHash(const CPubKey& pubkey); | ||
explicit PKHash(const CKeyID& pubkey_id); | ||
}; | ||
CKeyID ToKeyID(const PKHash& key_hash); | ||
|
||
struct WitnessV0KeyHash; | ||
|
||
struct ScriptHash : public BaseHash<uint160> | ||
{ | ||
ScriptHash() : BaseHash() {} | ||
// These don't do what you'd expect. | ||
// Use ScriptHash(GetScriptForDestination(...)) instead. | ||
explicit ScriptHash(const WitnessV0KeyHash& hash) = delete; | ||
explicit ScriptHash(const PKHash& hash) = delete; | ||
|
||
explicit ScriptHash(const uint160& hash) : BaseHash(hash) {} | ||
explicit ScriptHash(const CScript& script); | ||
explicit ScriptHash(const CScriptID& script); | ||
}; | ||
CScriptID ToScriptID(const ScriptHash& script_hash); | ||
|
||
struct WitnessV0ScriptHash : public BaseHash<uint256> | ||
{ | ||
WitnessV0ScriptHash() : BaseHash() {} | ||
explicit WitnessV0ScriptHash(const uint256& hash) : BaseHash(hash) {} | ||
explicit WitnessV0ScriptHash(const CScript& script); | ||
}; | ||
|
||
struct WitnessV0KeyHash : public BaseHash<uint160> | ||
{ | ||
WitnessV0KeyHash() : BaseHash() {} | ||
explicit WitnessV0KeyHash(const uint160& hash) : BaseHash(hash) {} | ||
explicit WitnessV0KeyHash(const CPubKey& pubkey); | ||
explicit WitnessV0KeyHash(const PKHash& pubkey_hash); | ||
}; | ||
CKeyID ToKeyID(const WitnessV0KeyHash& key_hash); | ||
|
||
struct WitnessV1Taproot : public XOnlyPubKey | ||
{ | ||
WitnessV1Taproot() : XOnlyPubKey() {} | ||
explicit WitnessV1Taproot(const XOnlyPubKey& xpk) : XOnlyPubKey(xpk) {} | ||
}; | ||
|
||
//! CTxDestination subtype to encode any future Witness version | ||
struct WitnessUnknown | ||
{ | ||
unsigned int version; | ||
unsigned int length; | ||
unsigned char program[40]; | ||
|
||
friend bool operator==(const WitnessUnknown& w1, const WitnessUnknown& w2) { | ||
if (w1.version != w2.version) return false; | ||
if (w1.length != w2.length) return false; | ||
return std::equal(w1.program, w1.program + w1.length, w2.program); | ||
} | ||
|
||
friend bool operator<(const WitnessUnknown& w1, const WitnessUnknown& w2) { | ||
if (w1.version < w2.version) return true; | ||
if (w1.version > w2.version) return false; | ||
if (w1.length < w2.length) return true; | ||
if (w1.length > w2.length) return false; | ||
return std::lexicographical_compare(w1.program, w1.program + w1.length, w2.program, w2.program + w2.length); | ||
} | ||
}; | ||
|
||
/** | ||
* A txout script template with a specific destination. It is either: | ||
* * CNoDestination: no destination set | ||
* * PKHash: TxoutType::PUBKEYHASH destination (P2PKH) | ||
* * ScriptHash: TxoutType::SCRIPTHASH destination (P2SH) | ||
* * WitnessV0ScriptHash: TxoutType::WITNESS_V0_SCRIPTHASH destination (P2WSH) | ||
* * WitnessV0KeyHash: TxoutType::WITNESS_V0_KEYHASH destination (P2WPKH) | ||
* * WitnessV1Taproot: TxoutType::WITNESS_V1_TAPROOT destination (P2TR) | ||
* * WitnessUnknown: TxoutType::WITNESS_UNKNOWN destination (P2W???) | ||
* A CTxDestination is the internal data type encoded in a bitcoin address | ||
*/ | ||
using CTxDestination = std::variant<CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown>; | ||
|
||
/** Check whether a CTxDestination is a CNoDestination. */ | ||
bool IsValidDestination(const CTxDestination& dest); | ||
|
||
/** | ||
* Parse a standard scriptPubKey for the destination address. Assigns result to | ||
* the addressRet parameter and returns true if successful. Currently only works for P2PK, | ||
* P2PKH, P2SH, P2WPKH, and P2WSH scripts. | ||
*/ | ||
bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet); | ||
|
||
/** | ||
* Generate a Bitcoin scriptPubKey for the given CTxDestination. Returns a P2PKH | ||
* script for a CKeyID destination, a P2SH script for a CScriptID, and an empty | ||
* script for CNoDestination. | ||
*/ | ||
CScript GetScriptForDestination(const CTxDestination& dest); | ||
|
||
#endif // BITCOIN_ADDRESSTYPE_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.