Skip to content

Commit fd24729

Browse files
committed
Expose ScriptError codes from kernel verification API
1 parent 61533c2 commit fd24729

7 files changed

Lines changed: 579 additions & 28 deletions

File tree

libbitcoinkernel-sys/bitcoin/src/kernel/bitcoinkernel.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <script/debug.h>
2525
#include <script/interpreter.h>
2626
#include <script/script.h>
27+
#include <script/script_error.h>
2728
#include <serialize.h>
2829
#include <streams.h>
2930
#include <sync.h>
@@ -653,7 +654,8 @@ int btck_script_pubkey_verify(const btck_ScriptPubkey* script_pubkey,
653654
const btck_PrecomputedTransactionData* precomputed_txdata,
654655
const unsigned int input_index,
655656
const btck_ScriptVerificationFlags flags,
656-
btck_ScriptVerifyStatus* status)
657+
btck_ScriptVerifyStatus* status,
658+
btck_ScriptError* script_error)
657659
{
658660
// Assert that all specified flags are part of the interface before continuing
659661
assert((flags & ~btck_ScriptVerificationFlags_ALL) == 0);
@@ -675,12 +677,14 @@ int btck_script_pubkey_verify(const btck_ScriptPubkey* script_pubkey,
675677

676678
if (status) *status = btck_ScriptVerifyStatus_OK;
677679

680+
ScriptError serror;
678681
bool result = VerifyScript(tx.vin[input_index].scriptSig,
679682
btck_ScriptPubkey::get(script_pubkey),
680683
&tx.vin[input_index].scriptWitness,
681684
script_verify_flags::from_int(flags),
682685
TransactionSignatureChecker(&tx, input_index, amount, txdata, MissingDataBehavior::FAIL),
683-
nullptr);
686+
&serror);
687+
if (script_error) *script_error = static_cast<btck_ScriptError>(serror);
684688
return result ? 1 : 0;
685689
}
686690

libbitcoinkernel-sys/bitcoin/src/kernel/bitcoinkernel.h

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,75 @@ typedef uint8_t btck_ScriptVerifyStatus;
465465
#define btck_ScriptVerifyStatus_ERROR_INVALID_FLAGS_COMBINATION ((btck_ScriptVerifyStatus)(1)) //!< The flags were combined in an invalid way.
466466
#define btck_ScriptVerifyStatus_ERROR_SPENT_OUTPUTS_REQUIRED ((btck_ScriptVerifyStatus)(2)) //!< The taproot flag was set, so valid spent_outputs have to be provided.
467467

