Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mini-spv-node

A lightweight, modular, and production-grade Bitcoin Simplified Payment Verification (SPV) header validation engine written in Rust. This library implements the core consensus rules for validating Bitcoin block headers, tracking chain state, and resolving forks based on cumulative proof-of-work.

Architecture

The system is designed as a standalone validation engine, decoupled from networking and persistent storage logic.

+---------------------+       +----------------------+
|     BlockHeader     |       |     HeaderChain      |
|---------------------|       |----------------------|
| - version           | <---- | - headers (HashMap)  |
| - prev_block_hash   |       | - best_tip           |
| - merkle_root       |       |                      |
| - timestamp         |       +----------+-----------+
| - bits (difficulty) |                  |
| - nonce             |                  v
+----------+----------+       +----------------------+
           |                  | Consensus Validation |
           +----------------> | - Proof-of-Work      |
                              | - Difficulty Target  |
                              | - Chain Linking      |
                              +----------------------+

Consensus Logic

Cumulative Work vs. Block Count

Bitcoin uses the "Heaviest Chain" rule, not the "Longest Chain" rule. While often synonymous, a shorter chain with significantly higher difficulty can override a longer chain with lower difficulty. This implementation calculates work for each block as: Work = 2^256 / (Target + 1)

The HeaderChain tracks the cumulative work of every valid header and atomically updates the chain tip only when a new candidate chain exceeds the total work of the current best chain.

Compact Difficulty

Bitcoin encodes the 256-bit target threshold into a 32-bit integer ("bits").

  • Exponent: Top 8 bits (bits >> 24).
  • Mantissa: Bottom 23 bits (bits & 0x7fffff). Target = Mantissa * 256^(Exponent - 3)

Usage

Build and Run

# Build the project
cargo build --release

# Run unit tests
cargo test

Example: Header Validation

use mini_spv_node::{BlockHeader, crypto::double_sha256};
use hex;

fn main() {
    // Bitcoin Testnet Genesis Header
    let raw_header = "0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff001d1aa4ae18";
    let bytes = hex::decode(raw_header).expect("Invalid hex");

    match BlockHeader::from_bytes(&bytes) {
        Ok(header) => {
            if header.validate_pow() {
                println!("Valid Block: {}", hex::encode(header.hash()));
            } else {
                eprintln!("Invalid Proof-of-Work");
            }
        }
        Err(e) => eprintln!("Parse Error: {}", e),
    }
}

Design Decisions

  • Rust: Chosen for memory safety guarantees without a garbage collector, essential for low-level consensus code where performance and correctness are critical.
  • num-bigint: Used for arbitrary-precision arithmetic required for work calculations (2^256), avoiding overflow issues present in standard primitives.
  • Strict Serialization: The engine enforces the legacy 80-byte header format. Any deviation constitutes a consensus failure.

Testing Strategy

The test suite relies on known vectors from the Bitcoin Testnet blockchain to ensure compliance with the actual network rules.

  • Genesis Validation: Verifies strict binary parsing and hashing against the genesis block.
  • Fork Resolution: Simulates competitive fork scenarios to verify the Cumulative Work implementation correctly prioritizes "heavier" chains over "longer" ones.
  • Orphan Detection: Ensures headers without a known parent are rejected immediately.

Security Assumptions of SPV

SPV nodes verify block headers but do not validate transactions. They operate under the following assumptions:

  1. Honest Majority: The chain with the most cumulative work is generated by an honest majority of miners.
  2. Cost of Attack: Forging a block header requires expending real-world energy (Proof-of-Work), making it computationally expensive to spoof the chain history.
  3. Data Availability: An SPV node assumes that if a block header is valid, the underlying transaction data exists and is available from full nodes.

Future Work

  • P2P Networking: Implement the Bitcoin wire protocol to download headers from peers.
  • Merkle Proof Verification: Add validation for transaction inclusion proofs (SPV proofs).
  • Persistent Storage: Integrate a database (e.g., SQLite or LevelDB) for storing the header chain on disk.

About

Rust implementation of a Bitcoin SPV header validation engine with PoW verification, cumulative work tracking, and fork resolution.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages