Skip to content

Conversation

@nachog00
Copy link
Contributor

@nachog00 nachog00 commented Oct 17, 2025

Summary

Adds unit tests proving the Height type safety bugs described in #615.

Changes

  1. Extracted Height type to types/db/primitives/height.rs
  2. Added 5 unit tests proving the safety issues exist:
    • test_underflow_wraps_to_max_in_release - Proves Height(0) - 1 = Height(4,294,967,295)
    • test_underflow_panics_in_debug - Proves panic in debug mode
    • test_overflow_wraps_in_release - Proves Height(u32::MAX-10) + 20 = Height(9)
    • test_overflow_panics_in_debug - Proves panic on overflow
    • test_arithmetic_bypasses_validation - Proves arithmetic creates invalid Heights > MAX
  3. Updated module structure - primitives.rs exports Height and GENESIS_HEIGHT
  4. Updated legacy.rs to re-export from primitives

Tests

All 5 tests pass, proving the bugs are real:

# Release mode tests (3 tests - wraparound bugs)
$ cargo test --package zaino-state --lib types::db::primitives::height::height_safety_tests --release

running 3 tests
test test_arithmetic_bypasses_validation ... ok
test test_overflow_wraps_in_release ... ok
test test_underflow_wraps_to_max_in_release ... ok

test result: ok. 3 passed

# Debug mode tests (2 tests - panic bugs)
$ cargo test --package zaino-state --lib types::db::primitives::height::height_safety_tests

running 2 tests
test test_underflow_panics_in_debug - should panic ... ok
test test_overflow_panics_in_debug - should panic ... ok

test result: ok. 2 passed

Checklist

  • The PR name is suitable for the release notes.
  • The solution is tested (5 unit tests, all pass).
  • The documentation is up to date (N/A - tests document the bugs).

Related

Adds 5 unit tests that prove critical safety bugs in Zaino's Height type:

1. test_underflow_wraps_to_max_in_release - Proves Height(0) - 1 wraps to
   Height(4,294,967,295) in release mode. Documents real-world impact on
   reorg detection in non_finalised_state.rs:390.

2. test_underflow_panics_in_debug - Proves same operation panics in debug
   mode with 'attempt to subtract with overflow'.

3. test_overflow_wraps_in_release - Proves Height(u32::MAX - 10) + 20
   wraps to Height(9) instead of detecting overflow.

4. test_overflow_panics_in_debug - Proves addition overflow panics in
   debug mode.

5. test_arithmetic_bypasses_validation - Proves arithmetic operations can
   create Heights > MAX (2^31 - 1), bypassing TryFrom validation and
   breaking type invariants.

These tests demonstrate that business logic must manually check for edge
cases that should be enforced by the type system. Zebra's Height type
provides safe arithmetic (returns Option) that forces handling at compile
time, eliminating this class of bugs.

All tests pass, proving these are real bugs in production code.
Moves Height type and implementations from legacy.rs to dedicated module:
- Creates types/db/primitives/height.rs
- Adds 5 unit tests proving critical safety bugs in current implementation
- Updates primitives.rs to export Height and GENESIS_HEIGHT

Tests prove:
1. Underflow wraps to u32::MAX in release (Height(0) - 1 = Height(4294967295))
2. Underflow panics in debug mode
3. Overflow wraps in release (Height(u32::MAX-10) + 20 = Height(9))
4. Overflow panics in debug mode
5. Arithmetic bypasses TryFrom validation (can create Heights > MAX)

Real-world impact documented: non_finalised_state.rs:390 reorg detection bug
where unchecked subtraction causes silent failure instead of error.

This extraction prepares for future migration to safe arithmetic that returns
Option, matching Zebra's Height implementation.
@zancas
Copy link
Member

zancas commented Oct 20, 2025

Why is this still Draft?

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants