diff --git a/src/lib.cairo b/src/lib.cairo index 962ed1da..201712a7 100644 --- a/src/lib.cairo +++ b/src/lib.cairo @@ -1,5 +1,6 @@ -mod utils; +pub mod utils; pub mod validation; + mod state; mod main; mod merkle_tree; diff --git a/src/validation.cairo b/src/validation.cairo index 177eae3b..c9c58717 100644 --- a/src/validation.cairo +++ b/src/validation.cairo @@ -1,5 +1,5 @@ use super::merkle_tree::merkle_root; -use super::utils::{shl, shr, double_sha256}; +use super::utils::{shl, shr}; use super::state::{Block, ChainState, Transaction, UtreexoState}; const MAX_TARGET: u256 = 0x00000000FFFF0000000000000000000000000000000000000000000000000000; @@ -102,6 +102,46 @@ fn adjust_difficulty(self: @ChainState, block: @Block) -> (u32, u32) { (*self.current_target, *self.epoch_start_time) } +fn validate_merkle_root(self: @ChainState, block: @Block) -> Result<(), ByteArray> { + // TODO: implement + Result::Ok(()) +} + +// Helper functions +pub fn bits_to_target(bits: u32) -> Result { + // Extract exponent and mantissa + let exponent: u32 = (bits / 0x1000000); + let mantissa: u32 = bits & 0x00FFFFFF; + + // Check if mantissa is valid (should be less than 0x1000000) + if mantissa > 0x7FFFFF && exponent != 0 { + return Result::Err('Invalid mantissa'); + } + + // Calculate the full target value + let mut target: u256 = mantissa.into(); + + if exponent == 0 { + // Special case: exponent 0 means we use the mantissa as-is + return Result::Ok(target); + } else if exponent <= 3 { + // For exponents 1, 2, and 3, divide by 256^(3 - exponent) i.e right shift + let shift = 8 * (3 - exponent); + target = shr(target, shift); + } else { + let shift = 8 * (exponent - 3); + target = shl(target, shift); + } + + // Ensure the target doesn't exceed the maximum allowed value + if target > MAX_TARGET { + return Result::Err('Target exceeds maximum'); + } + + Result::Ok(target) +} + + pub fn target_to_bits(target: u256) -> Result { if target == 0 { return Result::Err('Target is zero'); diff --git a/tests/tests.cairo b/tests/tests.cairo index 0646d0a5..c7e52cb8 100644 --- a/tests/tests.cairo +++ b/tests/tests.cairo @@ -1,5 +1,81 @@ +use raito::validation::bits_to_target; use raito::validation::target_to_bits; +#[test] +fn test_bits_to_target_01003456() { + let result = bits_to_target(0x01003456); + assert!(result.is_ok(), "Should be valid"); + assert!(result.unwrap() == 0x00_u256, "Incorrect target for 0x01003456"); +} + +#[test] +fn test_bits_to_target_01123456() { + let result = bits_to_target(0x01123456); + assert!(result.is_ok(), "Should be valid"); + assert!(result.unwrap() == 0x12_u256, "Incorrect target for 0x01123456"); +} + +#[test] +fn test_bits_to_target_02008000() { + let result = bits_to_target(0x02008000); + assert!(result.is_ok(), "Should be valid"); + assert!(result.unwrap() == 0x80_u256, "Incorrect target for 0x02008000"); +} + +#[test] +fn test_bits_to_target_181bc330() { + let result = bits_to_target(0x181bc330); + assert!(result.is_ok(), "Should be valid"); + assert!( + result.unwrap() == 0x1bc330000000000000000000000000000000000000000000_u256, + "Incorrect target for 0x181bc330" + ); +} + +#[test] +fn test_bits_to_target_05009234() { + let result = bits_to_target(0x05009234); + assert!(result.is_ok(), "Should be valid"); + assert!(result.unwrap() == 0x92340000_u256, "Incorrect target for 0x05009234"); +} + +#[test] +fn test_bits_to_target_04123456() { + let result = bits_to_target(0x04123456); + assert!(result.is_ok(), "Should be valid"); + assert!(result.unwrap() == 0x12345600_u256, "Incorrect target for 0x04123456"); +} + +#[test] +fn test_bits_to_target_1d00ffff() { + let result = bits_to_target(0x1d00ffff); + assert!(result.is_ok(), "Should be valid"); + assert!( + result.unwrap() == 0x00000000ffff0000000000000000000000000000000000000000000000000000_u256, + "Incorrect target for 0x1d00ffff" + ); +} + +#[test] +fn test_bits_to_target_1c0d3142() { + let result = bits_to_target(0x1c0d3142); + assert!(result.is_ok(), "Should be valid"); + assert!( + result.unwrap() == 0x000000000d314200000000000000000000000000000000000000000000000000_u256, + "Incorrect target for 0x1c0d3142" + ); +} + +#[test] +fn test_bits_to_target_1707a429() { + let result = bits_to_target(0x1707a429); + assert!(result.is_ok(), "Should be valid"); + assert!( + result.unwrap() == 0x00000000000000000007a4290000000000000000000000000000000000000000_u256, + "Incorrect target for 0x1707a429" + ); +} + #[test] fn test_target_to_bits_large_target() { let target: u256 = 0x1bc330000000000000000000000000000000000000000000;