use neptune_consensus::block::Block;
use neptune_consensus::block::pow::LustrationStatus;
use neptune_consensus::block::pow::PowMastPaths;
use neptune_primitives::difficulty_control::Difficulty;
use serde::Deserialize;
use serde::Serialize;
use tasm_lib::prelude::Digest;
use tasm_lib::triton_vm::prelude::BFieldElement;
use crate::model::block::RpcBlock;
use crate::model::common::RpcNativeCurrencyAmount;
#[derive(Clone, Debug, Copy, Serialize, Deserialize)]
pub struct RpcBlockTemplateMetadata {
pub digest: Digest,
pub prev_block: Digest,
pub threshold: Digest,
pub total_guesser_reward: RpcNativeCurrencyAmount,
pub pow_mast_paths: PowMastPaths,
pub lustration_status: Option<LustrationStatus>,
pub version: BFieldElement,
}
impl RpcBlockTemplateMetadata {
pub fn new(block_proposal: &Block, difficulty: Difficulty) -> Self {
let digest = block_proposal.hash();
let prev_block = block_proposal.header().prev_block_digest;
let threshold = difficulty.target();
let guesser_reward = block_proposal
.body()
.total_guesser_reward()
.expect("Block proposal must have well-defined guesser reward");
let auth_paths = block_proposal.pow_mast_paths();
let lustration_status = block_proposal.header().pow.lustration_status().ok();
Self {
digest,
prev_block,
threshold,
total_guesser_reward: guesser_reward.into(),
pow_mast_paths: auth_paths,
lustration_status,
version: block_proposal.header().version,
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct RpcBlockTemplate {
pub block: RpcBlock,
pub metadata: RpcBlockTemplateMetadata,
}
#[cfg(any(test, feature = "test-helpers"))]
impl RpcBlockTemplateMetadata {
pub fn solve(
&self,
consensus_rule_set: neptune_consensus::consensus_rule_set::ConsensusRuleSet,
) -> crate::model::block::header::RpcBlockPow {
use neptune_consensus::block::block_header::BlockPow;
use tasm_lib::twenty_first::bfe_array;
assert!(
!consensus_rule_set.memory_hard_pow(),
"solving pre-hardfork-beta (memory-hard) proof-of-work is not supported"
);
let solution = (0u64..u64::MAX)
.map(|i| {
let nonce = Digest(bfe_array![0, 0, 0, 0, i]);
BlockPow::guess(
&self.pow_mast_paths,
nonce,
self.threshold,
self.lustration_status,
Some(self.version),
)
})
.find_map(|x| x)
.expect("Should find solution within 2^{64} attempts");
solution.into()
}
}