From 5e23410627ac22f2380e49329208af742b1d827a Mon Sep 17 00:00:00 2001 From: Pranav Gaddamadugu <23022326+d0cd@users.noreply.github.com> Date: Thu, 4 Apr 2024 12:25:36 -0700 Subject: [PATCH 1/3] Add fix --- ledger/block/src/verify.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ledger/block/src/verify.rs b/ledger/block/src/verify.rs index ace54ab287..6250782a3c 100644 --- a/ledger/block/src/verify.rs +++ b/ledger/block/src/verify.rs @@ -373,7 +373,7 @@ impl Block { expected_last_coinbase_target, expected_last_coinbase_timestamp, ) = to_next_targets::( - self.cumulative_proof_target(), + previous_block.cumulative_proof_target(), combined_proof_target, previous_block.coinbase_target(), previous_block.cumulative_weight(), From 8153718a836a9c512be06484291db48e9d2eec71 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Thu, 4 Apr 2024 23:15:27 -0400 Subject: [PATCH 2/3] Add test to check cumulative proof target correctness through several blocks --- ledger/src/tests.rs | 82 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/ledger/src/tests.rs b/ledger/src/tests.rs index d365c61c40..7d64f20b7c 100644 --- a/ledger/src/tests.rs +++ b/ledger/src/tests.rs @@ -1810,6 +1810,88 @@ mod valid_solutions { assert_eq!(block.aborted_solution_ids().len(), 0) } + #[test] + fn test_cumulative_proof_target_correctness() { + // Initialize the test environment. + let rng = &mut TestRng::default(); + let crate::test_helpers::TestEnv { ledger, private_key, address, .. } = + crate::test_helpers::sample_test_env(rng); + + // Retrieve the puzzle parameters. + let puzzle = ledger.puzzle(); + + // Initialize block height. + let mut block_height = ledger.latest_height(); + + // Start a local counter of proof targets. + let mut combined_targets = 0; + + // Run through 25 blocks of target adjustment. + while block_height < 25 { + // Get coinbase puzzle data from the latest block. + let block = ledger.latest_block(); + let coinbase_target = block.coinbase_target(); + let coinbase_threshold = coinbase_target.saturating_div(2); + let latest_epoch_hash = ledger.latest_epoch_hash().unwrap(); + let latest_proof_target = ledger.latest_proof_target(); + + // Initialize a vector for valid solutions for this block. + let mut solutions = vec![]; + + // Loop through proofs until two that meet the threshold are found. + loop { + if let Ok(solution) = puzzle.prove(latest_epoch_hash, address, rng.gen(), Some(latest_proof_target)) { + // Get the proof target. + let proof_target = puzzle.get_proof_target(&solution).unwrap(); + + // Update the local combined target counter and store the solution. + combined_targets += proof_target; + solutions.push(solution); + + // If two have been found, exit the solver loop. + if solutions.len() >= 2 { + break; + } + } + } + + // If the combined target exceeds the coinbase threshold reset it. + if combined_targets > coinbase_threshold { + combined_targets = 0; + } + + // Get a transfer transaction to ensure solutions can be included in the block. + let inputs = [Value::from_str(&format!("{address}")).unwrap(), Value::from_str("10u64").unwrap()]; + let transfer_transaction = ledger + .vm + .execute(&private_key, ("credits.aleo", "transfer_public"), inputs.iter(), None, 0, None, rng) + .unwrap(); + + // Generate the next prospective block. + let next_block = ledger + .prepare_advance_to_next_beacon_block( + &private_key, + vec![], + solutions, + vec![transfer_transaction.clone()], + rng, + ) + .unwrap(); + + // Ensure the combined target matches the expected value. + assert_eq!(combined_targets as u128, next_block.cumulative_proof_target()); + + // Ensure the next block is correct. + ledger.check_next_block(&next_block, rng).unwrap(); + + // Advanced to the next block. + ledger.advance_to_next_block(&next_block).unwrap(); + + // Set the latest block height. + block_height = ledger.latest_height(); + } + } + #[test] fn test_excess_invalid_solution_ids() { // Note that the sum of `NUM_INVALID_SOLUTIONS` and `NUM_VALID_SOLUTIONS` should exceed the maximum number of solutions. From 9739d9de4f8b4483ea4338e6f40cd929f4ccb005 Mon Sep 17 00:00:00 2001 From: Pranav Gaddamadugu <23022326+d0cd@users.noreply.github.com> Date: Thu, 4 Apr 2024 21:14:13 -0700 Subject: [PATCH 3/3] Adjust test --- ledger/src/tests.rs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/ledger/src/tests.rs b/ledger/src/tests.rs index 7d64f20b7c..5f8f3182c0 100644 --- a/ledger/src/tests.rs +++ b/ledger/src/tests.rs @@ -1748,7 +1748,7 @@ mod valid_solutions { #[test] fn test_duplicate_solution_ids() { - // Print the cfg to ensure that the test is running in the correct environment. + // Initialize an RNG. let rng = &mut TestRng::default(); // Initialize the test environment. @@ -1812,8 +1812,13 @@ mod valid_solutions { #[test] fn test_cumulative_proof_target_correctness() { - // Initialize the test environment. + // The number of blocks to test. + const NUM_BLOCKS: u32 = 25; + + // Initialize an RNG. let rng = &mut TestRng::default(); + + // Initialize the test environment. let crate::test_helpers::TestEnv { ledger, private_key, address, .. } = crate::test_helpers::sample_test_env(rng); @@ -1827,7 +1832,7 @@ mod valid_solutions { let mut combined_targets = 0; // Run through 25 blocks of target adjustment. - while block_height < 25 { + while block_height < NUM_BLOCKS { // Get coinbase puzzle data from the latest block. let block = ledger.latest_block(); let coinbase_target = block.coinbase_target(); @@ -1835,8 +1840,11 @@ mod valid_solutions { let latest_epoch_hash = ledger.latest_epoch_hash().unwrap(); let latest_proof_target = ledger.latest_proof_target(); + // Sample the number of solutions to generate. + let num_solutions = rng.gen_range(1..=CurrentNetwork::MAX_SOLUTIONS); + // Initialize a vector for valid solutions for this block. - let mut solutions = vec![]; + let mut solutions = Vec::with_capacity(num_solutions); // Loop through proofs until two that meet the threshold are found. loop { @@ -1849,14 +1857,14 @@ mod valid_solutions { solutions.push(solution); // If two have been found, exit the solver loop. - if solutions.len() >= 2 { + if solutions.len() >= num_solutions { break; } } } // If the combined target exceeds the coinbase threshold reset it. - if combined_targets > coinbase_threshold { + if combined_targets >= coinbase_threshold { combined_targets = 0; } @@ -1898,6 +1906,7 @@ mod valid_solutions { const NUM_INVALID_SOLUTIONS: usize = CurrentNetwork::MAX_SOLUTIONS; const NUM_VALID_SOLUTIONS: usize = CurrentNetwork::MAX_SOLUTIONS; + // Initialize an RNG. let rng = &mut TestRng::default(); // Initialize the test environment. @@ -1983,6 +1992,7 @@ mod valid_solutions { // Note that this should be greater than the maximum number of solutions. const NUM_VALID_SOLUTIONS: usize = 2 * CurrentNetwork::MAX_SOLUTIONS; + // Initialize an RNG. let rng = &mut TestRng::default(); // Initialize the test environment.