From e33e00ee58e3112a5c55eea03eeafcddf7063852 Mon Sep 17 00:00:00 2001 From: olufemi-olumaiyegun Date: Tue, 6 Aug 2024 14:16:42 -0500 Subject: [PATCH 01/13] Set up functions to calculate work required to update block --- Scarb.lock | 61 ++++++++++++++++++++++++++++++++++++++++++++ Scarb.toml | 2 ++ src/validation.cairo | 54 ++++++++++++++++++++++++++++++++++++--- 3 files changed, 114 insertions(+), 3 deletions(-) diff --git a/Scarb.lock b/Scarb.lock index a0e0284f..dd768b96 100644 --- a/Scarb.lock +++ b/Scarb.lock @@ -1,6 +1,67 @@ # Code generated by scarb DO NOT EDIT. version = 1 +[[package]] +name = "alexandria_bytes" +version = "0.1.0" +source = "git+https://github.com/keep-starknet-strange/alexandria.git#bcdca70afdf59c9976148e95cebad5cf63d75a7f" +dependencies = [ + "alexandria_data_structures", + "alexandria_math", +] + +[[package]] +name = "alexandria_data_structures" +version = "0.2.0" +source = "git+https://github.com/keep-starknet-strange/alexandria.git#bcdca70afdf59c9976148e95cebad5cf63d75a7f" +dependencies = [ + "alexandria_encoding", +] + +[[package]] +name = "alexandria_encoding" +version = "0.1.0" +source = "git+https://github.com/keep-starknet-strange/alexandria.git#bcdca70afdf59c9976148e95cebad5cf63d75a7f" +dependencies = [ + "alexandria_bytes", + "alexandria_math", + "alexandria_numeric", +] + +[[package]] +name = "alexandria_math" +version = "0.2.0" +source = "git+https://github.com/keep-starknet-strange/alexandria.git#bcdca70afdf59c9976148e95cebad5cf63d75a7f" +dependencies = [ + "alexandria_data_structures", +] + +[[package]] +name = "alexandria_numeric" +version = "0.1.0" +source = "git+https://github.com/keep-starknet-strange/alexandria.git#bcdca70afdf59c9976148e95cebad5cf63d75a7f" +dependencies = [ + "alexandria_math", + "alexandria_searching", +] + +[[package]] +name = "alexandria_searching" +version = "0.1.0" +source = "git+https://github.com/keep-starknet-strange/alexandria.git#bcdca70afdf59c9976148e95cebad5cf63d75a7f" +dependencies = [ + "alexandria_data_structures", +] + +[[package]] +name = "cairo_lib" +version = "0.2.0" +source = "git+https://github.com/HerodotusDev/cairo-lib.git#a0c0ee4feeb4edb61e7a35d29595ad8647c3d469" + [[package]] name = "raito" version = "0.1.0" +dependencies = [ + "alexandria_math", + "cairo_lib", +] diff --git a/Scarb.toml b/Scarb.toml index 7a78c68a..1a266abe 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -7,6 +7,8 @@ edition = "2023_11" gen_data_test= "chmod -x ./scripts/data/launch.sh && bash ./scripts/data/launch.sh" [dependencies] +alexandria_math = { git = "https://github.com/keep-starknet-strange/alexandria.git" } +cairo_lib = { git = "https://github.com/HerodotusDev/cairo-lib.git" } [dev-dependencies] cairo_test = "2.7.0" \ No newline at end of file diff --git a/src/validation.cairo b/src/validation.cairo index 68bf7eb8..ce425b52 100644 --- a/src/validation.cairo +++ b/src/validation.cairo @@ -1,4 +1,10 @@ use super::state::{Block, ChainState}; +use alexandria_math::i257::{i257, I257Impl}; +use alexandria_math::pow; + + +const ONE_256: u256 = 1_u256; +const ALL_ONES_U128: u128 = 340282366920938463463374607431768211455; #[generate_trait] impl BlockValidatorImpl of BlockValidator { @@ -56,8 +62,40 @@ fn next_prev_timestamps(self: @ChainState, block: @Block) -> Span { } fn compute_total_work(self: @ChainState, block: @Block) -> u256 { - // TODO: implement - *self.total_work + let block_target: u256 = convert_u32_to_u256(*block.header.bits); + let work_in_block: u256 = compute_work_from_target(block_target); + let new_total_work: u256 = *self.total_work + work_in_block; + new_total_work +} + +fn convert_u32_to_u256(val: u32) -> u256 { + let felt_val: felt252 = val.into(); + let mut val_u256: u256 = 1; + let low: u128 = felt_val.try_into().unwrap(); + let high: u128 = 0; + val_u256.low = low; + val_u256.high = high; + val_u256 + +} + +fn compute_bitwise_not_for_u256(val: u256) -> u256 { + let mut not_val: u256 = 0; + not_val.low = ALL_ONES_U128 - val.low; + not_val.high = ALL_ONES_U128 - val.high; + not_val +} +fn compute_work_from_target(target: u256) -> u256 { + let one_i257: i257 = I257Impl::new(ONE_256, false); + let target_i257: i257 = target.into(); + print!("converted target is {}", target_i257.abs()); + let not_target: i257 = compute_bitwise_not_for_u256(target).into(); + print!("not target is {}", not_target.abs()); + let div_i257: i257 = not_target / (target_i257 + one_i257); + print!("div target is {}", div_i257.abs()); + let result_i257: i257 = div_i257 + one_i257; + print!("result is {}", result_i257.abs()); + result_i257.abs() } fn adjust_difficulty(self: @ChainState, block: @Block) -> (u32, u32) { @@ -72,9 +110,11 @@ fn validate_merkle_root(self: @ChainState, block: @Block) -> Result<(), ByteArra #[cfg(test)] mod tests { - use super::{validate_target, validate_timestamp}; + use super::{validate_target, validate_timestamp, compute_work_from_target}; use super::{Block, ChainState}; use super::super::state::{Header, Transaction, TxIn, TxOut}; + use alexandria_math::i257::{i257, I257Impl}; + use cairo_lib::utils::math::pow; #[test] fn test_validate_target() { @@ -107,6 +147,14 @@ mod tests { assert(result.is_err(), 'Expected target to be invalid'); } + #[test] + fn test_compute_work_from_target() { + let expected_work = 0x0100010001; + let target: u256 = 0x00000000ffff0000000000000000000000000000000000000000000000000000; + let work = compute_work_from_target(target); + assert(expected_work == work, 'failed to compute target'); + } + #[test] fn test_validate_timestamp() { let mut chain_state = ChainState { From a6d35314a5295b88deeeccae2b10974e59fa81b0 Mon Sep 17 00:00:00 2001 From: olufemi-olumaiyegun Date: Tue, 6 Aug 2024 15:14:30 -0500 Subject: [PATCH 02/13] adding more tests | unit testing --- src/validation.cairo | 56 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 9 deletions(-) diff --git a/src/validation.cairo b/src/validation.cairo index ce425b52..f7fa39c3 100644 --- a/src/validation.cairo +++ b/src/validation.cairo @@ -81,10 +81,11 @@ fn convert_u32_to_u256(val: u32) -> u256 { fn compute_bitwise_not_for_u256(val: u256) -> u256 { let mut not_val: u256 = 0; - not_val.low = ALL_ONES_U128 - val.low; - not_val.high = ALL_ONES_U128 - val.high; + not_val.low = ALL_ONES_U128 - val.low - 1_u128; + not_val.high = ALL_ONES_U128 - val.high - 1_u128; not_val } + fn compute_work_from_target(target: u256) -> u256 { let one_i257: i257 = I257Impl::new(ONE_256, false); let target_i257: i257 = target.into(); @@ -110,7 +111,7 @@ fn validate_merkle_root(self: @ChainState, block: @Block) -> Result<(), ByteArra #[cfg(test)] mod tests { - use super::{validate_target, validate_timestamp, compute_work_from_target}; + use super::{validate_target, validate_timestamp, compute_work_from_target, compute_total_work}; use super::{Block, ChainState}; use super::super::state::{Header, Transaction, TxIn, TxOut}; use alexandria_math::i257::{i257, I257Impl}; @@ -147,12 +148,49 @@ mod tests { assert(result.is_err(), 'Expected target to be invalid'); } - #[test] - fn test_compute_work_from_target() { - let expected_work = 0x0100010001; - let target: u256 = 0x00000000ffff0000000000000000000000000000000000000000000000000000; - let work = compute_work_from_target(target); - assert(expected_work == work, 'failed to compute target'); + // #[test] + // fn test_compute_work_from_targe1() { + // let expected_work = 0x0100010001; + // let target: u256 = 0x00000000ffff0000000000000000000000000000000000000000000000000000; + // let work = compute_work_from_target(target); + // assert(expected_work == work, 'failed to compute target'); + // } + // #[test] + // fn test_compute_work_from_target2() { + // let expected_work = 0x26d946e509ac00026d; + // let target: u256 = 0x00000000000000000696f4000000000000000000000000000000000000000000; + // let work = compute_work_from_target(target); + // assert(expected_work == work, 'failed to compute target'); + // } + + // #[test] + // fn test_compute_work_from_target3() { + // let expected_work = 0x21809b468faa88dbe34f; + // let target: u256 = 0x00000000000000000007a4290000000000000000000000000000000000000000; + // let work = compute_work_from_target(target); + // assert(expected_work == work, 'failed to compute target'); + // } + + #[test] + fn test_compute_total_work () { + 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, 6, 7, 8, 9, 10, 11].span(), + }; + let mut block = Block { + header: Header { + version: 1, prev_block_hash: 1, merkle_root_hash: 1, time: 12, bits: 0x1, nonce: 1, + }, + txs: ArrayTrait::new().span(), + }; + let expected_work = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + chain_state.total_work; + let total_work: u256 = compute_total_work(@chain_state, @block); + assert(total_work == expected_work, 'failed to compute target'); + } #[test] From b9524206cb96cee8200fb87eb8624556f5b9da03 Mon Sep 17 00:00:00 2001 From: olufemi-olumaiyegun Date: Tue, 6 Aug 2024 15:19:57 -0500 Subject: [PATCH 03/13] leaving only necessary tests --- src/validation.cairo | 70 +++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 43 deletions(-) diff --git a/src/validation.cairo b/src/validation.cairo index f7fa39c3..d7de200a 100644 --- a/src/validation.cairo +++ b/src/validation.cairo @@ -116,6 +116,7 @@ mod tests { use super::super::state::{Header, Transaction, TxIn, TxOut}; use alexandria_math::i257::{i257, I257Impl}; use cairo_lib::utils::math::pow; + const ONE_256: u256 = 1_u256; #[test] fn test_validate_target() { @@ -148,31 +149,8 @@ mod tests { assert(result.is_err(), 'Expected target to be invalid'); } - // #[test] - // fn test_compute_work_from_targe1() { - // let expected_work = 0x0100010001; - // let target: u256 = 0x00000000ffff0000000000000000000000000000000000000000000000000000; - // let work = compute_work_from_target(target); - // assert(expected_work == work, 'failed to compute target'); - // } - // #[test] - // fn test_compute_work_from_target2() { - // let expected_work = 0x26d946e509ac00026d; - // let target: u256 = 0x00000000000000000696f4000000000000000000000000000000000000000000; - // let work = compute_work_from_target(target); - // assert(expected_work == work, 'failed to compute target'); - // } - - // #[test] - // fn test_compute_work_from_target3() { - // let expected_work = 0x21809b468faa88dbe34f; - // let target: u256 = 0x00000000000000000007a4290000000000000000000000000000000000000000; - // let work = compute_work_from_target(target); - // assert(expected_work == work, 'failed to compute target'); - // } - #[test] - fn test_compute_total_work () { + fn test_validate_timestamp() { let mut chain_state = ChainState { block_height: 1, total_work: 1, @@ -183,18 +161,27 @@ mod tests { }; let mut block = Block { header: Header { - version: 1, prev_block_hash: 1, merkle_root_hash: 1, time: 12, bits: 0x1, nonce: 1, + version: 1, prev_block_hash: 1, merkle_root_hash: 1, time: 12, bits: 1, nonce: 1, }, txs: ArrayTrait::new().span(), }; - let expected_work = 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + chain_state.total_work; - let total_work: u256 = compute_total_work(@chain_state, @block); - assert(total_work == expected_work, 'failed to compute target'); - } + // new timestamp is greater than the last timestamp + let result = validate_timestamp(@chain_state, @block); + assert(result.is_ok(), 'Expected target to be valid'); + // new timestamp is strictly greater than the median of the last 11 timestamps + block.header.time = 7; + let result = validate_timestamp(@chain_state, @block); + assert(result.is_ok(), 'Expected target to be valid'); + + // new timestamp is equal to the median of the last 11 timestamps + block.header.time = 6; + let result = validate_timestamp(@chain_state, @block); + assert!(result.is_err(), "Median time is greater than block's timestamp"); + } #[test] - fn test_validate_timestamp() { + fn test_compute_total_work() { let mut chain_state = ChainState { block_height: 1, total_work: 1, @@ -209,19 +196,16 @@ mod tests { }, txs: ArrayTrait::new().span(), }; + let expected_work = compute_work_from_target(ONE_256) + chain_state.total_work; + let total_work: u256 = compute_total_work(@chain_state, @block); + assert(total_work == expected_work, 'failed to compute target'); + } - // new timestamp is greater than the last timestamp - let result = validate_timestamp(@chain_state, @block); - assert(result.is_ok(), 'Expected target to be valid'); - - // new timestamp is strictly greater than the median of the last 11 timestamps - block.header.time = 7; - let result = validate_timestamp(@chain_state, @block); - assert(result.is_ok(), 'Expected target to be valid'); - - // new timestamp is equal to the median of the last 11 timestamps - block.header.time = 6; - let result = validate_timestamp(@chain_state, @block); - assert!(result.is_err(), "Median time is greater than block's timestamp"); + #[test] + fn test_compute_work_from_target() { + let expected_work = 0x0100010001; + let target: u256 = 0x00000000ffff0000000000000000000000000000000000000000000000000000; + let work = compute_work_from_target(target); + assert(expected_work == work, 'failed to compute target'); } } From 70c05bcecff55b4818d64a4c0f4b7eae3298edd4 Mon Sep 17 00:00:00 2001 From: olufemi-olumaiyegun Date: Tue, 6 Aug 2024 15:20:32 -0500 Subject: [PATCH 04/13] remove comments --- src/validation.cairo | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/validation.cairo b/src/validation.cairo index d7de200a..315079e8 100644 --- a/src/validation.cairo +++ b/src/validation.cairo @@ -89,13 +89,9 @@ fn compute_bitwise_not_for_u256(val: u256) -> u256 { fn compute_work_from_target(target: u256) -> u256 { let one_i257: i257 = I257Impl::new(ONE_256, false); let target_i257: i257 = target.into(); - print!("converted target is {}", target_i257.abs()); let not_target: i257 = compute_bitwise_not_for_u256(target).into(); - print!("not target is {}", not_target.abs()); let div_i257: i257 = not_target / (target_i257 + one_i257); - print!("div target is {}", div_i257.abs()); let result_i257: i257 = div_i257 + one_i257; - print!("result is {}", result_i257.abs()); result_i257.abs() } From 4a25d9d85c69e2fc07bdc2d477d16232750550d5 Mon Sep 17 00:00:00 2001 From: olufemi-olumaiyegun Date: Tue, 6 Aug 2024 15:29:58 -0500 Subject: [PATCH 05/13] SOME CLEANING UP --- Scarb.lock | 6 ------ Scarb.toml | 1 - src/validation.cairo | 6 +++++- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/Scarb.lock b/Scarb.lock index dd768b96..b048f148 100644 --- a/Scarb.lock +++ b/Scarb.lock @@ -53,15 +53,9 @@ dependencies = [ "alexandria_data_structures", ] -[[package]] -name = "cairo_lib" -version = "0.2.0" -source = "git+https://github.com/HerodotusDev/cairo-lib.git#a0c0ee4feeb4edb61e7a35d29595ad8647c3d469" - [[package]] name = "raito" version = "0.1.0" dependencies = [ "alexandria_math", - "cairo_lib", ] diff --git a/Scarb.toml b/Scarb.toml index 1a266abe..fad892e4 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -8,7 +8,6 @@ gen_data_test= "chmod -x ./scripts/data/launch.sh && bash ./scripts/data/launch. [dependencies] alexandria_math = { git = "https://github.com/keep-starknet-strange/alexandria.git" } -cairo_lib = { git = "https://github.com/HerodotusDev/cairo-lib.git" } [dev-dependencies] cairo_test = "2.7.0" \ No newline at end of file diff --git a/src/validation.cairo b/src/validation.cairo index 315079e8..3401567f 100644 --- a/src/validation.cairo +++ b/src/validation.cairo @@ -76,7 +76,6 @@ fn convert_u32_to_u256(val: u32) -> u256 { val_u256.low = low; val_u256.high = high; val_u256 - } fn compute_bitwise_not_for_u256(val: u256) -> u256 { @@ -86,6 +85,11 @@ fn compute_bitwise_not_for_u256(val: u256) -> u256 { not_val } + +// Need to compute 2**256 / (target+1), but we can't represent 2**256 +// as it's too large for an u256. However, as 2**256 is at least as large +// as target+1, it is equal to ((2**256 - target - 1) / (target+1)) + 1, +// or ~target / (target+1) + 1. fn compute_work_from_target(target: u256) -> u256 { let one_i257: i257 = I257Impl::new(ONE_256, false); let target_i257: i257 = target.into(); From b46c0a3984cbd5cc82e7b23c4b4fca61205c400a Mon Sep 17 00:00:00 2001 From: olufemi-olumaiyegun Date: Tue, 6 Aug 2024 15:32:09 -0500 Subject: [PATCH 06/13] SOME CLEANING UP --- src/validation.cairo | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/validation.cairo b/src/validation.cairo index 333ce7f9..f6201419 100644 --- a/src/validation.cairo +++ b/src/validation.cairo @@ -1,8 +1,8 @@ use alexandria_math::i257::{i257, I257Impl}; -use alexandria_math::pow; +use super::state::{Block, ChainState, UtreexoState}; + const ONE_256: u256 = 1_u256; const ALL_ONES_U128: u128 = 340282366920938463463374607431768211455; -use super::state::{Block, ChainState, UtreexoState}; #[generate_trait] impl BlockValidatorImpl of BlockValidator { @@ -113,7 +113,6 @@ mod tests { use super::{Block, ChainState, UtreexoState}; use super::super::state::{Header, Transaction, TxIn, TxOut}; use alexandria_math::i257::{i257, I257Impl}; - use cairo_lib::utils::math::pow; const ONE_256: u256 = 1_u256; #[test] @@ -201,7 +200,7 @@ mod tests { assert(total_work == expected_work, 'failed to compute target'); } - #[test] + #[test] fn test_compute_work_from_target() { let expected_work = 0x0100010001; let target: u256 = 0x00000000ffff0000000000000000000000000000000000000000000000000000; From 6564a7439ed9780d27158162d6fb0958fbcd9a05 Mon Sep 17 00:00:00 2001 From: olufemi-olumaiyegun Date: Tue, 6 Aug 2024 15:41:29 -0500 Subject: [PATCH 07/13] fix test after update with main --- src/validation.cairo | 1 + 1 file changed, 1 insertion(+) diff --git a/src/validation.cairo b/src/validation.cairo index f6201419..a9da4c3f 100644 --- a/src/validation.cairo +++ b/src/validation.cairo @@ -188,6 +188,7 @@ mod tests { current_target: 1, epoch_start_time: 1, prev_timestamps: array![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11].span(), + utreexo_state: UtreexoState { roots: array![].span() }, }; let mut block = Block { header: Header { From 16190f67212c8c49efbbd0a28e499458cfa365d5 Mon Sep 17 00:00:00 2001 From: olufemi-olumaiyegun Date: Tue, 6 Aug 2024 16:19:13 -0500 Subject: [PATCH 08/13] -remove alexandria dependency -use u256 for operations instead of i157 -copy zkSync version of tests --- Scarb.lock | 55 --------------------------------- Scarb.toml | 1 - src/validation.cairo | 73 ++++++++++++++++++++------------------------ 3 files changed, 33 insertions(+), 96 deletions(-) diff --git a/Scarb.lock b/Scarb.lock index b048f148..a0e0284f 100644 --- a/Scarb.lock +++ b/Scarb.lock @@ -1,61 +1,6 @@ # Code generated by scarb DO NOT EDIT. version = 1 -[[package]] -name = "alexandria_bytes" -version = "0.1.0" -source = "git+https://github.com/keep-starknet-strange/alexandria.git#bcdca70afdf59c9976148e95cebad5cf63d75a7f" -dependencies = [ - "alexandria_data_structures", - "alexandria_math", -] - -[[package]] -name = "alexandria_data_structures" -version = "0.2.0" -source = "git+https://github.com/keep-starknet-strange/alexandria.git#bcdca70afdf59c9976148e95cebad5cf63d75a7f" -dependencies = [ - "alexandria_encoding", -] - -[[package]] -name = "alexandria_encoding" -version = "0.1.0" -source = "git+https://github.com/keep-starknet-strange/alexandria.git#bcdca70afdf59c9976148e95cebad5cf63d75a7f" -dependencies = [ - "alexandria_bytes", - "alexandria_math", - "alexandria_numeric", -] - -[[package]] -name = "alexandria_math" -version = "0.2.0" -source = "git+https://github.com/keep-starknet-strange/alexandria.git#bcdca70afdf59c9976148e95cebad5cf63d75a7f" -dependencies = [ - "alexandria_data_structures", -] - -[[package]] -name = "alexandria_numeric" -version = "0.1.0" -source = "git+https://github.com/keep-starknet-strange/alexandria.git#bcdca70afdf59c9976148e95cebad5cf63d75a7f" -dependencies = [ - "alexandria_math", - "alexandria_searching", -] - -[[package]] -name = "alexandria_searching" -version = "0.1.0" -source = "git+https://github.com/keep-starknet-strange/alexandria.git#bcdca70afdf59c9976148e95cebad5cf63d75a7f" -dependencies = [ - "alexandria_data_structures", -] - [[package]] name = "raito" version = "0.1.0" -dependencies = [ - "alexandria_math", -] diff --git a/Scarb.toml b/Scarb.toml index fad892e4..7a78c68a 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -7,7 +7,6 @@ edition = "2023_11" gen_data_test= "chmod -x ./scripts/data/launch.sh && bash ./scripts/data/launch.sh" [dependencies] -alexandria_math = { git = "https://github.com/keep-starknet-strange/alexandria.git" } [dev-dependencies] cairo_test = "2.7.0" \ No newline at end of file diff --git a/src/validation.cairo b/src/validation.cairo index a9da4c3f..3fb06194 100644 --- a/src/validation.cairo +++ b/src/validation.cairo @@ -1,8 +1,7 @@ -use alexandria_math::i257::{i257, I257Impl}; use super::state::{Block, ChainState, UtreexoState}; const ONE_256: u256 = 1_u256; -const ALL_ONES_U128: u128 = 340282366920938463463374607431768211455; +const ALL_ONES_U128: u128 = 340282366920938463463374607431768211455; //(2^128) - 1 #[generate_trait] impl BlockValidatorImpl of BlockValidator { @@ -76,25 +75,14 @@ fn convert_u32_to_u256(val: u32) -> u256 { val_u256 } -fn compute_bitwise_not_for_u256(val: u256) -> u256 { - let mut not_val: u256 = 0; - not_val.low = ALL_ONES_U128 - val.low - 1_u128; - not_val.high = ALL_ONES_U128 - val.high - 1_u128; - not_val -} - - // Need to compute 2**256 / (target+1), but we can't represent 2**256 // as it's too large for an u256. However, as 2**256 is at least as large // as target+1, it is equal to ((2**256 - target - 1) / (target+1)) + 1, // or ~target / (target+1) + 1. fn compute_work_from_target(target: u256) -> u256 { - let one_i257: i257 = I257Impl::new(ONE_256, false); - let target_i257: i257 = target.into(); - let not_target: i257 = compute_bitwise_not_for_u256(target).into(); - let div_i257: i257 = not_target / (target_i257 + one_i257); - let result_i257: i257 = div_i257 + one_i257; - result_i257.abs() + let div: u256 = ~target / (target + ONE_256); + let result: u256 = div + ONE_256; + result } fn adjust_difficulty(self: @ChainState, block: @Block) -> (u32, u32) { @@ -112,8 +100,6 @@ mod tests { use super::{validate_target, validate_timestamp, compute_work_from_target, compute_total_work}; use super::{Block, ChainState, UtreexoState}; use super::super::state::{Header, Transaction, TxIn, TxOut}; - use alexandria_math::i257::{i257, I257Impl}; - const ONE_256: u256 = 1_u256; #[test] fn test_validate_target() { @@ -179,33 +165,40 @@ mod tests { let result = validate_timestamp(@chain_state, @block); assert!(result.is_err(), "Median time is greater than block's timestamp"); } - #[test] - fn test_compute_total_work() { - 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, 6, 7, 8, 9, 10, 11].span(), - utreexo_state: UtreexoState { roots: array![].span() }, - }; - let mut block = Block { - header: Header { - version: 1, prev_block_hash: 1, merkle_root_hash: 1, time: 12, bits: 1, nonce: 1, - }, - txs: ArrayTrait::new().span(), - }; - let expected_work = compute_work_from_target(ONE_256) + chain_state.total_work; - let total_work: u256 = compute_total_work(@chain_state, @block); - assert(total_work == expected_work, 'failed to compute target'); - } #[test] - fn test_compute_work_from_target() { + fn test_compute_work_from_target1() { let expected_work = 0x0100010001; let target: u256 = 0x00000000ffff0000000000000000000000000000000000000000000000000000; let work = compute_work_from_target(target); assert(expected_work == work, 'failed to compute target'); } + #[test] + fn test_compute_work_from_target2() { + let expected_work = 0x26d946e509ac00026d; + let target: u256 = 0x00000000000000000696f4000000000000000000000000000000000000000000; + let work = compute_work_from_target(target); + assert(expected_work == work, 'failed to compute target'); + } + #[test] + fn test_compute_work_from_target3() { + let expected_work = 0xe10005d2a0269364ff907d1d1d3ce0e1b351d743fe3222740c2440d07; + let target: u256 = 0x12345600; + let work = compute_work_from_target(target); + assert(expected_work == work, 'failed to compute target'); + } + #[test] + fn test_compute_work_from_target4() { + let expected_work = 0x1c040c95d1a74d2e27abbbd2255f66c9db2cad7511eb970cd4dac39e4; + let target: u256 = 0x92340000; + let work = compute_work_from_target(target); + assert(expected_work == work, 'failed to compute target'); + } + #[test] + fn test_compute_work_from_target5() { + let expected_work = 0x21809b468faa88dbe34f; + let target: u256 = 0x00000000000000000007a4290000000000000000000000000000000000000000; + let work = compute_work_from_target(target); + assert(expected_work == work, 'failed to compute target'); + } } From d89d32700854c4cd3fb39ca4e8d6f6862ab318b3 Mon Sep 17 00:00:00 2001 From: olufemi-olumaiyegun Date: Tue, 6 Aug 2024 16:25:40 -0500 Subject: [PATCH 09/13] remove unused var --- src/validation.cairo | 1 - 1 file changed, 1 deletion(-) diff --git a/src/validation.cairo b/src/validation.cairo index 3fb06194..3b8383e6 100644 --- a/src/validation.cairo +++ b/src/validation.cairo @@ -1,7 +1,6 @@ use super::state::{Block, ChainState, UtreexoState}; const ONE_256: u256 = 1_u256; -const ALL_ONES_U128: u128 = 340282366920938463463374607431768211455; //(2^128) - 1 #[generate_trait] impl BlockValidatorImpl of BlockValidator { From f599f8124e7acf0cf4644a262fada94f54d20513 Mon Sep 17 00:00:00 2001 From: olufemi-olumaiyegun Date: Tue, 6 Aug 2024 19:45:42 -0500 Subject: [PATCH 10/13] fix tests --- src/validation.cairo | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/validation.cairo b/src/validation.cairo index 3b8383e6..71d6dd14 100644 --- a/src/validation.cairo +++ b/src/validation.cairo @@ -181,14 +181,14 @@ mod tests { } #[test] fn test_compute_work_from_target3() { - let expected_work = 0xe10005d2a0269364ff907d1d1d3ce0e1b351d743fe3222740c2440d07; + let expected_work = 0xe10005c64415f04ef3e387b97db388404db9fdfaab2b1918f6783471d; let target: u256 = 0x12345600; let work = compute_work_from_target(target); assert(expected_work == work, 'failed to compute target'); } #[test] fn test_compute_work_from_target4() { - let expected_work = 0x1c040c95d1a74d2e27abbbd2255f66c9db2cad7511eb970cd4dac39e4; + let expected_work = 0x1c040c95a099201bcaf85db4e7f2e21e18707c8d55a887643b95afb2f; let target: u256 = 0x92340000; let work = compute_work_from_target(target); assert(expected_work == work, 'failed to compute target'); From cefce7fbb00b0c7c09275bb45239f3d388551406 Mon Sep 17 00:00:00 2001 From: olufemi-olumaiyegun Date: Wed, 7 Aug 2024 20:01:10 -0500 Subject: [PATCH 11/13] address review comments --- src/validation.cairo | 36 ++++++++++-------------------------- 1 file changed, 10 insertions(+), 26 deletions(-) diff --git a/src/validation.cairo b/src/validation.cairo index 71d6dd14..906e6b9c 100644 --- a/src/validation.cairo +++ b/src/validation.cairo @@ -1,7 +1,5 @@ use super::state::{Block, ChainState, UtreexoState}; -const ONE_256: u256 = 1_u256; - #[generate_trait] impl BlockValidatorImpl of BlockValidator { fn validate_and_apply(self: ChainState, block: Block) -> Result { @@ -14,8 +12,9 @@ impl BlockValidatorImpl of BlockValidator { // validate_and_apply_transactions let prev_timestamps = next_prev_timestamps(@self, @block); - let total_work = compute_total_work(@self, @block); let (current_target, epoch_start_time) = adjust_difficulty(@self, @block); + let bits_to_target: u256 = block.header.bits.into(); //will replace with bits to target implementation + let total_work = compute_total_work(@self, bits_to_target); Result::Ok( ChainState { total_work, current_target, epoch_start_time, prev_timestamps, ..self, } @@ -57,21 +56,8 @@ fn next_prev_timestamps(self: @ChainState, block: @Block) -> Span { *self.prev_timestamps } -fn compute_total_work(self: @ChainState, block: @Block) -> u256 { - let block_target: u256 = convert_u32_to_u256(*block.header.bits); - let work_in_block: u256 = compute_work_from_target(block_target); - let new_total_work: u256 = *self.total_work + work_in_block; - new_total_work -} - -fn convert_u32_to_u256(val: u32) -> u256 { - let felt_val: felt252 = val.into(); - let mut val_u256: u256 = 1; - let low: u128 = felt_val.try_into().unwrap(); - let high: u128 = 0; - val_u256.low = low; - val_u256.high = high; - val_u256 +fn compute_total_work(self: @ChainState, target: u256) -> u256 { + *self.total_work + compute_work_from_target(target) } // Need to compute 2**256 / (target+1), but we can't represent 2**256 @@ -79,9 +65,7 @@ fn convert_u32_to_u256(val: u32) -> u256 { // as target+1, it is equal to ((2**256 - target - 1) / (target+1)) + 1, // or ~target / (target+1) + 1. fn compute_work_from_target(target: u256) -> u256 { - let div: u256 = ~target / (target + ONE_256); - let result: u256 = div + ONE_256; - result + (~target / (target + 1_u256)) + 1_u256 } fn adjust_difficulty(self: @ChainState, block: @Block) -> (u32, u32) { @@ -170,34 +154,34 @@ mod tests { let expected_work = 0x0100010001; let target: u256 = 0x00000000ffff0000000000000000000000000000000000000000000000000000; let work = compute_work_from_target(target); - assert(expected_work == work, 'failed to compute target'); + assert(expected_work == work, 'Failed to compute target'); } #[test] fn test_compute_work_from_target2() { let expected_work = 0x26d946e509ac00026d; let target: u256 = 0x00000000000000000696f4000000000000000000000000000000000000000000; let work = compute_work_from_target(target); - assert(expected_work == work, 'failed to compute target'); + assert(expected_work == work, 'Failed to compute target'); } #[test] fn test_compute_work_from_target3() { let expected_work = 0xe10005c64415f04ef3e387b97db388404db9fdfaab2b1918f6783471d; let target: u256 = 0x12345600; let work = compute_work_from_target(target); - assert(expected_work == work, 'failed to compute target'); + assert(expected_work == work, 'Failed to compute target'); } #[test] fn test_compute_work_from_target4() { let expected_work = 0x1c040c95a099201bcaf85db4e7f2e21e18707c8d55a887643b95afb2f; let target: u256 = 0x92340000; let work = compute_work_from_target(target); - assert(expected_work == work, 'failed to compute target'); + assert(expected_work == work, 'Failed to compute target'); } #[test] fn test_compute_work_from_target5() { let expected_work = 0x21809b468faa88dbe34f; let target: u256 = 0x00000000000000000007a4290000000000000000000000000000000000000000; let work = compute_work_from_target(target); - assert(expected_work == work, 'failed to compute target'); + assert(expected_work == work, 'Failed to compute target'); } } From 15cfcdf99aaad4afc7f80f97ad584876f0377255 Mon Sep 17 00:00:00 2001 From: olufemi-olumaiyegun Date: Wed, 7 Aug 2024 20:10:09 -0500 Subject: [PATCH 12/13] address review comments --- src/validation.cairo | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/validation.cairo b/src/validation.cairo index 906e6b9c..286ae3d6 100644 --- a/src/validation.cairo +++ b/src/validation.cairo @@ -14,7 +14,7 @@ impl BlockValidatorImpl of BlockValidator { let prev_timestamps = next_prev_timestamps(@self, @block); let (current_target, epoch_start_time) = adjust_difficulty(@self, @block); let bits_to_target: u256 = block.header.bits.into(); //will replace with bits to target implementation - let total_work = compute_total_work(@self, bits_to_target); + let total_work = compute_total_work(self.total_work, bits_to_target); Result::Ok( ChainState { total_work, current_target, epoch_start_time, prev_timestamps, ..self, } @@ -56,8 +56,8 @@ fn next_prev_timestamps(self: @ChainState, block: @Block) -> Span { *self.prev_timestamps } -fn compute_total_work(self: @ChainState, target: u256) -> u256 { - *self.total_work + compute_work_from_target(target) +fn compute_total_work(current_total_work: u256, target: u256) -> u256 { + current_total_work + compute_work_from_target(target) } // Need to compute 2**256 / (target+1), but we can't represent 2**256 From 648ddb3656e7c249f4f7b1b89b26663decba6005 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Kami=C5=84ski=20=40=20StarkWare?= Date: Fri, 9 Aug 2024 10:37:47 +0200 Subject: [PATCH 13/13] fix conflict in validation.cairo --- src/validation.cairo | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/validation.cairo b/src/validation.cairo index 84738b09..3fe41ea7 100644 --- a/src/validation.cairo +++ b/src/validation.cairo @@ -20,7 +20,9 @@ impl BlockValidatorImpl of BlockValidator { let best_block_hash = block_hash(@block, merkle_root)?; let prev_timestamps = next_prev_timestamps(@self, @block); let (current_target, epoch_start_time) = adjust_difficulty(@self, @block); - let total_work = compute_total_work(self.total_work, bits_to_target(block.header.bits).unwrap()); + let total_work = compute_total_work( + self.total_work, bits_to_target(block.header.bits).unwrap() + ); let block_height = self.block_height + 1; Result::Ok( @@ -223,7 +225,7 @@ fn compute_block_reward(block_height: u32) -> u64 { mod tests { use super::{ validate_target, validate_timestamp, validate_proof_of_work, compute_block_reward, - compute_total_work, shr, shl, REWARD_INITIAL, POW_SATS_AMOUNT + compute_total_work, compute_work_from_target, shr, shl, REWARD_INITIAL, POW_SATS_AMOUNT }; use super::{Block, ChainState, UtreexoState}; use super::super::state::{Header, Transaction, TxIn, TxOut};