Skip to content

Commit 9f89611

Browse files
feat(core): implement Debug for BlockValidationState and related types
Implements Debug for BlockValidationState, BlockValidationStateRef, ProcessBlockHeaderResult and BlockCheckResult. Also derives Clone for BlockCheckResult for consistency with ProcessBlockHeaderResult.
1 parent e22be3a commit 9f89611

4 files changed

Lines changed: 93 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111
- Added `Block::check` to perform context-free validation of a block (size, weight, coinbase, transactions, sigops), with optional proof-of-work and merkle-root checks toggled via the `BLOCK_CHECK_BASE` / `_POW` / `_MERKLE` / `_ALL` flags. Returns a `BlockCheckResult` enum carrying the validation state on failure.
12+
- Implemented `Debug` for `BlockValidationResult`, `BlockValidationStateRef`, `ProcessBlockHeaderresult` and `BlockCheckResult`, enabling inspection via `{:?}` in logs and test output.
1213

1314
### Changed
1415
- The `verify` function's `flags` parameter now uses `ScriptVerificationFlags` instead of `u32`, making the type explicit in the public API.

src/core/block.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ pub const BLOCK_CHECK_ALL: BlockCheckFlags = btck_BlockCheckFlags_ALL;
176176
///
177177
/// On failure, the [`BlockValidationState`] carries details that can be
178178
/// inspected via [`BlockValidationStateExt`](crate::notifications::BlockValidationStateExt).
179+
#[derive(Clone, Debug)]
179180
pub enum BlockCheckResult {
180181
/// The block passed the requested context-free checks.
181182
Valid,
@@ -2347,6 +2348,29 @@ mod tests {
23472348
"00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"
23482349
);
23492350
}
2351+
#[test]
2352+
fn test_block_check_result_debug() {
2353+
let valid = BlockCheckResult::Valid;
2354+
let debug_str = format!("{:?}", valid);
2355+
assert_eq!(debug_str, "Valid");
2356+
2357+
let state = BlockValidationState::new();
2358+
let invalid = BlockCheckResult::Invalid(state);
2359+
let debug_str = format!("{:?}", invalid);
2360+
assert!(debug_str.contains("Invalid"));
2361+
}
2362+
2363+
#[test]
2364+
fn test_block_check_result_clone() {
2365+
let valid = BlockCheckResult::Valid;
2366+
let cloned = valid.clone();
2367+
assert!(matches!(cloned, BlockCheckResult::Valid));
2368+
2369+
let state = BlockValidationState::new();
2370+
let invalid = BlockCheckResult::Invalid(state);
2371+
let cloned = invalid.clone();
2372+
assert!(matches!(cloned, BlockCheckResult::Invalid(_)));
2373+
}
23502374

23512375
#[test]
23522376
fn check_valid_block_passes_base_and_all() {

src/notifications/types.rs

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use std::marker::PhantomData;
1+
use std::{
2+
fmt::{Debug, Formatter, Result},
3+
marker::PhantomData,
4+
};
25

36
use libbitcoinkernel_sys::{
47
btck_BlockValidationResult, btck_BlockValidationResult_CACHED_INVALID,
@@ -230,6 +233,15 @@ impl FromMutPtr<btck_BlockValidationState> for BlockValidationState {
230233

231234
impl BlockValidationStateExt for BlockValidationState {}
232235

236+
impl Debug for BlockValidationState {
237+
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
238+
f.debug_struct("BlockValidationState")
239+
.field("mode", &self.mode())
240+
.field("result", &self.result())
241+
.finish()
242+
}
243+
}
244+
233245
impl Clone for BlockValidationState {
234246
fn clone(&self) -> Self {
235247
BlockValidationState {
@@ -275,6 +287,15 @@ impl<'a> Clone for BlockValidationStateRef<'a> {
275287
}
276288
}
277289

290+
impl<'a> Debug for BlockValidationStateRef<'a> {
291+
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
292+
f.debug_struct("BlockValidationStateRef")
293+
.field("mode", &self.mode())
294+
.field("result", &self.result())
295+
.finish()
296+
}
297+
}
298+
278299
impl<'a> BlockValidationStateExt for BlockValidationStateRef<'a> {}
279300

280301
#[cfg(test)]
@@ -621,4 +642,25 @@ mod tests {
621642
assert_eq!(result, back);
622643
}
623644
}
645+
646+
#[test]
647+
fn test_block_validation_state_debug() {
648+
let state = BlockValidationState::new();
649+
let s = format!("{:?}", state);
650+
assert!(s.contains("BlockValidationState"));
651+
assert!(s.contains("mode"));
652+
assert!(s.contains("result"));
653+
}
654+
655+
#[test]
656+
fn test_block_validation_state_ref_debug() {
657+
use crate::ffi::sealed::FromPtr;
658+
let state = BlockValidationState::new();
659+
let state_ref: BlockValidationStateRef<'_> =
660+
unsafe { BlockValidationStateRef::from_ptr(state.as_ptr()) };
661+
let s = format!("{:?}", state_ref);
662+
assert!(s.contains("BlockValidationStateRef"));
663+
assert!(s.contains("mode"));
664+
assert!(s.contains("result"));
665+
}
624666
}

src/state/chainstate.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ pub enum ProcessBlockResult {
7373
/// Result of proceesing a header with the [`ChainstateManager`]
7474
///
7575
/// Indicates whether a block header was processed, or rejected, and whether it is valid.
76-
#[derive(Clone)]
76+
#[derive(Clone, Debug)]
7777
pub enum ProcessBlockHeaderResult {
7878
/// Header was succssfully processed and added to the block tree
7979
Success(BlockValidationState),
@@ -817,4 +817,28 @@ mod tests {
817817
let debug_str = format!("{:?}", result);
818818
assert_eq!(debug_str, "NewBlock");
819819
}
820+
821+
#[test]
822+
fn test_process_block_header_result_debug() {
823+
let state = BlockValidationState::new();
824+
let success = ProcessBlockHeaderResult::Success(state.clone());
825+
let debug_str = format!("{:?}", success);
826+
assert!(debug_str.contains("Success"));
827+
828+
let failed = ProcessBlockHeaderResult::Failed(state);
829+
let debug_str = format!("{:?}", failed);
830+
assert!(debug_str.contains("Failed"));
831+
}
832+
833+
#[test]
834+
fn test_process_block_header_result_clone() {
835+
let state = BlockValidationState::new();
836+
let success = ProcessBlockHeaderResult::Success(state.clone());
837+
let cloned = success.clone();
838+
assert!(matches!(cloned, ProcessBlockHeaderResult::Success(_)));
839+
840+
let failed = ProcessBlockHeaderResult::Failed(state);
841+
let cloned = failed.clone();
842+
assert!(matches!(cloned, ProcessBlockHeaderResult::Failed(_)));
843+
}
820844
}

0 commit comments

Comments
 (0)