Skip to content

Commit 0fc8f7f

Browse files
committed
fix hash_structure_good function and improve preimage performance
1 parent 1d4a2e7 commit 0fc8f7f

File tree

1 file changed

+30
-52
lines changed

1 file changed

+30
-52
lines changed

src/lib.rs

Lines changed: 30 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -410,28 +410,17 @@ pub fn hash(salt: &[u8], rom: &Rom, nb_loops: u32, nb_instrs: u32) -> [u8; 64] {
410410
vm.finalize()
411411
}
412412

413-
pub fn hash_structure_good(hash: &[u8], zero_bits: usize) -> bool {
414-
let full_bytes = zero_bits / 8; // Number of full zero bytes
415-
let remaining_bits = zero_bits % 8; // Bits to check in the next byte
416-
417-
// Check full zero bytes
418-
if hash.len() < full_bytes || hash[..full_bytes].iter().any(|&b| b != 0) {
419-
return false;
420-
}
421-
422-
if remaining_bits == 0 {
423-
return true;
424-
}
425-
if hash.len() > full_bytes {
426-
// Mask for the most significant bits
427-
let mask = 0xFF << (8 - remaining_bits);
428-
hash[full_bytes] & mask == 0
429-
} else {
430-
false
413+
pub fn hash_structure_good(hash: &[u8], difficulty_mask: u32) -> bool {
414+
let u32_ptr = hash.as_ptr() as *const u32;
415+
unsafe {
416+
let value = u32_ptr.read_unaligned().to_be();
417+
if (value | difficulty_mask) == difficulty_mask {
418+
return true
419+
}
431420
}
421+
false
432422
}
433423

434-
435424
// --------------------------------------------------------------------------
436425
// SCAVENGE LOGIC
437426
// --------------------------------------------------------------------------
@@ -442,12 +431,11 @@ pub struct Thread {}
442431
#[derive(Clone)]
443432
pub struct ChallengeParams {
444433
pub rom_key: String, // no_pre_mine hex string (used for ROM init)
445-
pub difficulty_mask: String, // difficulty hex string (used for submission check)
434+
pub difficulty_mask: u32, // difficulty mask (used for submission check)
446435
pub address: String, // Registered Cardano address
447436
pub challenge_id: String,
448437
pub latest_submission: String,
449438
pub no_pre_mine_hour: String,
450-
pub required_zero_bits: usize, // Derived from difficulty_mask
451439
pub rom: Arc<Rom>,
452440
}
453441

@@ -462,7 +450,7 @@ pub fn build_preimage(
462450
nonce: u64,
463451
address: &str,
464452
challenge_id: &str,
465-
difficulty: &str,
453+
difficulty_mask: u32,
466454
no_pre_mine: &str,
467455
latest_submission: &str,
468456
no_pre_mine_hour: &str,
@@ -472,26 +460,19 @@ pub fn build_preimage(
472460
preimage.push_str(&nonce_hex);
473461
preimage.push_str(address);
474462
preimage.push_str(challenge_id);
475-
preimage.push_str(difficulty);
463+
preimage.push_str(&format!("{:08X}", difficulty_mask));
476464
preimage.push_str(no_pre_mine);
477465
preimage.push_str(latest_submission);
478466
preimage.push_str(no_pre_mine_hour);
479467
preimage
480468
}
481469

482-
// Utility function to convert difficulty mask (e.g., "000FFFFF") to number of required zero bits
483-
fn difficulty_to_zero_bits(difficulty_hex: &str) -> usize {
484-
let difficulty_bytes = hex::decode(difficulty_hex).unwrap();
485-
let mut zero_bits = 0;
486-
for &byte in difficulty_bytes.iter() {
487-
if byte == 0x00 {
488-
zero_bits += 8;
489-
} else {
490-
zero_bits += byte.leading_zeros() as usize;
491-
break;
492-
}
493-
}
494-
zero_bits
470+
fn update_preimage_nonce(preimage_string: &mut String, nonce: u64) {
471+
let bytes = unsafe {
472+
preimage_string.as_bytes_mut()
473+
};
474+
let nonce_str = format!("{:016x}", nonce);
475+
bytes[..16].copy_from_slice(nonce_str.as_bytes());
495476
}
496477

497478
// The worker thread function
@@ -501,22 +482,21 @@ fn spin(params: ChallengeParams, sender: Sender<Result>, stop_signal: Arc<Atomic
501482
const NB_LOOPS: u32 = 8;
502483
const NB_INSTRS: u32 = 256;
503484

504-
let my_address = &params.address;
485+
let mut preimage_string = build_preimage(
486+
nonce_value,
487+
&params.address,
488+
&params.challenge_id,
489+
params.difficulty_mask,
490+
&params.rom_key,
491+
&params.latest_submission,
492+
&params.no_pre_mine_hour,
493+
);
505494

506495
while !stop_signal.load(Ordering::Relaxed) {
507-
let preimage_string = build_preimage(
508-
nonce_value,
509-
my_address,
510-
&params.challenge_id,
511-
&params.difficulty_mask,
512-
&params.rom_key,
513-
&params.latest_submission,
514-
&params.no_pre_mine_hour,
515-
);
516496
let preimage_bytes = preimage_string.as_bytes();
517497
let h = hash(preimage_bytes, &params.rom, NB_LOOPS, NB_INSTRS);
518498

519-
if hash_structure_good(&h, params.required_zero_bits) {
499+
if hash_structure_good(&h, params.difficulty_mask) {
520500
if sender.send(Result::Found(nonce_value)).is_ok() {
521501
// Sent the found nonce
522502
}
@@ -529,6 +509,7 @@ fn spin(params: ChallengeParams, sender: Sender<Result>, stop_signal: Arc<Atomic
529509

530510
// Increment nonce by the thread step size
531511
nonce_value = nonce_value.wrapping_add(step_size);
512+
update_preimage_nonce(&mut preimage_string, nonce_value);
532513
}
533514
}
534515

@@ -545,9 +526,7 @@ pub fn scavenge(
545526
const MB: usize = 1024 * 1024;
546527
const GB: usize = 1024 * MB;
547528

548-
let required_zero_bits = difficulty_to_zero_bits(&difficulty);
549-
550-
// We rely on the caller to print required_zero_bits
529+
let difficulty_mask = u32::from_str_radix(&difficulty, 16).unwrap();
551530

552531
let nb_threads_u64 = nb_threads as u64;
553532
let step_size = nb_threads_u64;
@@ -570,12 +549,11 @@ pub fn scavenge(
570549

571550
let common_params = ChallengeParams {
572551
rom_key: no_pre_mine_key.clone(),
573-
difficulty_mask: difficulty.clone(),
552+
difficulty_mask,
574553
address: my_registered_address.clone(),
575554
challenge_id: challenge_id.clone(),
576555
latest_submission: latest_submission.clone(),
577556
no_pre_mine_hour: no_pre_mine_hour.clone(),
578-
required_zero_bits,
579557
rom: Arc::new(rom),
580558
};
581559

0 commit comments

Comments
 (0)