extern crate alloc;
use super::{HashMap, HashSet};
use alloc::string::String;
use bitcoin::hashes::sha256d::Hash;
#[derive(Debug)]
pub enum ShareValidationResult {
Valid(Hash),
BlockFound(Hash),
}
#[derive(Debug)]
pub enum ShareValidationError {
Invalid(&'static str),
Stale(&'static str),
InvalidJobId(&'static str),
DoesNotMeetTarget(&'static str),
VersionRollingNotAllowed(&'static str),
DuplicateShare(&'static str),
BadExtranonceSize(&'static str),
NoChainTip,
}
#[derive(Clone, Debug)]
pub struct ShareAccounting {
last_share_sequence_number: u32,
acknowledged_shares: u32,
acknowledged_work_sum: u64,
validated_shares: u32,
validated_work_sum: f64,
rejected_shares: HashMap<String, u32>, seen_shares: HashSet<Hash>,
best_diff: f64,
blocks_found: u32,
}
impl Default for ShareAccounting {
fn default() -> Self {
Self::new()
}
}
impl ShareAccounting {
pub fn new() -> Self {
Self {
last_share_sequence_number: 0,
acknowledged_shares: 0,
acknowledged_work_sum: 0,
validated_shares: 0,
validated_work_sum: 0.0,
rejected_shares: HashMap::new(),
seen_shares: HashSet::new(),
best_diff: 0.0,
blocks_found: 0,
}
}
pub fn on_share_acknowledgement(
&mut self,
new_submits_accepted_count: u32,
new_shares_sum: u64,
) {
self.acknowledged_shares += new_submits_accepted_count;
self.acknowledged_work_sum = self.acknowledged_work_sum.saturating_add(new_shares_sum);
}
pub fn on_share_rejection(&mut self, error_code: String) {
self.rejected_shares
.entry(error_code)
.and_modify(|v| *v += 1)
.or_insert(1);
}
pub fn track_validated_share(
&mut self,
share_sequence_number: u32,
share_hash: Hash,
share_work: f64,
) {
self.last_share_sequence_number = share_sequence_number;
self.validated_shares += 1;
self.validated_work_sum += share_work;
self.seen_shares.insert(share_hash);
}
pub fn flush_seen_shares(&mut self) {
self.seen_shares.clear();
}
pub fn get_last_share_sequence_number(&self) -> u32 {
self.last_share_sequence_number
}
pub fn get_acknowledged_shares(&self) -> u32 {
self.acknowledged_shares
}
pub fn get_validated_shares(&self) -> u32 {
self.validated_shares
}
pub fn get_rejected_shares_error_count(&self, error_code: &str) -> u32 {
self.rejected_shares.get(error_code).copied().unwrap_or(0)
}
pub fn get_rejected_shares_count(&self) -> u32 {
self.rejected_shares.values().copied().sum()
}
pub fn get_rejected_shares(&self) -> impl Iterator<Item = (&str, u32)> + '_ {
self.rejected_shares
.iter()
.map(|(error_code, count)| (error_code.as_str(), *count))
}
pub fn get_acknowledged_work_sum(&self) -> u64 {
self.acknowledged_work_sum
}
pub fn get_validated_work_sum(&self) -> f64 {
self.validated_work_sum
}
pub fn is_share_seen(&self, share_hash: Hash) -> bool {
self.seen_shares.contains(&share_hash)
}
pub fn get_best_diff(&self) -> f64 {
self.best_diff
}
pub fn update_best_diff(&mut self, diff: f64) {
if diff > self.best_diff {
self.best_diff = diff;
}
}
pub fn increment_blocks_found(&mut self) {
self.blocks_found += 1;
}
pub fn get_blocks_found(&self) -> u32 {
self.blocks_found
}
}