From 623b9f5730c5115c5b043b6e11723bdb4ab21b2c Mon Sep 17 00:00:00 2001 From: Jeanmichel7 Date: Fri, 2 Aug 2024 21:52:18 +0200 Subject: [PATCH 1/4] implement and tests validate_target --- Scarb.toml | 3 +++ src/state.cairo | 14 ++++++------ src/validation.cairo | 51 +++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 58 insertions(+), 10 deletions(-) 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..eb9c1950 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. @@ -65,9 +65,9 @@ pub struct Transaction { #[derive(Drop, Copy)] pub struct TxOut { /// The value of the output. - value: i64, + pub value: i64, /// The public key script of the output. - pk_script: @ByteArray, + pub pk_script: @ByteArray, } /// Input of a transaction. @@ -75,12 +75,12 @@ pub struct TxOut { #[derive(Drop, Copy)] pub struct TxIn { /// The transaction ID of the input. - txid: u256, + pub txid: u256, /// The index of the input. - index: u32, + pub index: u32, /// The script of the input. - script: @ByteArray, + pub script: @ByteArray, /// The sequence of the input. - sequence: u32, + pub sequence: u32, } diff --git a/src/validation.cairo b/src/validation.cairo index 1071898f..ede0ddce 100644 --- a/src/validation.cairo +++ b/src/validation.cairo @@ -1,4 +1,4 @@ -use super::state::{Block, ChainState}; +use super::state::{Block, ChainState, TxIn}; #[generate_trait] impl BlockValidatorImpl of BlockValidator { @@ -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,45 @@ 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 txIn = TxIn { txid: 1, index: 1, script: @"1", sequence: 1, }; + let txOut = TxOut { value: 1, pk_script: @"1", }; + let transaction = Transaction { + version: 1, inputs: array![txIn].span(), outputs: array![txOut].span(), lock_time: 1, + }; + let header = Header { + version: 1, prev_block_hash: 1, merkle_root_hash: 1, time: 1, bits: 1, nonce: 1, + }; + let mut block = Block { header: header, txs: array![transaction].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'); + } +} From 5e75469f00a875ae0d95e8e2436ce424728c59a3 Mon Sep 17 00:00:00 2001 From: Jeanmichel7 Date: Fri, 2 Aug 2024 21:56:13 +0200 Subject: [PATCH 2/4] clean --- src/validation.cairo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/validation.cairo b/src/validation.cairo index ede0ddce..06e626d3 100644 --- a/src/validation.cairo +++ b/src/validation.cairo @@ -1,4 +1,4 @@ -use super::state::{Block, ChainState, TxIn}; +use super::state::{Block, ChainState}; #[generate_trait] impl BlockValidatorImpl of BlockValidator { From ff242e58368fc0c3425d53e7130ba2df25c61238 Mon Sep 17 00:00:00 2001 From: Jeanmichel7 Date: Sat, 3 Aug 2024 11:34:53 +0200 Subject: [PATCH 3/4] remove transactions in test --- src/state.cairo | 14 +++++++------- src/validation.cairo | 16 +++++++--------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/state.cairo b/src/state.cairo index eb9c1950..37b072ff 100644 --- a/src/state.cairo +++ b/src/state.cairo @@ -13,7 +13,7 @@ pub struct ChainState { pub epoch_start_time: u32, /// Previous timestamps. pub prev_timestamps: Span, - // TODO: utreexo_roots? +// TODO: utreexo_roots? } /// Represents a block in the blockchain. @@ -65,9 +65,9 @@ pub struct Transaction { #[derive(Drop, Copy)] pub struct TxOut { /// The value of the output. - pub value: i64, + value: i64, /// The public key script of the output. - pub pk_script: @ByteArray, + pk_script: @ByteArray, } /// Input of a transaction. @@ -75,12 +75,12 @@ pub struct TxOut { #[derive(Drop, Copy)] pub struct TxIn { /// The transaction ID of the input. - pub txid: u256, + txid: u256, /// The index of the input. - pub index: u32, + index: u32, /// The script of the input. - pub script: @ByteArray, + script: @ByteArray, /// The sequence of the input. - pub sequence: u32, + sequence: u32, } diff --git a/src/validation.cairo b/src/validation.cairo index 06e626d3..478c8e71 100644 --- a/src/validation.cairo +++ b/src/validation.cairo @@ -71,7 +71,7 @@ fn validate_merkle_root(self: @ChainState, block: @Block) -> Result<(), ByteArra mod tests { use core::result::ResultTrait; use super::validate_target; - use super::{Block, ChainState,}; + use super::{Block, ChainState}; use super::super::state::{Header, Transaction, TxIn, TxOut}; use core::array::{Span}; @@ -85,15 +85,13 @@ mod tests { epoch_start_time: 1, prev_timestamps: array![1, 2, 3, 4, 5].span(), }; - let txIn = TxIn { txid: 1, index: 1, script: @"1", sequence: 1, }; - let txOut = TxOut { value: 1, pk_script: @"1", }; - let transaction = Transaction { - version: 1, inputs: array![txIn].span(), outputs: array![txOut].span(), lock_time: 1, + 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 header = Header { - version: 1, prev_block_hash: 1, merkle_root_hash: 1, time: 1, bits: 1, nonce: 1, - }; - let mut block = Block { header: header, txs: array![transaction].span() }; + let result = validate_target(@chain_state, @block); assert(result.is_ok(), 'Expected target to be valid'); From 4832a8ea0b9e15dd1b049bff154137fe671eeb3a Mon Sep 17 00:00:00 2001 From: Jeanmichel7 Date: Sat, 3 Aug 2024 11:36:12 +0200 Subject: [PATCH 4/4] format linter --- src/state.cairo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/state.cairo b/src/state.cairo index 37b072ff..c69d15b6 100644 --- a/src/state.cairo +++ b/src/state.cairo @@ -13,7 +13,7 @@ pub struct ChainState { pub epoch_start_time: u32, /// Previous timestamps. pub prev_timestamps: Span, -// TODO: utreexo_roots? + // TODO: utreexo_roots? } /// Represents a block in the blockchain.