Skip to content

Commit 9dc1281

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 4f79c32 commit 9dc1281

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
@@ -155,6 +155,11 @@ pub fn verify_merkle_root_with_txids(
155155
/// Computes the merkle root from caller-supplied transaction IDs and compares
156156
/// it to the block header. Mutation is intentionally ignored here; the later
157157
/// consensus path owns the mutation check and its error precedence.
158+
///
159+
/// On a nonempty successful reduction the mutable `txids` scratch buffer is
160+
/// consumed and reduced in place to a single element (the root). Returns
161+
/// `false` for empty input, encoding failure, or a root that does not match
162+
/// the block header's merkle root.
158163
#[doc(hidden)]
159164
pub fn block_merkle_root_matches_txids(block: &bitcoin::Block, txids: &mut Vec<Txid>) -> bool {
160165
match merkle_root_and_mutation(txids) {
@@ -278,6 +283,7 @@ mod tests {
278283
};
279284
use crate::ConsensusError;
280285
use crate::rust_path::TipState;
286+
use crate::sha256d64::detect_avx2;
281287

282288
#[test]
283289
fn valid_single_coinbase_block_passes() {
@@ -557,8 +563,23 @@ mod tests {
557563
}
558564
}
559565

566+
/// Reports whether `candidate_merkle` dispatches to the AVX2 or scalar
567+
/// `SHA256d` backend. Does not assert AVX2 availability — scalar-only hosts
568+
/// and generic runners remain supported.
569+
fn candidate_reducer_backend() -> &'static str {
570+
if detect_avx2().is_some() {
571+
"avx2"
572+
} else {
573+
"scalar"
574+
}
575+
}
576+
560577
#[test]
561578
fn avx2_matches_scalar_for_all_leaf_counts_0_to_129() {
579+
eprintln!(
580+
"avx2_matches_scalar_for_all_leaf_counts_0_to_129: candidate reducer backend = {}",
581+
candidate_reducer_backend()
582+
);
562583
for leaf_count in 0..=129 {
563584
let txids = txids(leaf_count);
564585
let mut avx = txids.clone();
@@ -571,6 +592,10 @@ mod tests {
571592

572593
#[test]
573594
fn lane_boundary_pairs_seven_and_eight() {
595+
eprintln!(
596+
"lane_boundary_pairs_seven_and_eight: candidate reducer backend = {}",
597+
candidate_reducer_backend()
598+
);
574599
for leaf_count in [14, 15, 16, 17, 31, 32, 33] {
575600
let txids = txids(leaf_count);
576601
let mut avx = txids.clone();
@@ -585,6 +610,10 @@ mod tests {
585610

586611
#[test]
587612
fn nonadjacent_duplicates_are_not_mutated() {
613+
eprintln!(
614+
"nonadjacent_duplicates_are_not_mutated: candidate reducer backend = {}",
615+
candidate_reducer_backend()
616+
);
588617
let a = txid(1);
589618
let b = txid(2);
590619

@@ -602,6 +631,10 @@ mod tests {
602631

603632
#[test]
604633
fn synthetic_odd_duplicate_distinguishes_padding_from_mutation() {
634+
eprintln!(
635+
"synthetic_odd_duplicate_distinguishes_padding_from_mutation: candidate reducer backend = {}",
636+
candidate_reducer_backend()
637+
);
605638
let a = txid(1);
606639
let b = txid(2);
607640

@@ -626,6 +659,10 @@ mod tests {
626659

627660
#[test]
628661
fn core_ambiguous_six_leaf_tree_vs_duplicated_tail() {
662+
eprintln!(
663+
"core_ambiguous_six_leaf_tree_vs_duplicated_tail: candidate reducer backend = {}",
664+
candidate_reducer_backend()
665+
);
629666
// Core test vector: [1..6] and [1..6, 5, 6] share a root but only the
630667
// duplicated version is mutated.
631668
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)