Merge bitcoin/bitcoin#29648: Remove libbitcoinconsensus

80f8b92f4f remove libbitcoinconsensus (fanquake)

Pull request description:

  This was deprecated in `v27.0`, for removal in `v28.0`. See discussion in PR #29189.

ACKs for top commit:
  theuni:
    Concept ACK and light review ACK 80f8b92f4f. My only hesitation here is that (afaics?) there's now nothing keeping undesired features like threading or globals from working their way into the interpreter in future commits.
  m3dwards:
    Concept ACK 80f8b92f4f
  TheCharlatan:
    ACK 80f8b92f4f
  hebasto:
    ACK 80f8b92f4f, I have reviewed the code and it looks OK.

Tree-SHA512: 17a62118aeb088f2695c892bb32794dfea3061e3cb7d9e8e9f1c06c3ff6f63a7587fa532e37edbb91fbc5a19b12c9a0f8e05fa9e8864aa07f92665375d847e80
This commit is contained in:
fanquake
2024-04-01 17:46:37 +02:00
17 changed files with 10 additions and 694 deletions

View File

@@ -1,157 +0,0 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2022 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <script/bitcoinconsensus.h>
#include <primitives/transaction.h>
#include <pubkey.h>
#include <script/interpreter.h>
namespace {
/** A class that deserializes a single CTransaction one time. */
class TxInputStream
{
public:
TxInputStream(const unsigned char *txTo, size_t txToLen) :
m_data(txTo),
m_remaining(txToLen)
{}
void read(Span<std::byte> dst)
{
if (dst.size() > m_remaining) {
throw std::ios_base::failure(std::string(__func__) + ": end of data");
}
if (dst.data() == nullptr) {
throw std::ios_base::failure(std::string(__func__) + ": bad destination buffer");
}
if (m_data == nullptr) {
throw std::ios_base::failure(std::string(__func__) + ": bad source buffer");
}
memcpy(dst.data(), m_data, dst.size());
m_remaining -= dst.size();
m_data += dst.size();
}
template<typename T>
TxInputStream& operator>>(T&& obj)
{
::Unserialize(*this, obj);
return *this;
}
private:
const unsigned char* m_data;
size_t m_remaining;
};
inline int set_error(bitcoinconsensus_error* ret, bitcoinconsensus_error serror)
{
if (ret)
*ret = serror;
return 0;
}
} // namespace
/** Check that all specified flags are part of the libconsensus interface. */
static bool verify_flags(unsigned int flags)
{
return (flags & ~(bitcoinconsensus_SCRIPT_FLAGS_VERIFY_ALL)) == 0;
}
static int verify_script(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, CAmount amount,
const unsigned char *txTo , unsigned int txToLen,
const UTXO *spentOutputs, unsigned int spentOutputsLen,
unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err)
{
if (!verify_flags(flags)) {
return set_error(err, bitcoinconsensus_ERR_INVALID_FLAGS);
}
if (flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_TAPROOT && spentOutputs == nullptr) {
return set_error(err, bitcoinconsensus_ERR_SPENT_OUTPUTS_REQUIRED);
}
try {
TxInputStream stream(txTo, txToLen);
CTransaction tx(deserialize, TX_WITH_WITNESS, stream);
std::vector<CTxOut> spent_outputs;
if (spentOutputs != nullptr) {
if (spentOutputsLen != tx.vin.size()) {
return set_error(err, bitcoinconsensus_ERR_SPENT_OUTPUTS_MISMATCH);
}
for (size_t i = 0; i < spentOutputsLen; i++) {
CScript spk = CScript(spentOutputs[i].scriptPubKey, spentOutputs[i].scriptPubKey + spentOutputs[i].scriptPubKeySize);
const CAmount& value = spentOutputs[i].value;
CTxOut tx_out = CTxOut(value, spk);
spent_outputs.push_back(tx_out);
}
}
if (nIn >= tx.vin.size())
return set_error(err, bitcoinconsensus_ERR_TX_INDEX);
if (GetSerializeSize(TX_WITH_WITNESS(tx)) != txToLen)
return set_error(err, bitcoinconsensus_ERR_TX_SIZE_MISMATCH);
// Regardless of the verification result, the tx did not error.
set_error(err, bitcoinconsensus_ERR_OK);
PrecomputedTransactionData txdata(tx);
if (spentOutputs != nullptr && flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_TAPROOT) {
txdata.Init(tx, std::move(spent_outputs));
}
return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), &tx.vin[nIn].scriptWitness, flags, TransactionSignatureChecker(&tx, nIn, amount, txdata, MissingDataBehavior::FAIL), nullptr);
} catch (const std::exception&) {
return set_error(err, bitcoinconsensus_ERR_TX_DESERIALIZE); // Error deserializing
}
}
int bitcoinconsensus_verify_script_with_spent_outputs(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, int64_t amount,
const unsigned char *txTo , unsigned int txToLen,
const UTXO *spentOutputs, unsigned int spentOutputsLen,
unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err)
{
CAmount am(amount);
return ::verify_script(scriptPubKey, scriptPubKeyLen, am, txTo, txToLen, spentOutputs, spentOutputsLen, nIn, flags, err);
}
int bitcoinconsensus_verify_script_with_amount(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, int64_t amount,
const unsigned char *txTo , unsigned int txToLen,
unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err)
{
CAmount am(amount);
UTXO *spentOutputs = nullptr;
unsigned int spentOutputsLen = 0;
return ::verify_script(scriptPubKey, scriptPubKeyLen, am, txTo, txToLen, spentOutputs, spentOutputsLen, nIn, flags, err);
}
int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen,
const unsigned char *txTo , unsigned int txToLen,
unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err)
{
if (flags & bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS) {
return set_error(err, bitcoinconsensus_ERR_AMOUNT_REQUIRED);
}
CAmount am(0);
UTXO *spentOutputs = nullptr;
unsigned int spentOutputsLen = 0;
return ::verify_script(scriptPubKey, scriptPubKeyLen, am, txTo, txToLen, spentOutputs, spentOutputsLen, nIn, flags, err);
}
unsigned int bitcoinconsensus_version()
{
// Just use the API version for now
return BITCOINCONSENSUS_API_VER;
}

