|
|
@@ -27,7 +27,10 @@ use tracing::info;
|
|
|
use crate::{
|
|
|
blockchain::{BlockInfo, BlockchainOverlayPtr, Header},
|
|
|
runtime::vm_runtime::Runtime,
|
|
|
- validator::consensus::{Fork, Proposal},
|
|
|
+ validator::{
|
|
|
+ consensus::{Fork, Proposal},
|
|
|
+ pow::PoWModule,
|
|
|
+ },
|
|
|
Error, Result,
|
|
|
};
|
|
|
|
|
|
@@ -108,30 +111,25 @@ pub async fn deploy_native_contracts(
|
|
|
Ok(())
|
|
|
}
|
|
|
|
|
|
-/// Verify provided header is valid for provided mining target and compute its rank.
|
|
|
+/// Verify provided header is valid for provided PoW module and compute
|
|
|
+/// its rank.
|
|
|
+/// Returns next mine difficulty, along with the computed rank.
|
|
|
///
|
|
|
-/// Header's rank is the tuple of its squared mining target distance from max 32 bytes int,
|
|
|
-/// along with its squared RandomX hash number distance from max 32 bytes int.
|
|
|
+/// Header's rank is the tuple of its squared mining target distance
|
|
|
+/// from max 32 bytes int, along with its squared RandomX hash number
|
|
|
+/// distance from max 32 bytes int.
|
|
|
/// Genesis block has rank (0, 0).
|
|
|
-pub fn header_rank(header: &Header, target: &BigUint) -> Result<(BigUint, BigUint)> {
|
|
|
+pub fn header_rank(module: &PoWModule, header: &Header) -> Result<(BigUint, BigUint, BigUint)> {
|
|
|
+ // Grab next mine target and difficulty
|
|
|
+ let (target, difficulty) = module.next_mine_target_and_difficulty()?;
|
|
|
+
|
|
|
// Genesis header has rank 0
|
|
|
if header.height == 0 {
|
|
|
- return Ok((0u64.into(), 0u64.into()))
|
|
|
+ return Ok((difficulty, 0u64.into(), 0u64.into()))
|
|
|
}
|
|
|
|
|
|
- // Setup RandomX verifier
|
|
|
- let flags = RandomXFlags::get_recommended_flags();
|
|
|
- let cache = RandomXCache::new(flags, header.previous.inner()).unwrap();
|
|
|
- let vm = RandomXVM::new(flags, Some(cache), None).unwrap();
|
|
|
-
|
|
|
- // Compute the output hash
|
|
|
- let out_hash = vm.calculate_hash(header.hash().inner())?;
|
|
|
- let out_hash = BigUint::from_bytes_le(&out_hash);
|
|
|
-
|
|
|
// Verify hash is less than the expected mine target
|
|
|
- if out_hash > *target {
|
|
|
- return Err(Error::PoWInvalidOutHash)
|
|
|
- }
|
|
|
+ let out_hash = module.verify_block_target(header, &target)?;
|
|
|
|
|
|
// Grab the max 32 bytes int
|
|
|
let max = BigUint::from_bytes_le(&[0xFF; 32]);
|
|
|
@@ -144,7 +142,7 @@ pub fn header_rank(header: &Header, target: &BigUint) -> Result<(BigUint, BigUin
|
|
|
let hash_distance = max - out_hash;
|
|
|
let hash_distance_sq = &hash_distance * &hash_distance;
|
|
|
|
|
|
- Ok((target_distance_sq, hash_distance_sq))
|
|
|
+ Ok((difficulty, target_distance_sq, hash_distance_sq))
|
|
|
}
|
|
|
|
|
|
/// Compute a block's rank, assuming that its valid, based on provided mining target.
|