Skip to content

Commit 37ef167

Browse files
committed
fix(consensus): clarify AVX validation evidence
Expose the reducer backend in tests, document scratch-buffer consumption, and make custody paths and Criterion scope portable.
1 parent 37d4ba7 commit 37ef167

3 files changed

Lines changed: 55 additions & 6 deletions

File tree

crates/consensus/src/sha256d64.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,8 +358,12 @@ mod tests {
358358
#[test]
359359
fn avx2_matches_independent_sha256d_vectors() {
360360
let Some(avx2) = detect_avx2() else {
361+
eprintln!(
362+
"test avx2_matches_independent_sha256d_vectors: AVX2 unavailable — skipping AVX2 vector test"
363+
);
361364
return;
362365
};
366+
eprintln!("test avx2_matches_independent_sha256d_vectors: running with AVX2 backend");
363367
let mut input = [[0_u8; 64]; 8];
364368
for (lane, message) in input.iter_mut().enumerate() {
365369
let lane = match u8::try_from(lane) {
@@ -387,8 +391,12 @@ mod tests {
387391
#[test]
388392
fn avx2_matches_literal_zero_message_digest() {
389393
let Some(avx2) = detect_avx2() else {
394+
eprintln!(
395+
"test avx2_matches_literal_zero_message_digest: AVX2 unavailable — skipping AVX2 zero-message test"
396+
);
390397
return;
391398
};
399+
eprintln!("test avx2_matches_literal_zero_message_digest: running with AVX2 backend");
392400
let input = [[0_u8; 64]; 8];
393401
let mut output = [[0_u8; 32]; 8];
394402
avx2.transform_8way(&input, &mut output);

crates/consensus/src/verify_block.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,11 @@ fn verify_merkle_root_with_txids(
146146
/// Computes the merkle root from caller-supplied transaction IDs and compares
147147
/// it to the block header. Mutation is intentionally ignored here; the later
148148
/// consensus path owns the mutation check and its error precedence.
149+
///
150+
/// On a nonempty successful reduction the mutable `txids` scratch buffer is
151+
/// consumed and reduced in place to a single element (the root). Returns
152+
/// `false` for empty input, encoding failure, or a root that does not match
153+
/// the block header's merkle root.
149154
#[doc(hidden)]
150155
pub fn block_merkle_root_matches_txids(block: &bitcoin::Block, txids: &mut Vec<Txid>) -> bool {
151156
match merkle_root_and_mutation(txids) {
@@ -269,6 +274,7 @@ mod tests {
269274
};
270275
use crate::ConsensusError;
271276
use crate::rust_path::TipState;
277+
use crate::sha256d64::detect_avx2;
272278

273279
#[test]
274280
fn valid_single_coinbase_block_passes() {
@@ -548,8 +554,23 @@ mod tests {
548554
}
549555
}
550556

557+
/// Reports whether `candidate_merkle` dispatches to the AVX2 or scalar
558+
/// `SHA256d` backend. Does not assert AVX2 availability — scalar-only hosts
559+
/// and generic runners remain supported.
560+
fn candidate_reducer_backend() -> &'static str {
561+
if detect_avx2().is_some() {
562+
"avx2"
563+
} else {
564+
"scalar"
565+
}
566+
}
567+
551568
#[test]
552569
fn avx2_matches_scalar_for_all_leaf_counts_0_to_129() {
570+
eprintln!(
571+
"avx2_matches_scalar_for_all_leaf_counts_0_to_129: candidate reducer backend = {}",
572+
candidate_reducer_backend()
573+
);
553574
for leaf_count in 0..=129 {
554575
let txids = txids(leaf_count);
555576
let mut avx = txids.clone();
@@ -562,6 +583,10 @@ mod tests {
562583

563584
#[test]
564585
fn lane_boundary_pairs_seven_and_eight() {
586+
eprintln!(
587+
"lane_boundary_pairs_seven_and_eight: candidate reducer backend = {}",
588+
candidate_reducer_backend()
589+
);
565590
for leaf_count in [14, 15, 16, 17, 31, 32, 33] {
566591
let txids = txids(leaf_count);
567592
let mut avx = txids.clone();
@@ -576,6 +601,10 @@ mod tests {
576601

577602
#[test]
578603
fn nonadjacent_duplicates_are_not_mutated() {
604+
eprintln!(
605+
"nonadjacent_duplicates_are_not_mutated: candidate reducer backend = {}",
606+
candidate_reducer_backend()
607+
);
579608
let a = txid(1);
580609
let b = txid(2);
581610

@@ -593,6 +622,10 @@ mod tests {
593622

594623
#[test]
595624
fn synthetic_odd_duplicate_distinguishes_padding_from_mutation() {
625+
eprintln!(
626+
"synthetic_odd_duplicate_distinguishes_padding_from_mutation: candidate reducer backend = {}",
627+
candidate_reducer_backend()
628+
);
596629
let a = txid(1);
597630
let b = txid(2);
598631

@@ -617,6 +650,10 @@ mod tests {
617650

618651
#[test]
619652
fn core_ambiguous_six_leaf_tree_vs_duplicated_tail() {
653+
eprintln!(
654+
"core_ambiguous_six_leaf_tree_vs_duplicated_tail: candidate reducer backend = {}",
655+
candidate_reducer_backend()
656+
);
620657
// Core test vector: [1..6] and [1..6, 5, 6] share a root but only the
621658
// duplicated version is mutated.
622659
let one_to_six: Vec<Txid> = (1u8..=6).map(txid).collect();

docs/benchmarks/data/end-to-end-sync/avx2-merkle-custody-v1.json

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,10 @@
404404
"parents_64_speedup": 4.564475858916201,
405405
"parents_1024_speedup": 5.5749675465166595
406406
},
407+
"criterion_notes": {
408+
"ratio_scope": "The reported criterion ratios include identical scratch-buffer refill overhead in both the candidate and scalar arms, so they are conservative end-to-end Merkle-reducer ratios rather than pure-kernel SHA256d ratios.",
409+
"conservative": "Because the scalar arm benefits from the same buffer-reuse strategy as the candidate, any AVX2 kernel advantage is partially absorbed by shared setup cost, making these speedup figures lower bounds on the raw kernel speedup."
410+
},
407411
"final_source_smoke": {
408412
"command": "taskset -c 0-31 target/release/examples/mainnet_prefix_replay --stop-height 150000 --blocks-file $CORPUS --assume-valid-height 0 --storage-backend fjall --data-dir $DATA_DIR --output $OUTPUT",
409413
"label": "candidate-final-source",
@@ -415,11 +419,11 @@
415419
"stop_hash": "0000000000000a3290f20e75860d505ce0e948a1d1d846bec7e39015d242884b"
416420
},
417421
"optional_local_archive": {
418-
"fjall": "/home/alpha/bench-g14/results/avx2-merkle-paired/packet.json",
419-
"rocksdb": "/home/alpha/bench-g14/results/avx2-merkle-rocksdb-paired/packet.json",
420-
"redb": "/home/alpha/bench-g14/results/avx2-merkle-redb-paired/packet.json",
421-
"core": "/home/alpha/bench-g14/results/avx2-merkle-core-final/packet.json",
422-
"validation": "/home/alpha/bench-g14/results/avx2-merkle-validation/packet.json",
423-
"smoke": "/home/alpha/bench-g14/results/avx2-merkle-final-smoke/packet.json"
422+
"fjall": "$BENCH_RESULTS/avx2-merkle-paired/packet.json",
423+
"rocksdb": "$BENCH_RESULTS/avx2-merkle-rocksdb-paired/packet.json",
424+
"redb": "$BENCH_RESULTS/avx2-merkle-redb-paired/packet.json",
425+
"core": "$BENCH_RESULTS/avx2-merkle-core-final/packet.json",
426+
"validation": "$BENCH_RESULTS/avx2-merkle-validation/packet.json",
427+
"smoke": "$BENCH_RESULTS/avx2-merkle-final-smoke/packet.json"
424428
}
425429
}

0 commit comments

Comments
 (0)