fix: sync with the latest lez changes

This commit is contained in:
Roman 2026-05-07 14:27:44 +08:00
parent fb6071e72a
commit e512f7a4df
No known key found for this signature in database
GPG Key ID: 583BDF43C238B83E
4 changed files with 2976 additions and 195 deletions

1568
Cargo.lock generated

File diff suppressed because it is too large Load Diff

1568
fuzz/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -2,26 +2,39 @@
use common::block::{Block, HashableBlockData};
use libfuzzer_sys::fuzz_target;
use nssa::PrivateKey;
// A fixed, valid signing key used only to exercise the hash-computation path.
// The specific key value is irrelevant to hash correctness.
const DUMMY_KEY_BYTES: [u8; 32] = [1u8; 32];
fuzz_target!(|data: &[u8]| {
let Ok(block) = borsh::from_slice::<Block>(data) else {
return;
};
// Convert to hashable form and re-derive the block hash
let hashable = HashableBlockData::from(block.clone());
let signing_key = PrivateKey::try_new(DUMMY_KEY_BYTES).expect("constant key is valid");
let bedrock_parent_id = [0u8; 32];
// INVARIANT: block_hash() must never panic regardless of fuzz input
let recomputed = hashable.block_hash();
// Convert to hashable form twice so we can check determinism without
// moving the value into the first call.
let hashable1 = HashableBlockData::from(block.clone());
let hashable2 = HashableBlockData::from(block.clone());
// INVARIANT: block_hash() must be deterministic
let recomputed2 = hashable.block_hash();
assert_eq!(recomputed, recomputed2, "block_hash() is not deterministic");
// INVARIANT: into_pending_block() must never panic regardless of fuzz input
let recomputed1 = hashable1.into_pending_block(&signing_key, bedrock_parent_id);
let hash1 = recomputed1.header.hash;
// INVARIANT: hash derivation must be deterministic
let recomputed2 = hashable2.into_pending_block(&signing_key, bedrock_parent_id);
let hash2 = recomputed2.header.hash;
assert_eq!(hash1, hash2, "block hash is not deterministic");
// We intentionally do NOT assert that the stored header hash equals the
// recomputed one: adversarially-crafted fuzz inputs can store an arbitrary
// hash field that does not match the body content, and that is a valid input
// for the purpose of this target (which only tests hash stability, not
// block validity).
let _ = (block.header.hash, recomputed);
let _ = block.header.hash;
});

View File

@ -22,7 +22,7 @@ fuzz_target!(|data: &[u8]| {
if let Ok(key_wrap) = ArbPrivateKey::arbitrary(&mut u) {
let private_key = key_wrap.0;
let public_key = PublicKey::new_from_private_key(&private_key);
let msg: Vec<u8> = u.arbitrary().unwrap_or_default();
let msg: [u8; 32] = u.arbitrary().unwrap_or_default();
let sig = Signature::new(&private_key, &msg);
assert!(
@ -36,7 +36,7 @@ fuzz_target!(|data: &[u8]| {
ArbSignature::arbitrary(&mut u),
ArbPublicKey::arbitrary(&mut u),
) {
let msg: Vec<u8> = u.arbitrary().unwrap_or_default();
let msg: [u8; 32] = u.arbitrary().unwrap_or_default();
// The result may be true or false — we only assert no panic.
let _ = sig_wrap.0.is_valid_for(&msg, &pk_wrap.0);
}
@ -47,7 +47,7 @@ fuzz_target!(|data: &[u8]| {
ArbPrivateKey::arbitrary(&mut u),
) {
let public_b = PublicKey::new_from_private_key(&key_b_wrap.0);
let msg: Vec<u8> = u.arbitrary().unwrap_or_default();
let msg: [u8; 32] = u.arbitrary().unwrap_or_default();
let sig_from_a = Signature::new(&key_a_wrap.0, &msg);
// Must not panic regardless of key mismatch.
let _ = sig_from_a.is_valid_for(&msg, &public_b);