Skip to content

Commit 7ef2d4e

Browse files
committed
Merge bitcoin/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
2 parents d78ff38 + 91d924e commit 7ef2d4e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+1096
-1053
lines changed

src/Makefile.am

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ endif
117117
.PHONY: FORCE check-symbols check-security
118118
# bitcoin core #
119119
BITCOIN_CORE_H = \
120+
addresstype.h \
120121
addrdb.h \
121122
addrman.h \
122123
addrman_impl.h \
@@ -265,7 +266,7 @@ BITCOIN_CORE_H = \
265266
script/sigcache.h \
266267
script/sign.h \
267268
script/signingprovider.h \
268-
script/standard.h \
269+
script/solver.h \
269270
shutdown.h \
270271
signet.h \
271272
streams.h \
@@ -659,6 +660,7 @@ libbitcoin_consensus_a_SOURCES = \
659660
libbitcoin_common_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BOOST_CPPFLAGS)
660661
libbitcoin_common_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
661662
libbitcoin_common_a_SOURCES = \
663+
addresstype.cpp \
662664
base58.cpp \
663665
bech32.cpp \
664666
chainparams.cpp \
@@ -699,7 +701,7 @@ libbitcoin_common_a_SOURCES = \
699701
script/miniscript.cpp \
700702
script/sign.cpp \
701703
script/signingprovider.cpp \
702-
script/standard.cpp \
704+
script/solver.cpp \
703705
warnings.cpp \
704706
$(BITCOIN_CORE_H)
705707

@@ -960,7 +962,7 @@ libbitcoinkernel_la_SOURCES = \
960962
script/script.cpp \
961963
script/script_error.cpp \
962964
script/sigcache.cpp \
963-
script/standard.cpp \
965+
script/solver.cpp \
964966
signet.cpp \
965967
streams.cpp \
966968
support/cleanse.cpp \

