From b489a41d50e298099e3034ca43ed605ffc269ff2 Mon Sep 17 00:00:00 2001 From: Byron Hambly Date: Mon, 8 Dec 2025 15:01:09 +0200 Subject: [PATCH] ci: fuzz fixes --- src/rpc/output_script.cpp | 2 -- src/rpc/rawtransaction.cpp | 3 +++ src/script/interpreter.cpp | 2 +- src/test/fuzz/script.cpp | 2 +- src/test/fuzz/simplicity_tx.cpp | 6 +++++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/rpc/output_script.cpp b/src/rpc/output_script.cpp index 0b779710ef..2328036339 100644 --- a/src/rpc/output_script.cpp +++ b/src/rpc/output_script.cpp @@ -78,8 +78,6 @@ static RPCHelpMan validateaddress() CTxDestination parent_dest = DecodeParentDestination(request.params[0].get_str(), error_msg_parent); const bool isValid = IsValidDestination(dest); const bool is_valid_parent = IsValidDestination(parent_dest); - CHECK_NONFATAL(isValid == error_msg.empty()); - CHECK_NONFATAL(is_valid_parent == error_msg_parent.empty()); UniValue ret(UniValue::VOBJ); ret.pushKV("isvalid", isValid); diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 1dc5ffc8ac..7786078106 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -725,6 +725,9 @@ static RPCHelpMan combinerawtransaction() }, [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { + if (request.params.size() < 1 || !request.params[0].isArray()) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Expected an array of hex-encoded transactions"); + } UniValue txs = request.params[0].get_array(); std::vector txVariants(txs.size()); diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index 2796390556..4d213d2851 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -2641,7 +2641,7 @@ void PrecomputedTransactionData::Init(const T& txTo, std::vector&& spent simplicityRawTx.numInputs = simplicityRawInput.size(); simplicityRawTx.output = simplicityRawOutput.data(); simplicityRawTx.numOutputs = simplicityRawOutput.size(); - simplicityRawTx.version = txTo.nVersion; + simplicityRawTx.version = (uint32_t)txTo.nVersion; simplicityRawTx.lockTime = txTo.nLockTime; m_simplicity_tx_data = SimplicityTransactionUniquePtr(simplicity_elements_mallocTransaction(&simplicityRawTx)); diff --git a/src/test/fuzz/script.cpp b/src/test/fuzz/script.cpp index fe41a8c6ae..535dbbdeb3 100644 --- a/src/test/fuzz/script.cpp +++ b/src/test/fuzz/script.cpp @@ -155,7 +155,7 @@ FUZZ_TARGET(script, .init = initialize_script) if (!std::get_if(&tx_destination_1)) { // Only try to round trip non-pubkey destinations since PubKeyDestination has no encoding - Assert(dest.empty() != valid); + // Assert(dest.empty() != valid); // ELEMENTS: CNoDestination can have a script but is still not a valid destination Assert(tx_destination_1 == DecodeDestination(encoded_dest)); Assert(valid == IsValidDestinationString(encoded_dest)); } diff --git a/src/test/fuzz/simplicity_tx.cpp b/src/test/fuzz/simplicity_tx.cpp index d6ee92795d..6711ef4905 100644 --- a/src/test/fuzz/simplicity_tx.cpp +++ b/src/test/fuzz/simplicity_tx.cpp @@ -146,7 +146,11 @@ FUZZ_TARGET(simplicity_tx, .init = initialize_simplicity_tx) const auto& control = current[top - 1]; const auto& program = current[top - 3]; - if (control.size() >= TAPROOT_CONTROL_BASE_SIZE && (control[0] & 0xfe) == 0xbe) { + // invariant for ComputeTaprootMerkleRoot + bool control_size_valid = control.size() >= TAPROOT_CONTROL_BASE_SIZE && + control.size() <= TAPROOT_CONTROL_MAX_SIZE && + ((control.size() - TAPROOT_CONTROL_BASE_SIZE) % TAPROOT_CONTROL_NODE_SIZE == 0); + if (control_size_valid && (control[0] & TAPROOT_LEAF_MASK) == TAPROOT_LEAF_TAPSIMPLICITY) { // The fuzzer won't be able to produce a valid CMR on its own, so we compute it // and jam it into the witness stack. But we do require the fuzzer give us a // place to put it, so we don't have to resize the stack (and so that actual