diff --git a/Scarb.toml b/Scarb.toml index 1bb5fb6c..461ae188 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -4,3 +4,6 @@ version = "0.1.0" edition = "2023_11" [dependencies] + +[dev-dependencies] +cairo_test = "2.7.0" \ No newline at end of file diff --git a/src/state.cairo b/src/state.cairo index b1a75261..c69d15b6 100644 --- a/src/state.cairo +++ b/src/state.cairo @@ -31,7 +31,7 @@ pub struct Block { /// Block header /// https://developer.bitcoin.org/reference/block_chain.html#block-headers #[derive(Drop, Copy)] -struct Header { +pub struct Header { /// The version of the block. pub version: u32, /// The hash of the previous block in the blockchain. diff --git a/src/validation.cairo b/src/validation.cairo index 1071898f..478c8e71 100644 --- a/src/validation.cairo +++ b/src/validation.cairo @@ -35,8 +35,11 @@ fn validate_proof_of_work(self: @ChainState, block: @Block) -> Result<(), ByteAr } fn validate_target(self: @ChainState, block: @Block) -> Result<(), ByteArray> { - // TODO: implement - Result::Ok(()) + if self.current_target == block.header.bits { + Result::Ok(()) + } else { + Result::Err("Target is {block.header.bits}. Expected {self.current_target}") + } } fn validate_timestamp(self: @ChainState, block: @Block) -> Result<(), ByteArray> { @@ -63,3 +66,43 @@ fn validate_merkle_root(self: @ChainState, block: @Block) -> Result<(), ByteArra // TODO: implement Result::Ok(()) } + +#[cfg(test)] +mod tests { + use core::result::ResultTrait; + use super::validate_target; + use super::{Block, ChainState}; + use super::super::state::{Header, Transaction, TxIn, TxOut}; + use core::array::{Span}; + + #[test] + fn test_validate_target() { + let mut chain_state = ChainState { + block_height: 1, + total_work: 1, + best_block_hash: 1, + current_target: 1, + epoch_start_time: 1, + prev_timestamps: array![1, 2, 3, 4, 5].span(), + }; + let mut block = Block { + header: Header { + version: 1, prev_block_hash: 1, merkle_root_hash: 1, time: 1, bits: 1, nonce: 1, + }, + txs: ArrayTrait::new().span(), + }; + + let result = validate_target(@chain_state, @block); + assert(result.is_ok(), 'Expected target to be valid'); + + chain_state.current_target = 2; + block.header.bits = 1; + let result = validate_target(@chain_state, @block); + assert(result.is_err(), 'Expected target to be invalid'); + + chain_state.current_target = 1; + block.header.bits = 2; + let result = validate_target(@chain_state, @block); + assert(result.is_err(), 'Expected target to be invalid'); + } +}