src/addresstype.cpp

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
// Copyright (c) 2023 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or https://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <addresstype.h>
6+
#include <script/script.h>
7+
#include <script/solver.h>
8+
#include <hash.h>
9+
#include <pubkey.h>
10+
#include <uint256.h>
11+
#include <util/hash_type.h>
12+
13+
#include <vector>
14+
15+
typedef std::vector<unsigned char> valtype;
16+
17+
ScriptHash::ScriptHash(const CScript& in) : BaseHash(Hash160(in)) {}
18+
ScriptHash::ScriptHash(const CScriptID& in) : BaseHash(static_cast<uint160>(in)) {}
19+
20+
PKHash::PKHash(const CPubKey& pubkey) : BaseHash(pubkey.GetID()) {}
21+
PKHash::PKHash(const CKeyID& pubkey_id) : BaseHash(pubkey_id) {}
22+
23+
WitnessV0KeyHash::WitnessV0KeyHash(const CPubKey& pubkey) : BaseHash(pubkey.GetID()) {}
24+
WitnessV0KeyHash::WitnessV0KeyHash(const PKHash& pubkey_hash) : BaseHash(static_cast<uint160>(pubkey_hash)) {}
25+
26+
CKeyID ToKeyID(const PKHash& key_hash)
27+
{
28+
return CKeyID{static_cast<uint160>(key_hash)};
29+
}
30+
31+
CKeyID ToKeyID(const WitnessV0KeyHash& key_hash)
32+
{
33+
return CKeyID{static_cast<uint160>(key_hash)};
34+
}
35+
36+
CScriptID ToScriptID(const ScriptHash& script_hash)
37+
{
38+
return CScriptID{static_cast<uint160>(script_hash)};
39+
}
40+
41+
WitnessV0ScriptHash::WitnessV0ScriptHash(const CScript& in)
42+
{
43+
CSHA256().Write(in.data(), in.size()).Finalize(begin());
44+
}
45+
46+
bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
47+
{
48+
std::vector<valtype> vSolutions;
49+
TxoutType whichType = Solver(scriptPubKey, vSolutions);
50+
51+
switch (whichType) {
52+
case TxoutType::PUBKEY: {
53+
CPubKey pubKey(vSolutions[0]);
54+
if (!pubKey.IsValid())
55+
return false;
56+
57+
addressRet = PKHash(pubKey);
58+
return true;
59+
}
60+
case TxoutType::PUBKEYHASH: {
61+
addressRet = PKHash(uint160(vSolutions[0]));
62+
return true;
63+
}
64+
case TxoutType::SCRIPTHASH: {
65+
addressRet = ScriptHash(uint160(vSolutions[0]));
66+
return true;
67+
}
68+
case TxoutType::WITNESS_V0_KEYHASH: {
69+
WitnessV0KeyHash hash;
70+
std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin());
71+
addressRet = hash;
72+
return true;
73+
}
74+
case TxoutType::WITNESS_V0_SCRIPTHASH: {
75+
WitnessV0ScriptHash hash;
76+
std::copy(vSolutions[0].begin(), vSolutions[0].end(), hash.begin());
77+
addressRet = hash;
78+
return true;
79+
}
80+
case TxoutType::WITNESS_V1_TAPROOT: {
81+
WitnessV1Taproot tap;
82+
std::copy(vSolutions[0].begin(), vSolutions[0].end(), tap.begin());
83+
addressRet = tap;
84+
return true;
85+
}
86+
case TxoutType::WITNESS_UNKNOWN: {
87+
WitnessUnknown unk;
88+
unk.version = vSolutions[0][0];
89+
std::copy(vSolutions[1].begin(), vSolutions[1].end(), unk.program);
90+
unk.length = vSolutions[1].size();
91+
addressRet = unk;
92+
return true;
93+
}
94+
case TxoutType::MULTISIG:
95+
case TxoutType::NULL_DATA:
96+
case TxoutType::NONSTANDARD:
97+
return false;
98+
} // no default case, so the compiler can warn about missing cases
99+
assert(false);
100+
}
101+
102+
namespace {
103+
class CScriptVisitor
104+
{
105+
public:
106+
CScript operator()(const CNoDestination& dest) const
107+
{
108+
return CScript();
109+
}
110+
111+
CScript operator()(const PKHash& keyID) const
112+
{
113+
return CScript() << OP_DUP << OP_HASH160 << ToByteVector(keyID) << OP_EQUALVERIFY << OP_CHECKSIG;
114+
}
115+
116+
CScript operator()(const ScriptHash& scriptID) const
117+
{
118+
return CScript() << OP_HASH160 << ToByteVector(scriptID) << OP_EQUAL;
119+
}
120+
121+
CScript operator()(const WitnessV0KeyHash& id) const
122+
{
123+
return CScript() << OP_0 << ToByteVector(id);
124+
}
125+
126+
CScript operator()(const WitnessV0ScriptHash& id) const
127+
{
128+
return CScript() << OP_0 << ToByteVector(id);
129+
}
130+
131+
CScript operator()(const WitnessV1Taproot& tap) const
132+
{
133+
return CScript() << OP_1 << ToByteVector(tap);
134+
}
135+
136+
CScript operator()(const WitnessUnknown& id) const
137+
{
138+
return CScript() << CScript::EncodeOP_N(id.version) << std::vector<unsigned char>(id.program, id.program + id.length);
139+
}
140+
};
141+
} // namespace
142+
143+
CScript GetScriptForDestination(const CTxDestination& dest)
144+
{
145+
return std::visit(CScriptVisitor(), dest);
146+
}
147+
148+
bool IsValidDestination(const CTxDestination& dest) {
149+
return dest.index() != 0;
150+
}

src/addresstype.h

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
// Copyright (c) 2023 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or https://www.opensource.org/licenses/mit-license.php.
4+
5+
#ifndef BITCOIN_ADDRESSTYPE_H
6+
#define BITCOIN_ADDRESSTYPE_H
7+
8+
#include <pubkey.h>
9+
#include <script/script.h>
10+
#include <uint256.h>
11+
#include <util/hash_type.h>
12+
13+
#include <variant>
14+
#include <algorithm>
15+
16+
class CNoDestination {
17+
public:
18+
friend bool operator==(const CNoDestination &a, const CNoDestination &b) { return true; }
19+
friend bool operator<(const CNoDestination &a, const CNoDestination &b) { return true; }
20+
};
21+
22+
struct PKHash : public BaseHash<uint160>
23+
{
24+
PKHash() : BaseHash() {}
25+
explicit PKHash(const uint160& hash) : BaseHash(hash) {}
26+
explicit PKHash(const CPubKey& pubkey);
27+
explicit PKHash(const CKeyID& pubkey_id);
28+
};
29+
CKeyID ToKeyID(const PKHash& key_hash);
30+
31+
struct WitnessV0KeyHash;
32+
33+
struct ScriptHash : public BaseHash<uint160>
34+
{
35+
ScriptHash() : BaseHash() {}
36+
// These don't do what you'd expect.
37+
// Use ScriptHash(GetScriptForDestination(...)) instead.
38+
explicit ScriptHash(const WitnessV0KeyHash& hash) = delete;
39+
explicit ScriptHash(const PKHash& hash) = delete;
40+
41+
explicit ScriptHash(const uint160& hash) : BaseHash(hash) {}
42+
explicit ScriptHash(const CScript& script);
43+
explicit ScriptHash(const CScriptID& script);
44+
};
45+
CScriptID ToScriptID(const ScriptHash& script_hash);
46+
47+
struct WitnessV0ScriptHash : public BaseHash<uint256>
48+
{
49+
WitnessV0ScriptHash() : BaseHash() {}
50+
explicit WitnessV0ScriptHash(const uint256& hash) : BaseHash(hash) {}
51+
explicit WitnessV0ScriptHash(const CScript& script);
52+
};
53+
54+
struct WitnessV0KeyHash : public BaseHash<uint160>
55+
{
56+
WitnessV0KeyHash() : BaseHash() {}
57+
explicit WitnessV0KeyHash(const uint160& hash) : BaseHash(hash) {}
58+
explicit WitnessV0KeyHash(const CPubKey& pubkey);
59+
explicit WitnessV0KeyHash(const PKHash& pubkey_hash);
60+
};
61+
CKeyID ToKeyID(const WitnessV0KeyHash& key_hash);
62+
63+
struct WitnessV1Taproot : public XOnlyPubKey
64+
{
65+
WitnessV1Taproot() : XOnlyPubKey() {}
66+
explicit WitnessV1Taproot(const XOnlyPubKey& xpk) : XOnlyPubKey(xpk) {}
67+
};
68+
69+
//! CTxDestination subtype to encode any future Witness version
70+
struct WitnessUnknown
71+
{
72+
unsigned int version;
73+
unsigned int length;
74+
unsigned char program[40];
75+
76+
friend bool operator==(const WitnessUnknown& w1, const WitnessUnknown& w2) {
77+
if (w1.version != w2.version) return false;
78+
if (w1.length != w2.length) return false;
79+
return std::equal(w1.program, w1.program + w1.length, w2.program);
80+
}
81+
82+
friend bool operator<(const WitnessUnknown& w1, const WitnessUnknown& w2) {
83+
if (w1.version < w2.version) return true;
84+
if (w1.version > w2.version) return false;
85+
if (w1.length < w2.length) return true;
86+
if (w1.length > w2.length) return false;
87+
return std::lexicographical_compare(w1.program, w1.program + w1.length, w2.program, w2.program + w2.length);
88+
}
89+
};
90+
91+
/**
92+
* A txout script template with a specific destination. It is either:
93+
* * CNoDestination: no destination set
94+
* * PKHash: TxoutType::PUBKEYHASH destination (P2PKH)
95+
* * ScriptHash: TxoutType::SCRIPTHASH destination (P2SH)
96+
* * WitnessV0ScriptHash: TxoutType::WITNESS_V0_SCRIPTHASH destination (P2WSH)
97+
* * WitnessV0KeyHash: TxoutType::WITNESS_V0_KEYHASH destination (P2WPKH)
98+
* * WitnessV1Taproot: TxoutType::WITNESS_V1_TAPROOT destination (P2TR)
99+
* * WitnessUnknown: TxoutType::WITNESS_UNKNOWN destination (P2W???)
100+
* A CTxDestination is the internal data type encoded in a bitcoin address
101+
*/
102+
using CTxDestination = std::variant<CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown>;
103+
104+
/** Check whether a CTxDestination is a CNoDestination. */
105+
bool IsValidDestination(const CTxDestination& dest);
106+
107+
/**
108+
* Parse a standard scriptPubKey for the destination address. Assigns result to
109+
* the addressRet parameter and returns true if successful. Currently only works for P2PK,
110+
* P2PKH, P2SH, P2WPKH, and P2WSH scripts.
111+
*/
112+
bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet);
113+
114+
/**
115+
* Generate a Bitcoin scriptPubKey for the given CTxDestination. Returns a P2PKH
116+
* script for a CKeyID destination, a P2SH script for a CScriptID, and an empty
117+
* script for CNoDestination.
118+
*/
119+
CScript GetScriptForDestination(const CTxDestination& dest);
120+
121+
#endif // BITCOIN_ADDRESSTYPE_H

src/bench/descriptors.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
#include <key.h>
77
#include <pubkey.h>
88
#include <script/descriptor.h>
9-
#include <script/standard.h>
109

1110
#include <string>
1211
#include <utility>

src/bench/verify_script.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#include <script/bitcoinconsensus.h>
99
#endif
1010
#include <script/script.h>
11-
#include <script/standard.h>
11+
#include <script/interpreter.h>
1212
#include <streams.h>
1313
#include <test/util/transaction_utils.h>
1414

src/common/bloom.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#include <primitives/transaction.h>
99
#include <random.h>
1010
#include <script/script.h>
11-
#include <script/standard.h>
11+
#include <script/solver.h>
1212
#include <span.h>
1313
#include <streams.h>
1414
#include <util/fastrange.h>

src/compressor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#include <compressor.h>
77

88
#include <pubkey.h>
9-
#include <script/standard.h>
9+
#include <script/script.h>
1010

1111
/*
1212
* These check for scripts for which a special case with a shorter encoding is defined.

src/core_write.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#include <key_io.h>
1212
#include <script/descriptor.h>
1313
#include <script/script.h>
14-
#include <script/standard.h>
14+
#include <script/solver.h>
1515
#include <serialize.h>
1616
#include <streams.h>
1717
#include <undo.h>

src/init.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@
6565
#include <rpc/util.h>
6666
#include <scheduler.h>
6767
#include <script/sigcache.h>
68-
#include <script/standard.h>
6968
#include <shutdown.h>
7069
#include <sync.h>
7170
#include <timedata.h>

src/interfaces/wallet.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@
55
#ifndef BITCOIN_INTERFACES_WALLET_H
66
#define BITCOIN_INTERFACES_WALLET_H
77

8+
#include <addresstype.h>
89
#include <consensus/amount.h>
9-
#include <interfaces/chain.h> // For ChainClient
10-
#include <pubkey.h> // For CKeyID and CScriptID (definitions needed in CTxDestination instantiation)
11-
#include <script/standard.h> // For CTxDestination
12-
#include <support/allocators/secure.h> // For SecureString
10+
#include <interfaces/chain.h>
11+
#include <pubkey.h>
12+
#include <script/script.h>
13+
#include <support/allocators/secure.h>
1314
#include <util/fs.h>
1415
#include <util/message.h>
1516
#include <util/result.h>

0 commit comments

Comments
 (0)