Skip to content

Commit

Permalink
Merge pull request #2422 from AleoHQ/fix/proof-target
Browse files Browse the repository at this point in the history
Use previous block for proof target.
  • Loading branch information
howardwu authored Apr 5, 2024
2 parents 13268a3 + 4aa50b9 commit ed20562
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 2 deletions.
2 changes: 1 addition & 1 deletion ledger/block/src/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ impl<N: Network> Block<N> {
expected_last_coinbase_target,
expected_last_coinbase_timestamp,
) = to_next_targets::<N>(
self.cumulative_proof_target(),
previous_block.cumulative_proof_target(),
combined_proof_target,
previous_block.coinbase_target(),
previous_block.cumulative_weight(),
Expand Down
94 changes: 93 additions & 1 deletion ledger/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -1810,12 +1810,103 @@ mod valid_solutions {
assert_eq!(block.aborted_solution_ids().len(), 0)
}

#[test]
fn test_cumulative_proof_target_correctness() {
// 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);

// 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 < NUM_BLOCKS {
// 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();

// 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::with_capacity(num_solutions);

// 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() >= num_solutions {
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.
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.
Expand Down Expand Up @@ -1901,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.
Expand Down

0 comments on commit ed20562

Please sign in to comment.