Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Break up script/standard.{h/cpp} #28244

Merged
merged 9 commits into from
Aug 17, 2023
8 changes: 5 additions & 3 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ endif
.PHONY: FORCE check-symbols check-security
# bitcoin core #
BITCOIN_CORE_H = \
addresstype.h \
addrdb.h \
addrman.h \
addrman_impl.h \
Expand Down Expand Up @@ -264,7 +265,7 @@ BITCOIN_CORE_H = \
script/sigcache.h \
script/sign.h \
script/signingprovider.h \
script/standard.h \
script/solver.h \
shutdown.h \
signet.h \
streams.h \
Expand Down Expand Up @@ -657,6 +658,7 @@ libbitcoin_consensus_a_SOURCES = \
libbitcoin_common_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BOOST_CPPFLAGS)
libbitcoin_common_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
libbitcoin_common_a_SOURCES = \
addresstype.cpp \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit in 7a172c7: Could keep this in the script directory, next to script/descriptor.cpp?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes or maybe have a new directory for everything that's "working with scripts" (addresstype, descriptor, signingprovider, ..).

base58.cpp \
bech32.cpp \
chainparams.cpp \
Expand Down Expand Up @@ -697,7 +699,7 @@ libbitcoin_common_a_SOURCES = \
script/miniscript.cpp \
script/sign.cpp \
script/signingprovider.cpp \
script/standard.cpp \
script/solver.cpp \
warnings.cpp \
$(BITCOIN_CORE_H)

Expand Down Expand Up @@ -958,7 +960,7 @@ libbitcoinkernel_la_SOURCES = \
script/script.cpp \
script/script_error.cpp \
script/sigcache.cpp \
script/standard.cpp \
script/solver.cpp \
signet.cpp \
streams.cpp \
support/cleanse.cpp \
Expand Down
150 changes: 150 additions & 0 deletions src/addresstype.cpp
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>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

7a172c7:nit: missing newline?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #28284

#include <script/script.h>
#include <script/solver.h>
#include <hash.h>
#include <pubkey.h>
#include <uint256.h>
#include <util/hash_type.h>

#include <vector>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

7a172c7: nit:

addresstype.cpp should add these lines:
#include <cassert>
#include "crypto/sha256.h"   // for CSHA256
#include "span.h"            // for Span

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in #28284


typedef std::vector<unsigned char> valtype;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

7a172c7: nit: Any reason to put this in this scope, instead of in the only scope that uses it (one function)?

Also, could use using (C++11)?


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;
}
121 changes: 121 additions & 0 deletions src/addresstype.h
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
1 change: 0 additions & 1 deletion src/bench/descriptors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#include <key.h>
#include <pubkey.h>
#include <script/descriptor.h>
#include <script/standard.h>

#include <string>
#include <utility>
Expand Down
2 changes: 1 addition & 1 deletion src/bench/verify_script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include <script/bitcoinconsensus.h>
#endif
#include <script/script.h>
#include <script/standard.h>
#include <script/interpreter.h>
#include <streams.h>
#include <test/util/transaction_utils.h>

Expand Down
2 changes: 1 addition & 1 deletion src/common/bloom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include <primitives/transaction.h>
#include <random.h>
#include <script/script.h>
#include <script/standard.h>
#include <script/solver.h>
#include <span.h>
#include <streams.h>
#include <util/fastrange.h>
Expand Down
2 changes: 1 addition & 1 deletion src/compressor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <compressor.h>

#include <pubkey.h>
#include <script/standard.h>
#include <script/script.h>

/*
* These check for scripts for which a special case with a shorter encoding is defined.
Expand Down
2 changes: 1 addition & 1 deletion src/core_write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include <key_io.h>
#include <script/descriptor.h>
#include <script/script.h>
#include <script/standard.h>
#include <script/solver.h>
#include <serialize.h>
#include <streams.h>
#include <undo.h>
Expand Down
1 change: 0 additions & 1 deletion src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@
#include <rpc/util.h>
#include <scheduler.h>
#include <script/sigcache.h>
#include <script/standard.h>
#include <shutdown.h>
#include <sync.h>
#include <timedata.h>
Expand Down
9 changes: 5 additions & 4 deletions src/interfaces/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
#ifndef BITCOIN_INTERFACES_WALLET_H
#define BITCOIN_INTERFACES_WALLET_H

#include <addresstype.h>
#include <consensus/amount.h>
#include <interfaces/chain.h> // For ChainClient
#include <pubkey.h> // For CKeyID and CScriptID (definitions needed in CTxDestination instantiation)
#include <script/standard.h> // For CTxDestination
#include <support/allocators/secure.h> // For SecureString
#include <interfaces/chain.h>
#include <pubkey.h>
#include <script/script.h>
#include <support/allocators/secure.h>
#include <util/fs.h>
#include <util/message.h>
#include <util/result.h>
Expand Down
1 change: 0 additions & 1 deletion src/kernel/mempool_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

#include <policy/feerate.h>
#include <policy/policy.h>
#include <script/standard.h>

#include <chrono>
#include <cstdint>
Expand Down