|
| 1 | +//! # rust-bitcoinkernel |
| 2 | +//! |
| 3 | +//! Rust bindings for the `libbitcoinkernel` library, providing safe and idiomatic |
| 4 | +//! access to Bitcoin's consensus engine and validation logic. |
| 5 | +//! |
| 6 | +//! ## Overview |
| 7 | +//! |
| 8 | +//! This crate enables Rust applications to leverage Bitcoin Core's consensus implementation. |
| 9 | +//! It provides type-safe wrappers around the C API exposed by `libbitcoinkernel`. |
| 10 | +//! |
| 11 | +//! ## Key Features |
| 12 | +//! |
| 13 | +//! - **Block Processing**: Process and validate blocks against consensus rules |
| 14 | +//! - **Script Verification**: Validate transaction scripts |
| 15 | +//! - **Chain Queries**: Traverse the chain and read block data |
| 16 | +//! - **Event Notifications**: Subscribe to block validation, tip updates, and error events |
| 17 | +//! - **Memory Safety**: FFI interactions are wrapped in safe Rust abstractions |
| 18 | +//! |
| 19 | +//! ## Architecture |
| 20 | +//! |
| 21 | +//! The crate is organized into several modules: |
| 22 | +//! |
| 23 | +//! - [`core`]: Core Bitcoin primitives (blocks, transactions, scripts) |
| 24 | +//! - [`state`]: Chain state management (chainstate, context, chain parameters) |
| 25 | +//! - [`notifications`]: Event callbacks for validation and synchronization events |
| 26 | +//! - [`log`]: Logging integration with Bitcoin Core's logging system |
| 27 | +//! - [`prelude`]: Commonly used extension traits for ergonomic API access |
| 28 | +//! |
| 29 | +//! ## Quick Start |
| 30 | +//! |
| 31 | +//! ### Basic Block Validation |
| 32 | +//! |
| 33 | +//! ```no_run |
| 34 | +//! use bitcoinkernel::{ |
| 35 | +//! Block, ContextBuilder, ChainType, ChainstateManager, |
| 36 | +//! KernelError, ProcessBlockResult |
| 37 | +//! }; |
| 38 | +//! |
| 39 | +//! // Create a context for mainnet |
| 40 | +//! let context = ContextBuilder::new() |
| 41 | +//! .chain_type(ChainType::Mainnet) |
| 42 | +//! .build()?; |
| 43 | +//! |
| 44 | +//! // Initialize chainstate manager |
| 45 | +//! let chainman = ChainstateManager::new(&context, "/path/to/data", "path/to/blocks/")?; |
| 46 | +//! |
| 47 | +//! // Process a block |
| 48 | +//! let block_data = vec![0u8; 100]; // placeholder |
| 49 | +//! let block = Block::new(&block_data)?; |
| 50 | +//! |
| 51 | +//! match chainman.process_block(&block) { |
| 52 | +//! ProcessBlockResult::NewBlock => println!("Block validated and written to disk"), |
| 53 | +//! ProcessBlockResult::Duplicate => println!("Block already known (valid)"), |
| 54 | +//! ProcessBlockResult::Rejected => println!("Block validation failed"), |
| 55 | +//! } |
| 56 | +//! |
| 57 | +//! # Ok::<(), KernelError>(()) |
| 58 | +//! ``` |
| 59 | +//! |
| 60 | +//! ### Script Verification |
| 61 | +//! |
| 62 | +//! ```no_run |
| 63 | +//! use bitcoinkernel::{prelude::*, Transaction, verify, VERIFY_ALL}; |
| 64 | +//! let spending_tx_bytes = vec![]; // placeholder |
| 65 | +//! let prev_tx_bytes = vec![]; // placeholder |
| 66 | +//! let spending_tx = Transaction::new(&spending_tx_bytes).unwrap(); |
| 67 | +//! let prev_tx = Transaction::new(&prev_tx_bytes).unwrap(); |
| 68 | +//! let prev_output = prev_tx.output(0).unwrap(); |
| 69 | +//! |
| 70 | +//! let result = verify( |
| 71 | +//! &prev_output.script_pubkey(), |
| 72 | +//! Some(prev_output.value()), |
| 73 | +//! &spending_tx, |
| 74 | +//! 0, |
| 75 | +//! Some(VERIFY_ALL), |
| 76 | +//! &[prev_output], |
| 77 | +//! ); |
| 78 | +//! |
| 79 | +//! match result { |
| 80 | +//! Ok(()) => println!("Script verification passed"), |
| 81 | +//! Err(e) => println!("Script verification failed: {}", e), |
| 82 | +//! } |
| 83 | +//! ``` |
| 84 | +//! |
| 85 | +//! ### Event Notifications |
| 86 | +//! |
| 87 | +//! ```no_run |
| 88 | +//! use bitcoinkernel::{ |
| 89 | +//! Block, BlockValidationStateRef, ChainType, ContextBuilder, KernelError, |
| 90 | +//! ValidationCallbackRegistry, |
| 91 | +//! }; |
| 92 | +//! |
| 93 | +//! let context = ContextBuilder::new() |
| 94 | +//! .chain_type(ChainType::Mainnet) |
| 95 | +//! .notifications(|registry| { |
| 96 | +//! registry.register_progress(|title, percent, _resume| { |
| 97 | +//! println!("{}: {}%", title, percent); |
| 98 | +//! }); |
| 99 | +//! registry.register_warning_set(|warning, message| { |
| 100 | +//! eprintln!("Warning: {} - {}", warning, message); |
| 101 | +//! }); |
| 102 | +//! registry.register_flush_error(|message| { |
| 103 | +//! eprintln!("Flush error: {}", message); |
| 104 | +//! // Consider tearing down context and terminating operations |
| 105 | +//! }); |
| 106 | +//! registry.register_fatal_error(|message| { |
| 107 | +//! eprintln!("FATAL: {}", message); |
| 108 | +//! // Tear down context and terminate all operations |
| 109 | +//! std::process::exit(1); |
| 110 | +//! }); |
| 111 | +//! }) |
| 112 | +//! .validation(|registry| { |
| 113 | +//! registry.register_block_checked(|block: Block, _state: BlockValidationStateRef<'_>| { |
| 114 | +//! println!("Checked block: {}", block.hash()); |
| 115 | +//! }); |
| 116 | +//! }) |
| 117 | +//! .build()?; |
| 118 | +//! # Ok::<(), KernelError>(()) |
| 119 | +//! ``` |
| 120 | +//! |
| 121 | +//! **Note**: System-level errors are surfaced through [`FatalErrorCallback`] and |
| 122 | +//! [`FlushErrorCallback`]. When encountering either error type, it is recommended to |
| 123 | +//! tear down the [`Context`] and terminate any running tasks using the [`ChainstateManager`]. |
| 124 | +//! |
| 125 | +//! ### Chain Traversal |
| 126 | +//! |
| 127 | +//! ```no_run |
| 128 | +//! use bitcoinkernel::{ContextBuilder, ChainType, ChainstateManager, KernelError}; |
| 129 | +//! |
| 130 | +//! // Create a context for mainnet |
| 131 | +//! let context = ContextBuilder::new() |
| 132 | +//! .chain_type(ChainType::Mainnet) |
| 133 | +//! .build()?; |
| 134 | +//! |
| 135 | +//! // Initialize chainstate manager |
| 136 | +//! let chainman = ChainstateManager::new(&context, "path/to/data", "path/to/blocks")?; |
| 137 | +//! |
| 138 | +//! chainman.import_blocks()?; |
| 139 | +//! |
| 140 | +//! // Get the active chain |
| 141 | +//! let chain = chainman.active_chain(); |
| 142 | +//! |
| 143 | +//! // Traverse the chain |
| 144 | +//! for entry in chain.iter() { |
| 145 | +//! println!("Block hash {} at height {}", entry.block_hash(), entry.height()); |
| 146 | +//! } |
| 147 | +//! # Ok::<(), KernelError>(()) |
| 148 | +//! ``` |
| 149 | +//! |
| 150 | +//! ## Type System |
| 151 | +//! |
| 152 | +//! The crate uses owned and borrowed types extensively: |
| 153 | +//! |
| 154 | +//! - **Owned types** (e.g., `Block`, `Transaction`): Manage C memory lifecycle |
| 155 | +//! - **Borrowed types** (e.g., `BlockRef`, `TransactionRef`): Zero-copy views into data |
| 156 | +//! - **Extension traits**: Provide ergonomic methods (use `prelude::*` to import) |
| 157 | +//! |
| 158 | +//! ## Error Handling |
| 159 | +//! |
| 160 | +//! The crate provides multiple layers of error handling: |
| 161 | +//! |
| 162 | +//! - **Operation Errors**: Standard [`KernelError`] results for validation failures, |
| 163 | +//! serialization errors, and internal library errors |
| 164 | +//! - **System Errors**: Critical failures are reported through notification callbacks: |
| 165 | +//! - [`FatalErrorCallback`]: Unrecoverable system errors requiring immediate shutdown |
| 166 | +//! - [`FlushErrorCallback`]: Disk I/O errors during state persistence |
| 167 | +//! |
| 168 | +//! When encountering fatal or flush errors through these callbacks, applications should |
| 169 | +//! tear down the [`Context`] and terminate any operations using the [`ChainstateManager`]. |
| 170 | +//! |
| 171 | +//! ## Minimum Supported Rust Version (MSRV) |
| 172 | +//! |
| 173 | +//! This crate requires Rust 1.71.0 or later. |
| 174 | +//! |
| 175 | +//! ## Examples |
| 176 | +//! |
| 177 | +//! See the `examples/` directory for complete working examples including: |
| 178 | +//! |
| 179 | +//! - Silent Payment Scanning |
| 180 | +
|
1 | 181 | #![allow(non_upper_case_globals)] |
2 | 182 | #![allow(non_camel_case_types)] |
3 | 183 | #![allow(non_snake_case)] |
|
0 commit comments