From 9920d4077beecbb23c5428f288ece22c21087593 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Fri, 16 May 2025 16:53:23 +0000 Subject: [PATCH 1/2] test(fortuna): add unit tests for HashChainState Co-Authored-By: Jayant Krishnamurthy --- apps/fortuna/src/state.rs | 84 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/apps/fortuna/src/state.rs b/apps/fortuna/src/state.rs index 99839dcff6..63eb7dd1f2 100644 --- a/apps/fortuna/src/state.rs +++ b/apps/fortuna/src/state.rs @@ -203,3 +203,87 @@ mod test { run_hash_chain_test([0u8; 32], 100, 55); } } + +#[cfg(test)] +mod hash_chain_state_test { + use { + crate::state::{HashChainState, PebbleHashChain}, + anyhow::Result, + }; + + #[test] + fn test_from_chain_at_offset() { + let chain = PebbleHashChain::new([0u8; 32], 10, 1); + let hash_chain_state = HashChainState::from_chain_at_offset(5, chain); + + assert_eq!(hash_chain_state.offsets.len(), 1); + assert_eq!(hash_chain_state.hash_chains.len(), 1); + assert_eq!(hash_chain_state.offsets[0], 5); + } + + #[test] + fn test_reveal_valid_sequence() -> Result<()> { + let chain = PebbleHashChain::new([0u8; 32], 10, 1); + let expected_hash = chain.reveal_ith(3)?; + + let hash_chain_state = HashChainState::from_chain_at_offset(5, chain); + let result = hash_chain_state.reveal(8)?; + + assert_eq!(result, expected_hash); + Ok(()) + } + + #[test] + fn test_reveal_sequence_too_small() { + let chain = PebbleHashChain::new([0u8; 32], 10, 1); + let hash_chain_state = HashChainState::from_chain_at_offset(5, chain); + + let result = hash_chain_state.reveal(4); + assert!(result.is_err()); + } + + #[test] + fn test_reveal_sequence_too_large() { + let chain = PebbleHashChain::new([0u8; 32], 10, 1); + let hash_chain_state = HashChainState::from_chain_at_offset(5, chain); + + let result = hash_chain_state.reveal(15); + assert!(result.is_err()); + } + + #[test] + fn test_multiple_hash_chains() -> Result<()> { + let chain1 = PebbleHashChain::new([0u8; 32], 10, 1); + let expected_hash1 = chain1.reveal_ith(3)?; + + let chain2 = PebbleHashChain::new([1u8; 32], 10, 1); + let expected_hash2 = chain2.reveal_ith(3)?; + + let mut hash_chain_state = HashChainState::from_chain_at_offset(5, chain1); + hash_chain_state.offsets.push(20); + hash_chain_state.hash_chains.push(chain2); + + let result1 = hash_chain_state.reveal(8)?; + assert_eq!(result1, expected_hash1); + + let result2 = hash_chain_state.reveal(23)?; + assert_eq!(result2, expected_hash2); + + let result3 = hash_chain_state.reveal(15); + assert!(result3.is_err()); + + Ok(()) + } + + #[test] + fn test_reveal_at_offset() -> Result<()> { + let chain = PebbleHashChain::new([0u8; 32], 10, 1); + let expected_hash = chain.reveal_ith(0)?; + + let hash_chain_state = HashChainState::from_chain_at_offset(5, chain); + let result = hash_chain_state.reveal(5)?; + + assert_eq!(result, expected_hash); + Ok(()) + } +} From 20d7714695a2c9d7adcb9983566c7924c08d43f4 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Fri, 16 May 2025 17:56:36 +0000 Subject: [PATCH 2/2] refactor(fortuna): address PR feedback for HashChainState tests Co-Authored-By: Jayant Krishnamurthy --- apps/fortuna/src/state.rs | 54 ++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/apps/fortuna/src/state.rs b/apps/fortuna/src/state.rs index 63eb7dd1f2..7bd7aeb453 100644 --- a/apps/fortuna/src/state.rs +++ b/apps/fortuna/src/state.rs @@ -155,7 +155,8 @@ impl HashChainState { #[cfg(test)] mod test { use { - crate::state::PebbleHashChain, + crate::state::{HashChainState, PebbleHashChain}, + anyhow::Result, sha3::{Digest, Keccak256}, }; @@ -202,17 +203,9 @@ mod test { run_hash_chain_test([0u8; 32], 100, 50); run_hash_chain_test([0u8; 32], 100, 55); } -} - -#[cfg(test)] -mod hash_chain_state_test { - use { - crate::state::{HashChainState, PebbleHashChain}, - anyhow::Result, - }; #[test] - fn test_from_chain_at_offset() { + fn test_hash_chain_state_from_chain_at_offset() { let chain = PebbleHashChain::new([0u8; 32], 10, 1); let hash_chain_state = HashChainState::from_chain_at_offset(5, chain); @@ -222,7 +215,7 @@ mod hash_chain_state_test { } #[test] - fn test_reveal_valid_sequence() -> Result<()> { + fn test_hash_chain_state_reveal_valid_sequence() -> Result<()> { let chain = PebbleHashChain::new([0u8; 32], 10, 1); let expected_hash = chain.reveal_ith(3)?; @@ -234,7 +227,7 @@ mod hash_chain_state_test { } #[test] - fn test_reveal_sequence_too_small() { + fn test_hash_chain_state_reveal_sequence_too_small() { let chain = PebbleHashChain::new([0u8; 32], 10, 1); let hash_chain_state = HashChainState::from_chain_at_offset(5, chain); @@ -243,7 +236,7 @@ mod hash_chain_state_test { } #[test] - fn test_reveal_sequence_too_large() { + fn test_hash_chain_state_reveal_sequence_too_large() { let chain = PebbleHashChain::new([0u8; 32], 10, 1); let hash_chain_state = HashChainState::from_chain_at_offset(5, chain); @@ -252,16 +245,17 @@ mod hash_chain_state_test { } #[test] - fn test_multiple_hash_chains() -> Result<()> { + fn test_hash_chain_state_multiple_chains() -> Result<()> { let chain1 = PebbleHashChain::new([0u8; 32], 10, 1); let expected_hash1 = chain1.reveal_ith(3)?; let chain2 = PebbleHashChain::new([1u8; 32], 10, 1); let expected_hash2 = chain2.reveal_ith(3)?; - let mut hash_chain_state = HashChainState::from_chain_at_offset(5, chain1); - hash_chain_state.offsets.push(20); - hash_chain_state.hash_chains.push(chain2); + let hash_chain_state = HashChainState { + offsets: vec![5, 20], + hash_chains: vec![chain1, chain2], + }; let result1 = hash_chain_state.reveal(8)?; assert_eq!(result1, expected_hash1); @@ -269,6 +263,10 @@ mod hash_chain_state_test { let result2 = hash_chain_state.reveal(23)?; assert_eq!(result2, expected_hash2); + let result_boundary = hash_chain_state.reveal(20)?; + let expected_boundary = hash_chain_state.hash_chains[1].reveal_ith(0)?; + assert_eq!(result_boundary, expected_boundary); + let result3 = hash_chain_state.reveal(15); assert!(result3.is_err()); @@ -276,14 +274,24 @@ mod hash_chain_state_test { } #[test] - fn test_reveal_at_offset() -> Result<()> { - let chain = PebbleHashChain::new([0u8; 32], 10, 1); - let expected_hash = chain.reveal_ith(0)?; + fn test_hash_chain_state_overlapping_chains() -> Result<()> { + let chain1 = PebbleHashChain::new([0u8; 32], 10, 1); + let chain2 = PebbleHashChain::new([1u8; 32], 10, 1); - let hash_chain_state = HashChainState::from_chain_at_offset(5, chain); - let result = hash_chain_state.reveal(5)?; + let hash_chain_state = HashChainState { + offsets: vec![5, 10], + hash_chains: vec![chain1, chain2], + }; + + let result1 = hash_chain_state.reveal(8)?; + let expected1 = hash_chain_state.hash_chains[0].reveal_ith(3)?; + assert_eq!(result1, expected1); + + // returns the first offset that is > sequence_number) + let result2 = hash_chain_state.reveal(12)?; + let expected2 = hash_chain_state.hash_chains[1].reveal_ith(2)?; + assert_eq!(result2, expected2); - assert_eq!(result, expected_hash); Ok(()) } }