dg_fast_farmer 2.1.0

A lite farmer for the Chia Blockchain.
Documentation
use crate::PROTOCOL_VERSION;
use crate::farmer::FarmerSharedState;
use crate::farmer::config::Config;
use crate::harvesters::{Harvester, SignatureHandler};
use async_trait::async_trait;
use dg_xch_clients::api::pool::PoolClient;
use dg_xch_clients::websocket::farmer::FarmerClient;
use dg_xch_core::blockchain::sized_bytes::Bytes32;
use dg_xch_core::consensus::constants::ConsensusConstants;
use dg_xch_core::protocols::farmer::RequestSignedValues;
use dg_xch_core::protocols::harvester::{
    RequestSignatures, SignatureRequestSourceData, SigningDataKind,
};
use dg_xch_core::protocols::{ChiaMessage, MessageHandler, PeerMap};
use dg_xch_serialize::ChiaSerialize;
use log::{debug, error};
use std::io::{Cursor, Error, ErrorKind};
use std::sync::Arc;
use tokio::sync::RwLock;
use uuid::Uuid;

pub struct RequestSignedValuesHandle<P, S, T, H, C>
where
    P: PoolClient + Sized + Sync + Send + 'static,
    S: SignatureHandler<T, H, C> + Sync + Send + 'static,
    T: Sync + Send + 'static,
    H: Harvester<T, H, C> + Sync + Send + 'static,
    C: Sync + Send + Clone + 'static,
{
    pub id: Uuid,
    pub shared_state: Arc<FarmerSharedState<T>>,
    pub pool_client: Arc<P>,
    pub harvester: Arc<H>,
    pub constants: &'static ConsensusConstants,
    pub config: Arc<RwLock<Config<C>>>,
    pub client: Arc<RwLock<Option<FarmerClient<T>>>>,
    pub signature_handle: Arc<S>,
}
#[async_trait]
impl<P, S, T, H, C> MessageHandler for RequestSignedValuesHandle<P, S, T, H, C>
where
    P: PoolClient + Default + Sized + Sync + Send + 'static,
    S: SignatureHandler<T, H, C> + Sync + Send + 'static,
    T: Sync + Send + 'static,
    H: Harvester<T, H, C> + Sync + Send + 'static,
    C: Sync + Send + Clone + 'static,
{
    async fn handle(
        &self,
        msg: Arc<ChiaMessage>,
        _peer_id: Arc<Bytes32>,
        _peers: PeerMap,
    ) -> Result<(), Error> {
        debug!("RequestSignedValues Message. Starting Deserialization.");
        let mut cursor = Cursor::new(&msg.data);
        let request = RequestSignedValues::from_bytes(&mut cursor, PROTOCOL_VERSION)?;
        debug!("RequestSignedValues Message. Finished Deserialization.");
        if let Some(identifier) = self
            .shared_state
            .quality_to_identifiers
            .read()
            .await
            .get(&request.quality_string)
        {
            debug!("Found Identifier for {}", &request.quality_string);
            let mut foliage_block_data = None;
            let mut foliage_transaction_block = None;
            if let Some(data) = request.foliage_block_data {
                foliage_block_data = Some(SignatureRequestSourceData {
                    kind: SigningDataKind::FoliageBlockData,
                    data: data.to_bytes(PROTOCOL_VERSION)?,
                });
            }
            if let Some(data) = request.foliage_transaction_block_data {
                foliage_transaction_block = Some(SignatureRequestSourceData {
                    kind: SigningDataKind::FoliageTransactionBlock,
                    data: data.to_bytes(PROTOCOL_VERSION)?,
                });
            }
            let request = RequestSignatures {
                plot_identifier: identifier.plot_identifier.clone(),
                challenge_hash: identifier.challenge_hash,
                sp_hash: identifier.sp_hash,
                messages: vec![
                    request.foliage_block_data_hash,
                    request.foliage_transaction_block_hash,
                ],
                message_data: Some(vec![foliage_block_data, foliage_transaction_block]),
                rc_block_unfinished: request.rc_block_unfinished,
            };
            let harvester = self.harvester.clone();
            let shared_state = self.shared_state.clone();
            let config = self.config.clone();
            let client = self.client.clone();
            tokio::spawn(async move {
                let handle = S::load(shared_state, config, harvester.clone(), client).await?;
                if let Err(e) = harvester.request_signatures(request, handle).await {
                    error!("Error Requesting Signature: {e}");
                }
                Ok::<(), Error>(())
            });
            Ok(())
        } else {
            error!("Do not have quality {}", &request.quality_string);
            Err(Error::new(
                ErrorKind::NotFound,
                format!("Do not have quality {}", &request.quality_string),
            ))
        }
    }
}