468+
/**
469+
* Script error codes returned by the script interpreter.
470+
* Values match the C++ ScriptError_t enum in script_error.h.
471+
*/
472+
typedef uint8_t btck_ScriptError;
473+
#define btck_ScriptError_OK ((btck_ScriptError)(0))
474+
#define btck_ScriptError_UNKNOWN ((btck_ScriptError)(1))
475+
#define btck_ScriptError_EVAL_FALSE ((btck_ScriptError)(2))
476+
#define btck_ScriptError_OP_RETURN ((btck_ScriptError)(3))
477+
/* Max sizes */
478+
#define btck_ScriptError_SCRIPT_SIZE ((btck_ScriptError)(4))
479+
#define btck_ScriptError_PUSH_SIZE ((btck_ScriptError)(5))
480+
#define btck_ScriptError_OP_COUNT ((btck_ScriptError)(6))
481+
#define btck_ScriptError_STACK_SIZE ((btck_ScriptError)(7))
482+
#define btck_ScriptError_SIG_COUNT ((btck_ScriptError)(8))
483+
#define btck_ScriptError_PUBKEY_COUNT ((btck_ScriptError)(9))
484+
/* Failed verify operations */
485+
#define btck_ScriptError_VERIFY ((btck_ScriptError)(10))
486+
#define btck_ScriptError_EQUALVERIFY ((btck_ScriptError)(11))
487+
#define btck_ScriptError_CHECKMULTISIGVERIFY ((btck_ScriptError)(12))
488+
#define btck_ScriptError_CHECKSIGVERIFY ((btck_ScriptError)(13))
489+
#define btck_ScriptError_NUMEQUALVERIFY ((btck_ScriptError)(14))
490+
/* Logical/Format/Canonical errors */
491+
#define btck_ScriptError_BAD_OPCODE ((btck_ScriptError)(15))
492+
#define btck_ScriptError_DISABLED_OPCODE ((btck_ScriptError)(16))
493+
#define btck_ScriptError_INVALID_STACK_OPERATION ((btck_ScriptError)(17))
494+
#define btck_ScriptError_INVALID_ALTSTACK_OPERATION ((btck_ScriptError)(18))
495+
#define btck_ScriptError_UNBALANCED_CONDITIONAL ((btck_ScriptError)(19))
496+
/* CHECKLOCKTIMEVERIFY and CHECKSEQUENCEVERIFY */
497+
#define btck_ScriptError_NEGATIVE_LOCKTIME ((btck_ScriptError)(20))
498+
#define btck_ScriptError_UNSATISFIED_LOCKTIME ((btck_ScriptError)(21))
499+
/* Malleability */
500+
#define btck_ScriptError_SIG_HASHTYPE ((btck_ScriptError)(22))
501+
#define btck_ScriptError_SIG_DER ((btck_ScriptError)(23))
502+
#define btck_ScriptError_MINIMALDATA ((btck_ScriptError)(24))
503+
#define btck_ScriptError_SIG_PUSHONLY ((btck_ScriptError)(25))
504+
#define btck_ScriptError_SIG_HIGH_S ((btck_ScriptError)(26))
505+
#define btck_ScriptError_SIG_NULLDUMMY ((btck_ScriptError)(27))
506+
#define btck_ScriptError_PUBKEYTYPE ((btck_ScriptError)(28))
507+
#define btck_ScriptError_CLEANSTACK ((btck_ScriptError)(29))
508+
#define btck_ScriptError_MINIMALIF ((btck_ScriptError)(30))
509+
#define btck_ScriptError_SIG_NULLFAIL ((btck_ScriptError)(31))
510+
/* Softfork safeness */
511+
#define btck_ScriptError_DISCOURAGE_UPGRADABLE_NOPS ((btck_ScriptError)(32))
512+
#define btck_ScriptError_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM ((btck_ScriptError)(33))
513+
#define btck_ScriptError_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION ((btck_ScriptError)(34))
514+
#define btck_ScriptError_DISCOURAGE_OP_SUCCESS ((btck_ScriptError)(35))
515+
#define btck_ScriptError_DISCOURAGE_UPGRADABLE_PUBKEYTYPE ((btck_ScriptError)(36))
516+
/* Segregated witness */
517+
#define btck_ScriptError_WITNESS_PROGRAM_WRONG_LENGTH ((btck_ScriptError)(37))
518+
#define btck_ScriptError_WITNESS_PROGRAM_WITNESS_EMPTY ((btck_ScriptError)(38))
519+
#define btck_ScriptError_WITNESS_PROGRAM_MISMATCH ((btck_ScriptError)(39))
520+
#define btck_ScriptError_WITNESS_MALLEATED ((btck_ScriptError)(40))
521+
#define btck_ScriptError_WITNESS_MALLEATED_P2SH ((btck_ScriptError)(41))
522+
#define btck_ScriptError_WITNESS_UNEXPECTED ((btck_ScriptError)(42))
523+
#define btck_ScriptError_WITNESS_PUBKEYTYPE ((btck_ScriptError)(43))
524+
/* Taproot */
525+
#define btck_ScriptError_SCHNORR_SIG_SIZE ((btck_ScriptError)(44))
526+
#define btck_ScriptError_SCHNORR_SIG_HASHTYPE ((btck_ScriptError)(45))
527+
#define btck_ScriptError_SCHNORR_SIG ((btck_ScriptError)(46))
528+
#define btck_ScriptError_TAPROOT_WRONG_CONTROL_SIZE ((btck_ScriptError)(47))
529+
#define btck_ScriptError_TAPSCRIPT_VALIDATION_WEIGHT ((btck_ScriptError)(48))
530+
#define btck_ScriptError_TAPSCRIPT_CHECKMULTISIG ((btck_ScriptError)(49))
531+
#define btck_ScriptError_TAPSCRIPT_MINIMALIF ((btck_ScriptError)(50))
532+
#define btck_ScriptError_TAPSCRIPT_EMPTY_PUBKEY ((btck_ScriptError)(51))
533+
/* Constant scriptCode */
534+
#define btck_ScriptError_OP_CODESEPARATOR ((btck_ScriptError)(52))
535+
#define btck_ScriptError_SIG_FINDANDDELETE ((btck_ScriptError)(53))
536+
468537
/**
469538
* Script verification flags that may be composed with each other.
470539
*/
@@ -664,6 +733,7 @@ BITCOINKERNEL_API btck_ScriptPubkey* BITCOINKERNEL_WARN_UNUSED_RESULT btck_scrip
664733
* @param[in] input_index Index of the input in tx_to spending the script_pubkey.
665734
* @param[in] flags Bitfield of btck_ScriptVerificationFlags controlling validation constraints.
666735
* @param[out] status Nullable, will be set to an error code if the operation fails, or OK otherwise.
736+
* @param[out] script_error Nullable, will be set to the specific script error code on verification failure.
667737
* @return 1 if the script is valid, 0 otherwise.
668738
*/
669739
BITCOINKERNEL_API int BITCOINKERNEL_WARN_UNUSED_RESULT btck_script_pubkey_verify(
@@ -673,7 +743,8 @@ BITCOINKERNEL_API int BITCOINKERNEL_WARN_UNUSED_RESULT btck_script_pubkey_verify
673743
const btck_PrecomputedTransactionData* precomputed_txdata,
674744
unsigned int input_index,
675745
btck_ScriptVerificationFlags flags,
676-
btck_ScriptVerifyStatus* status) BITCOINKERNEL_ARG_NONNULL(1, 3);
746+
btck_ScriptVerifyStatus* status,
747+
btck_ScriptError* script_error) BITCOINKERNEL_ARG_NONNULL(1, 3);
677748

678749
/**
679750
* @brief Serializes the script pubkey through the passed in callback to bytes.

src/core/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub use block::{
2323
pub use script::ScriptPubkeyExt;
2424
pub use transaction::{TransactionExt, TxInExt, TxOutExt, TxOutPointExt, TxidExt};
2525

26-
pub use verify::{verify, PrecomputedTransactionData, ScriptVerifyError};
26+
pub use verify::{verify, PrecomputedTransactionData, ScriptError, ScriptVerifyError};
2727

2828
pub mod verify_flags {
2929
pub use super::verify::{

0 commit comments

Comments
 (0)