Skip to content

Conversation

@w0xlt
Copy link
Contributor

@w0xlt w0xlt commented Nov 5, 2025

This PR exposes the consensus-level CheckTransaction function through the libbitcoinkernel C API and adds a corresponding C++ wrapper.

Currently, libkernel only provided script-level validation via btck_script_pubkey_verify and ScriptPubkeyApi<>::Verify.

AFAIK there was no way to perform context-free consensus checks on a transaction’s structure (e.g., coinbase rules, money-range, duplicate inputs).

This change introduces a new API:

int btck_check_transaction(const btck_Transaction* tx, btck_TxValidationState** out_state);

and a C++ convenience wrapper:

std::pair<bool, TxValidationState> btck::CheckTransaction(const Transaction& tx);

Both follow the ownership and error-handling conventions established in bitcoinkernel.h.

The test suite is extended with cases covering:

  • coinbase scriptSig length bounds
  • empty vin / vout detection
  • negative or out-of-range output values
  • duplicate inputs
  • null prevouts in non-coinbase transactions

@DrahtBot
Copy link
Contributor

DrahtBot commented Nov 5, 2025

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Code Coverage & Benchmarks

For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/33796.

Reviews

See the guideline for information on the review process.

Type Reviewers
Concept ACK TheCharlatan, janb84
Approach ACK yuvicc

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #33908 (kernel: add context‑free block validation API (btck_check_block_context_free) with POW/Merkle flags by w0xlt)
  • #33891 (kernel: Expose reusable PrecomputedTransactionData in script validation by joshdoman)
  • #33856 (kernel, validation: Refactor ProcessNewBlockHeaders to return BlockValidationState by yuvicc)
  • #33847 (kernel: Improve logging API by ryanofsky)
  • #33822 (kernel: Add block header support and validation by yuvicc)
  • #33779 (ci, iwyu: Fix warnings in src/kernel and treat them as errors by hebasto)

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

#define btck_TxValidationResult_MEMPOOL_POLICY ((btck_TxValidationResult)(9))
#define btck_TxValidationResult_NO_MEMPOOL ((btck_TxValidationResult)(10))
#define btck_TxValidationResult_RECONSIDERABLE ((btck_TxValidationResult)(11))
#define btck_TxValidationResult_UNKNOWN ((btck_TxValidationResult)(12))
Copy link
Contributor

Choose a reason for hiding this comment

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

shouldn't this be bigger than 12 (or could maybe be 0) so that new values can be added in the future?

@sedited
Copy link
Contributor

sedited commented Nov 6, 2025

Concept ACK on adding more checks. I am not sure how useful this check by itself is though, since it lacks finality, inputs, sigops, amount + fee, and script checks. Are you planning on adding these too and if not, what is the purpose served from surfacing the context-free checks, but not the others?

I think the unit tests are going a bit too far. We don't have to verify again that our validation logic works internally and should instead just verify that the function's contract is correct. If you want to check that the mapping for each of the result enums is correct maybe pass in a few hard-coded transactions instead? We do the same in our unit tests too so maybe just reuse a few of the vectors from test/data/tx_invalid.json?

@w0xlt
Copy link
Contributor Author

w0xlt commented Nov 6, 2025

I am not sure how useful this check by itself is … what is the purpose served from surfacing the context‑free checks, but not the others?

The new API intentionally exposes only the context‑free consensus predicate (consensus/tx_check::CheckTransaction) so callers can fail fast on malformed transactions without needing a kernel context, UTXO set, or policy knobs.

This gives library users (indexers, gateways, alternative mempool layers, etc.) a cheap pre‑filter to catch structural rule violations like empty vin/vout, out‑of‑range amounts, coinbase scriptSig length bounds, duplicate inputs, or null prevouts in non‑coinbase txs—before doing any stateful or expensive work.

Script checks are already available via btck_script_pubkey_verify in this API; inputs/fees/sigops/finality all need UTXO and/or chain context and are out of scope for a context‑free entry point.

think the unit tests are going a bit too far … instead just verify that the function’s contract is correct.

Agreed. This can be simplified.

@sedited sedited moved this to Ready for Review PRs in The libbitcoinkernel Project Nov 7, 2025
@fanquake fanquake changed the title [kernel] Expose CheckTransaction consensus validation function kernel: Expose CheckTransaction consensus validation function Nov 7, 2025
Copy link
Contributor

@yuvicc yuvicc left a comment

Choose a reason for hiding this comment

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

Approach ACK

Great addition exposing CheckTransaction to the kernel API. This will be useful to external users needing context-free transaction validation.

Comment on lines +600 to +603
/**
* @brief Run consensus/tx_check::CheckTransaction on a tx and return the filled state.
* @return 1 if valid, 0 if invalid.
*/
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
/**
* @brief Run consensus/tx_check::CheckTransaction on a tx and return the filled state.
* @return 1 if valid, 0 if invalid.
*/
/**
* @brief Run consensus/tx_check::CheckTransaction on a transaction.
*
* Performs context-free consensus validation on a transaction without
* requiring blockchain state.
*
* @param[in] tx The transaction to validate
* @param[out] out_state Pointer to receive the validation state (always set,
* caller must destroy with btck_tx_validation_state_destroy)
* @return 1 if valid, 0 if invalid
*/

Copy link
Contributor

@janb84 janb84 left a comment

Choose a reason for hiding this comment

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

Concept ACK a262282

PR extends bitcoin kernel library with the checkTransaction consensus validation function.

Added a suggestion NIT (non-blocking) and I agree with the NIT from yuvicc

Steps taken:


// -----------------------------------------------------------------------------
// CheckTransaction tests
// -----------------------------------------------------------------------------
Copy link
Contributor

Choose a reason for hiding this comment

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

NIT: (non-blocking) maybe add a note why only the 2 (possible) states are tested ? For a non-bitcoin-core dev this is maybe a bit unclear given all the TxValidationResults and the Check_Transaction that these are the 2 outcomes.
It's for me not logical to add this as a comment on the function because it returns a pointer to the results.

Suggested change
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Note: CheckTransaction performs only basic consensus checks and returns either:
// - VALID (ValidationMode::VALID, TxValidationResult::UNSET) for valid transactions
// - INVALID (ValidationMode::INVALID, TxValidationResult::CONSENSUS) for violations
//
// Other TxValidationResult values are set by higher-level validation functions and
// not exposed through btck_check_transaction.
// -----------------------------------------------------------------------------

@DrahtBot
Copy link
Contributor

🐙 This pull request conflicts with the target branch and needs rebase.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: API Development

Development

Successfully merging this pull request may close these issues.

6 participants