use bitcoin::hashes::sha256d::Hash;
use std::collections::HashSet;
#[derive(Debug)]
pub enum ShareValidationResult {
Valid(Hash),
BlockFound(Hash, Option<u64>, Vec<u8>),
}
#[derive(Debug)]
pub enum ShareValidationError {
Invalid,
Stale,
InvalidJobId,
DoesNotMeetTarget,
VersionRollingNotAllowed,
DuplicateShare,
InvalidCoinbase,
NoChainTip,
BadExtranonceSize,
}
#[derive(Clone, Debug)]
pub struct ShareAccounting {
last_share_sequence_number: u32,
shares_accepted: u32,
share_work_sum: f64,
last_batch_accepted: u32,
last_batch_work_sum: f64,
batch_acknowledged: bool,
share_batch_size: usize,
seen_shares: HashSet<Hash>,
best_diff: f64,
blocks_found: u32,
}
impl ShareAccounting {
pub fn new(share_batch_size: usize) -> Self {
Self {
last_share_sequence_number: 0,
shares_accepted: 0,
share_work_sum: 0.0,
last_batch_accepted: 0,
last_batch_work_sum: 0.0,
batch_acknowledged: false,
share_batch_size,
seen_shares: HashSet::new(),
best_diff: 0.0,
blocks_found: 0,
}
}
pub fn update_share_accounting(
&mut self,
share_work: f64,
share_sequence_number: u32,
share_hash: Hash,
) {
self.last_share_sequence_number = share_sequence_number;
self.shares_accepted += 1;
self.share_work_sum += share_work;
self.seen_shares.insert(share_hash);
if self.batch_acknowledged || self.should_acknowledge() {
self.last_batch_accepted = 1;
self.last_batch_work_sum = share_work;
self.batch_acknowledged = false;
} else {
self.last_batch_accepted += 1;
self.last_batch_work_sum += share_work;
}
}
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_last_batch_accepted(&self) -> u32 {
self.last_batch_accepted
}
pub fn get_last_batch_work_sum(&self) -> f64 {
self.last_batch_work_sum
}
pub fn get_shares_accepted(&self) -> u32 {
self.shares_accepted
}
pub fn get_share_work_sum(&self) -> f64 {
self.share_work_sum
}
pub fn get_share_batch_size(&self) -> usize {
self.share_batch_size
}
pub fn should_acknowledge(&self) -> bool {
self.last_batch_accepted == self.share_batch_size as u32
}
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 mark_batch_acknowledged(&mut self) {
self.batch_acknowledged = true;
}
pub fn get_blocks_found(&self) -> u32 {
self.blocks_found
}
}