From 734d2811a9919ae954cb7d2bf640e39a3245f06c Mon Sep 17 00:00:00 2001 From: sedited Date: Fri, 22 May 2026 22:51:28 +0200 Subject: [PATCH 1/3] kernel: Generate a signet with a challenge --- .../bitcoin/src/kernel/bitcoinkernel.cpp | 10 ++++++++++ .../bitcoin/src/kernel/bitcoinkernel.h | 11 +++++++++++ .../bitcoin/src/kernel/bitcoinkernel_wrapper.h | 3 +++ .../bitcoin/src/test/kernel/test_kernel.cpp | 7 +++++++ 4 files changed, 31 insertions(+) diff --git a/libbitcoinkernel-sys/bitcoin/src/kernel/bitcoinkernel.cpp b/libbitcoinkernel-sys/bitcoin/src/kernel/bitcoinkernel.cpp index f21ea041..58f55d6e 100644 --- a/libbitcoinkernel-sys/bitcoin/src/kernel/bitcoinkernel.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/kernel/bitcoinkernel.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -823,6 +824,15 @@ btck_ChainParameters* btck_chain_parameters_create(const btck_ChainType chain_ty assert(false); } +btck_ChainParameters* btck_chain_parameters_create_signet(const void* challenge, size_t challenge_len) +{ + const uint8_t* p = static_cast(challenge); + CChainParams::SigNetOptions options{ + .challenge = std::vector{p, p + challenge_len}, + }; + return btck_ChainParameters::ref(const_cast(CChainParams::SigNet(options).release())); +} + btck_ChainParameters* btck_chain_parameters_copy(const btck_ChainParameters* chain_parameters) { return btck_ChainParameters::copy(chain_parameters); diff --git a/libbitcoinkernel-sys/bitcoin/src/kernel/bitcoinkernel.h b/libbitcoinkernel-sys/bitcoin/src/kernel/bitcoinkernel.h index d3028729..caad5f21 100644 --- a/libbitcoinkernel-sys/bitcoin/src/kernel/bitcoinkernel.h +++ b/libbitcoinkernel-sys/bitcoin/src/kernel/bitcoinkernel.h @@ -869,6 +869,17 @@ BITCOINKERNEL_API void btck_logging_connection_destroy(btck_LoggingConnection* l BITCOINKERNEL_API btck_ChainParameters* BITCOINKERNEL_WARN_UNUSED_RESULT btck_chain_parameters_create( btck_ChainType chain_type); +/** + * @brief Create a signet chain parameters struct with a user-provided + * challenge. + * + * @param[in] challenge The signet challenge value. Blocks must satisfy it in + * order to be valid. + * @return An allocated chain parameters opaque struct. + */ +BITCOINKERNEL_API btck_ChainParameters* BITCOINKERNEL_WARN_UNUSED_RESULT btck_chain_parameters_create_signet( + const void* challenge, size_t challenge_len) BITCOINKERNEL_ARG_NONNULL(1); + /** * Copy the chain parameters. */ diff --git a/libbitcoinkernel-sys/bitcoin/src/kernel/bitcoinkernel_wrapper.h b/libbitcoinkernel-sys/bitcoin/src/kernel/bitcoinkernel_wrapper.h index 2be5e223..bc1f7b3b 100644 --- a/libbitcoinkernel-sys/bitcoin/src/kernel/bitcoinkernel_wrapper.h +++ b/libbitcoinkernel-sys/bitcoin/src/kernel/bitcoinkernel_wrapper.h @@ -1019,6 +1019,9 @@ class ChainParams : public Handle(chain_type))} {} + ChainParams(std::span signet_challenge) + : Handle{btck_chain_parameters_create_signet(signet_challenge.data(), signet_challenge.size())} {} + ConsensusParamsView GetConsensusParams() const { return ConsensusParamsView{btck_chain_parameters_get_consensus_params(get())}; diff --git a/libbitcoinkernel-sys/bitcoin/src/test/kernel/test_kernel.cpp b/libbitcoinkernel-sys/bitcoin/src/test/kernel/test_kernel.cpp index 97b0b91f..1c5a4a82 100644 --- a/libbitcoinkernel-sys/bitcoin/src/test/kernel/test_kernel.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/test/kernel/test_kernel.cpp @@ -651,6 +651,13 @@ BOOST_AUTO_TEST_CASE(logging_tests) Logger logger{std::make_unique()}; } +BOOST_AUTO_TEST_CASE(btck_chainparams_tests) +{ + ChainParams params_regtest{ChainType::REGTEST}; + ChainParams params_signet{hex_string_to_byte_vec("51")}; + CheckHandle(params_regtest, params_signet); +} + BOOST_AUTO_TEST_CASE(btck_context_tests) { { // test default context From c77bf343762d6d2e5874f5afd59e01fea778d836 Mon Sep 17 00:00:00 2001 From: sedited Date: Fri, 22 May 2026 22:52:15 +0200 Subject: [PATCH 2/3] test kernel: Don't log on warnings change --- libbitcoinkernel-sys/bitcoin/src/test/kernel/test_kernel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libbitcoinkernel-sys/bitcoin/src/test/kernel/test_kernel.cpp b/libbitcoinkernel-sys/bitcoin/src/test/kernel/test_kernel.cpp index 1c5a4a82..15f8102b 100644 --- a/libbitcoinkernel-sys/bitcoin/src/test/kernel/test_kernel.cpp +++ b/libbitcoinkernel-sys/bitcoin/src/test/kernel/test_kernel.cpp @@ -122,12 +122,12 @@ class TestKernelNotifications : public KernelNotifications void WarningSetHandler(Warning warning, std::string_view message) override { - std::cout << "Kernel warning is set: " << message << std::endl; + BOOST_FAIL("Received unexpected warning"); } void WarningUnsetHandler(Warning warning) override { - std::cout << "Kernel warning was unset." << std::endl; + BOOST_CHECK_EQUAL(Warning::LARGE_WORK_INVALID_CHAIN, warning); } void FlushErrorHandler(std::string_view error) override From 58820021f43b592e20c450edbf3aac4b57449329 Mon Sep 17 00:00:00 2001 From: Leonardo Lima Date: Fri, 5 Jun 2026 10:29:41 -0300 Subject: [PATCH 3/3] feat: add custom signet support - bind btck_chain_parameters_create_signet in libbitcoinkernel-sys - add ChainParams::new_signet and ContextBuilder::signet - add tests for both paths Co-Authored-By: Davidson-Souza Co-Authored-By: Johnny Santos Co-Authored-By: Claude Opus 4.8 --- CHANGELOG.md | 1 + libbitcoinkernel-sys/CHANGELOG.md | 3 ++ libbitcoinkernel-sys/src/lib.rs | 5 ++ src/state/context.rs | 78 +++++++++++++++++++++++++++++-- 4 files changed, 83 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f189b60b..2e2ab4ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Implemented `Debug` for `BlockValidationResult`, `BlockValidationStateRef`, `ProcessBlockHeaderresult` and `BlockCheckResult`, enabling inspection via `{:?}` in logs and test output. - Added `#[must_use]` to `BlockCheckResult` and `ProcessBlockHeaderResult` to warn when validation results are silently ignored. - Added `ScriptPubkeyExt::as_bytes` to return a zero-copy slice into kernel-managed memory. Unlike `to_bytes`, this does not allocate. +- Added `ChainParams::new_signet` and `ContextBuilder::signet` to configure a custom signet from a user-provided challenge. ### Changed - The `verify` function's `flags` parameter now uses `ScriptVerificationFlags` instead of `u32`, making the type explicit in the public API. diff --git a/libbitcoinkernel-sys/CHANGELOG.md b/libbitcoinkernel-sys/CHANGELOG.md index 7366bad9..f4eeee52 100644 --- a/libbitcoinkernel-sys/CHANGELOG.md +++ b/libbitcoinkernel-sys/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added +- New `btck_chain_parameters_create_signet` for creating chain parameters for a custom signet from a user-provided challenge. + ## [0.3.0] - 2026-05-20 ### Added diff --git a/libbitcoinkernel-sys/src/lib.rs b/libbitcoinkernel-sys/src/lib.rs index cb964184..29d0da6b 100644 --- a/libbitcoinkernel-sys/src/lib.rs +++ b/libbitcoinkernel-sys/src/lib.rs @@ -486,6 +486,11 @@ extern "C" { pub fn btck_chain_parameters_create(chain_type: btck_ChainType) -> *mut btck_ChainParameters; + pub fn btck_chain_parameters_create_signet( + challenge: *const c_void, + challenge_len: usize, + ) -> *mut btck_ChainParameters; + pub fn btck_chain_parameters_copy( chain_parameters: *const btck_ChainParameters, ) -> *mut btck_ChainParameters; diff --git a/src/state/context.rs b/src/state/context.rs index 2014c7e5..88f42e95 100644 --- a/src/state/context.rs +++ b/src/state/context.rs @@ -59,10 +59,11 @@ use libbitcoinkernel_sys::{ btck_ChainParameters, btck_ChainType, btck_ChainType_MAINNET, btck_ChainType_REGTEST, btck_ChainType_SIGNET, btck_ChainType_TESTNET, btck_ChainType_TESTNET_4, btck_Context, btck_ContextOptions, btck_NotificationInterfaceCallbacks, btck_ValidationInterfaceCallbacks, - btck_chain_parameters_create, btck_chain_parameters_destroy, btck_context_create, - btck_context_destroy, btck_context_interrupt, btck_context_options_create, - btck_context_options_destroy, btck_context_options_set_chainparams, - btck_context_options_set_notifications, btck_context_options_set_validation_interface, + btck_chain_parameters_create, btck_chain_parameters_create_signet, + btck_chain_parameters_destroy, btck_context_create, btck_context_destroy, + btck_context_interrupt, btck_context_options_create, btck_context_options_destroy, + btck_context_options_set_chainparams, btck_context_options_set_notifications, + btck_context_options_set_validation_interface, }; use crate::{ @@ -133,6 +134,35 @@ impl ChainParams { inner: unsafe { btck_chain_parameters_create(btck_chain_type) }, } } + + /// Creates chain parameters for a custom signet with a user-provided challenge. + /// + /// The signet challenge is the script that blocks must satisfy in order to be + /// considered valid, allowing private signets with their own block signers. + /// + /// # Arguments + /// * `challenge` - The signet challenge value (a serialized script). + /// + /// # Returns + /// A new [`ChainParams`] instance configured for the custom signet. + /// + /// # Example + /// ```no_run + /// use bitcoinkernel::ChainParams; + /// + /// let challenge = [0x51]; // OP_TRUE + /// let params = ChainParams::new_signet(&challenge); + /// ``` + pub fn new_signet(challenge: &[u8]) -> ChainParams { + ChainParams { + inner: unsafe { + btck_chain_parameters_create_signet( + challenge.as_ptr() as *const c_void, + challenge.len(), + ) + }, + } + } } impl Drop for ChainParams { @@ -456,6 +486,33 @@ impl ContextBuilder { self } + /// Configures the context for a custom signet. + /// + /// Sets the chain parameters to a signet defined by the given challenge, + /// the script that blocks must satisfy in order to be considered valid. + /// + /// # Arguments + /// * `challenge` - The signet challenge value (a serialized script). + /// + /// # Returns + /// The builder instance for method chaining. + /// + /// # Example + /// ```no_run + /// use bitcoinkernel::{ContextBuilder, KernelError}; + /// + /// let challenge = [0x51]; // OP_TRUE + /// let context = ContextBuilder::new() + /// .signet(&challenge) + /// .build()?; + /// # Ok::<(), KernelError>(()) + /// ``` + pub fn signet(self, challenge: &[u8]) -> ContextBuilder { + let chain_params = ChainParams::new_signet(challenge); + unsafe { btck_context_options_set_chainparams(self.inner, chain_params.inner) }; + self + } + /// Registers a callback for block tip notifications. /// /// The callback is invoked when the chain's tip is updated to a new block. @@ -1099,6 +1156,12 @@ mod tests { let _regtest_params = ChainParams::new(ChainType::Regtest); } + #[test] + fn test_signet_params_creation() { + // OP_TRUE challenge - blocks are trivially valid. + let _params = ChainParams::new_signet(&[0x51]); + } + // Context tests #[test] fn test_context_creation_default() { @@ -1130,6 +1193,13 @@ mod tests { assert!(regtest.is_ok()); } + #[test] + fn test_context_creation_with_signet() { + // OP_TRUE challenge - blocks are trivially valid. + let signet = ContextBuilder::new().signet(&[0x51]).build(); + assert!(signet.is_ok()); + } + #[test] fn test_context_interrupt() { let context = ContextBuilder::new()