View File

@@ -1,96 +0,0 @@
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2021 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef BITCOIN_SCRIPT_BITCOINCONSENSUS_H
#define BITCOIN_SCRIPT_BITCOINCONSENSUS_H
#include <stdint.h>
#if defined(BUILD_BITCOIN_INTERNAL) && defined(HAVE_CONFIG_H)
#include <config/bitcoin-config.h>
#if defined(_WIN32)
#if defined(HAVE_DLLEXPORT_ATTRIBUTE)
#define EXPORT_SYMBOL __declspec(dllexport)
#else
#define EXPORT_SYMBOL
#endif
#elif defined(HAVE_DEFAULT_VISIBILITY_ATTRIBUTE)
#define EXPORT_SYMBOL __attribute__ ((visibility ("default")))
#endif
#elif defined(MSC_VER) && !defined(STATIC_LIBBITCOINCONSENSUS)
#define EXPORT_SYMBOL __declspec(dllimport)
#endif
#ifndef EXPORT_SYMBOL
#define EXPORT_SYMBOL
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define BITCOINCONSENSUS_API_VER 2
typedef enum bitcoinconsensus_error_t
{
bitcoinconsensus_ERR_OK = 0,
bitcoinconsensus_ERR_TX_INDEX,
bitcoinconsensus_ERR_TX_SIZE_MISMATCH,
bitcoinconsensus_ERR_TX_DESERIALIZE,
bitcoinconsensus_ERR_AMOUNT_REQUIRED,
bitcoinconsensus_ERR_INVALID_FLAGS,
bitcoinconsensus_ERR_SPENT_OUTPUTS_REQUIRED,
bitcoinconsensus_ERR_SPENT_OUTPUTS_MISMATCH
} bitcoinconsensus_error;
/** Script verification flags */
enum
{
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NONE = 0,
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_P2SH = (1U << 0), // evaluate P2SH (BIP16) subscripts
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_DERSIG = (1U << 2), // enforce strict DER (BIP66) compliance
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NULLDUMMY = (1U << 4), // enforce NULLDUMMY (BIP147)
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY = (1U << 9), // enable CHECKLOCKTIMEVERIFY (BIP65)
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKSEQUENCEVERIFY = (1U << 10), // enable CHECKSEQUENCEVERIFY (BIP112)
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS = (1U << 11), // enable WITNESS (BIP141)
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_TAPROOT = (1U << 17), // enable TAPROOT (BIPs 341 & 342)
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_ALL = bitcoinconsensus_SCRIPT_FLAGS_VERIFY_P2SH | bitcoinconsensus_SCRIPT_FLAGS_VERIFY_DERSIG |
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NULLDUMMY | bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKLOCKTIMEVERIFY |
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_CHECKSEQUENCEVERIFY | bitcoinconsensus_SCRIPT_FLAGS_VERIFY_WITNESS |
bitcoinconsensus_SCRIPT_FLAGS_VERIFY_TAPROOT
};
typedef struct {
const unsigned char *scriptPubKey;
unsigned int scriptPubKeySize;
int64_t value;
} UTXO;
/// Returns 1 if the input nIn of the serialized transaction pointed to by
/// txTo correctly spends the scriptPubKey pointed to by scriptPubKey under
/// the additional constraints specified by flags.
/// If not nullptr, err will contain an error/success code for the operation
EXPORT_SYMBOL int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen,
const unsigned char *txTo , unsigned int txToLen,
unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err);
EXPORT_SYMBOL int bitcoinconsensus_verify_script_with_amount(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, int64_t amount,
const unsigned char *txTo , unsigned int txToLen,
unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err);
EXPORT_SYMBOL int bitcoinconsensus_verify_script_with_spent_outputs(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, int64_t amount,
const unsigned char *txTo , unsigned int txToLen,
const UTXO *spentOutputs, unsigned int spentOutputsLen,
unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err);
EXPORT_SYMBOL unsigned int bitcoinconsensus_version();
#ifdef __cplusplus
} // extern "C"
#endif
#undef EXPORT_SYMBOL
#endif // BITCOIN_SCRIPT_BITCOINCONSENSUS_H