async fn mining(mut self) -> Result<Miner, MinerError> {
        // Lets make sure its set to mine
        info!(target: LOG_TARGET, "Miner asking for new candidate block to mine.");
        let block_template = self.get_block_template().await;
        if block_template.is_err() {
            error!(
                target: LOG_TARGET,
                "Could not get block template from basenode {:?}.", block_template
            );
            return Ok(self);
        };
        let mut block_template = block_template.unwrap();
        let output = self.add_coinbase(&mut block_template);
        if output.is_err() {
            error!(
                target: LOG_TARGET,
                "Could not add coinbase to block template {:?}.", output
            );
            return Ok(self);
        };
        let output = output.unwrap();
        let block = self.get_block(block_template).await;
        if block.is_err() {
            error!(target: LOG_TARGET, "Could not get block from basenode {:?}.", block);
            return Ok(self);
        };
        self.mining_status.store(true, Ordering::Relaxed);
        let mut block = block.unwrap();
        debug!(target: LOG_TARGET, "Miner got new block to mine.");
        let (tx, mut rx): (mpscSender<Option<BlockHeader>>, mpscReceiver<Option<BlockHeader>>) =
            mpsc::channel(self.threads);
        for _ in 0..self.threads {
            let stop_mining_flag = self.stop_mining_flag.clone();
            let header = block.header.clone();
            let thread_hash_rate = self.hashrate.clone();
            let mut tx_channel = tx.clone();
            trace!("spawning mining thread");
            spawn_blocking(move || {
                let result = CpuPow::mine(header, stop_mining_flag, thread_hash_rate);
                // send back what the miner found, None will be sent if the miner did not find a nonce
                if let Err(e) = tx_channel.try_send(result) {
                    warn!(target: LOG_TARGET, "Could not return mining result: {}", e);
                }
            });
        }
        drop(tx); // lets ensure that the tx all get dropped
        while let Some(value) = rx.next().await {
            // let see if we sound a header, this will be none if no header was found
            if let Some(r) = value {
                // found block, lets ensure we kill all other threads
                self.stop_mining_flag.store(true, Ordering::Relaxed);
                block.header = r;
                let block_sent = self.send_block(block).await;

                if let Err(e) = block_sent {
                    error!(target: LOG_TARGET, "Could not send block to base node. {:?}.", e);
                    break;
                }

                let utxo_sent = self.utxo_sender.try_send(output);

                if let Err(e) = utxo_sent {
                    error!(target: LOG_TARGET, "Could not send utxo to wallet. {:?}.", e);
                    return Err(MinerError::CommunicationError(e.to_string()));
                }

                break;
            }
        }
        trace!("returning closing thread");
        Ok(self)
    }
/// Mine blocks asynchronously.
///
/// On the first iteration, the thread will loop around until `received_new_block_flag` is true. This flag is set
/// to true when either a new block is received from the node, or when the node reaches the `Listening` state
/// (see [Miner::mine]).
///
/// Then, if the miner hasn't been stopped, it starts the main mining loop:
/// 1. We request a new template block from the base node
/// 2. We add our Coinbase UTXO to the block
/// 3. We send this back to the node to calculate the MMR roots
/// 4. We iterate on the header nonce until
///     * the target difficulty is reached
///     * or the loop is interrupted because a new block was found in the interim, or the miner is stopped
Mine blocks asynchronously.
On the first iteration, the thread will loop around until `received_new_block_flag` is true. This flag is set
to true when either a new block is received from the node, or when the node reaches the `Listening` state
.

Then, if the miner hasn't been stopped, it starts the main mining loop:
1. We request a new template block from the base node
2. We add our Coinbase UTXO to the block
3. We send this back to the node to calculate the MMR roots
4. We iterate on the header nonce until
the target difficulty is reached
or the loop is interrupted because a new block was found in the interim, or the miner is stopped
Mine blocks asynchronously . On the first iteration the thread will loop around until ` received_new_block_flag ` is true . This flag is set to true when either a new block is received from the node or when the node reaches the ` Listening ` state . Then if the miner hasn ' t been stopped it starts the main mining loop : 1 . We request a new template block from the base node 2 . We add our Coinbase UTXO to the block 3 . We send this back to the node to calculate the MMR roots 4 . We iterate on the header nonce until the target difficulty is reached or the loop is interrupted because a new block was found in the interim or the miner is stopped
async fn mining(mut self) -> Result<Miner, MinerError> {
        // Lets make sure its set to mine
        info!(target: LOG_TARGET, "Miner asking for new candidate block to mine.");
        let block_template = self.get_block_template().await;
        if block_template.is_err() {
            error!(
                target: LOG_TARGET,
                "Could not get block template from basenode {:?}.", block_template
            );
            return Ok(self);
        };
        let mut block_template = block_template.unwrap();
        let output = self.add_coinbase(&mut block_template);
        if output.is_err() {
            error!(
                target: LOG_TARGET,
                "Could not add coinbase to block template {:?}.", output
            );
            return Ok(self);
        };
        let output = output.unwrap();
        let block = self.get_block(block_template).await;
        if block.is_err() {
            error!(target: LOG_TARGET, "Could not get block from basenode {:?}.", block);
            return Ok(self);
        };
        self.mining_status.store(true, Ordering::Relaxed);
        let mut block = block.unwrap();
        debug!(target: LOG_TARGET, "Miner got new block to mine.");
        let (tx, mut rx): (mpscSender<Option<BlockHeader>>, mpscReceiver<Option<BlockHeader>>) =
            mpsc::channel(self.threads);
        for _ in 0..self.threads {
            let stop_mining_flag = self.stop_mining_flag.clone();
            let header = block.header.clone();
            let thread_hash_rate = self.hashrate.clone();
            let mut tx_channel = tx.clone();
            trace!("spawning mining thread");
            spawn_blocking(move || {
                let result = CpuPow::mine(header, stop_mining_flag, thread_hash_rate);
                // send back what the miner found, None will be sent if the miner did not find a nonce
                if let Err(e) = tx_channel.try_send(result) {
                    warn!(target: LOG_TARGET, "Could not return mining result: {}", e);
                }
            });
        }
        drop(tx); // lets ensure that the tx all get dropped
        while let Some(value) = rx.next().await {
            // let see if we sound a header, this will be none if no header was found
            if let Some(r) = value {
                // found block, lets ensure we kill all other threads
                self.stop_mining_flag.store(true, Ordering::Relaxed);
                block.header = r;
                let block_sent = self.send_block(block).await;
                if let Err(e) = block_sent {
                    error!(target: LOG_TARGET, "Could not send block to base node. {:?}.", e);
                    break;
                }
                let utxo_sent = self.utxo_sender.try_send(output);
                if let Err(e) = utxo_sent {
                    error!(target: LOG_TARGET, "Could not send utxo to wallet. {:?}.", e);
                    return Err(MinerError::CommunicationError(e.to_string()));
                }
                break;
            }
        }
        trace!("returning closing thread");
        Ok(self)
    }
async fn mining ( mut self ) -> Result < Miner , MinerError > { // Lets make sure its set to mine info ! ( target LOG_TARGET " " ) ; let block_template = self . get_block_template ( ) . await ; if block_template . is_err ( ) { error ! ( target LOG_TARGET " " block_template ) ; return Ok ( self ) ; } ; let mut block_template = block_template . unwrap ( ) ; let output = self . add_coinbase ( & mut block_template ) ; if output . is_err ( ) { error ! ( target LOG_TARGET " " output ) ; return Ok ( self ) ; } ; let output = output . unwrap ( ) ; let block = self . get_block ( block_template ) . await ; if block . is_err ( ) { error ! ( target LOG_TARGET " " block ) ; return Ok ( self ) ; } ; self . mining_status . store ( true , Ordering :: Relaxed ) ; let mut block = block . unwrap ( ) ; debug ! ( target LOG_TARGET " " ) ; let ( tx , mut rx ) : ( mpscSender < Option < BlockHeader > > , mpscReceiver < Option < BlockHeader > > ) = mpsc :: channel ( self . threads ) ; for _ in 0 .. self . threads { let stop_mining_flag = self . stop_mining_flag . clone ( ) ; let header = block . header . clone ( ) ; let thread_hash_rate = self . hashrate . clone ( ) ; let mut tx_channel = tx . clone ( ) ; trace ! ( " " ) ; spawn_blocking ( move | | { let result = CpuPow :: mine ( header , stop_mining_flag , thread_hash_rate ) ; // send back what the miner found, None will be sent if the miner did not find a nonce if let Err ( e ) = tx_channel . try_send ( result ) { warn ! ( target LOG_TARGET " " e ) ; } } ) ; } drop ( tx ) ; // lets ensure that the tx all get dropped while let Some ( value ) = rx . next ( ) . await { // let see if we sound a header, this will be none if no header was found if let Some ( r ) = value { // found block, lets ensure we kill all other threads self . stop_mining_flag . store ( true , Ordering :: Relaxed ) ; block . header = r ; let block_sent = self . send_block ( block ) . await ; if let Err ( e ) = block_sent { error ! ( target LOG_TARGET " " e ) ; break ; } let utxo_sent = self . utxo_sender . try_send ( output ) ; if let Err ( e ) = utxo_sent { error ! ( target LOG_TARGET " " e ) ; return Err ( MinerError :: CommunicationError ( e . to_string ( ) ) ) ; } break ; } } trace ! ( " " ) ; Ok ( self ) }
Mine blocks asynchronously.
Mine blocks asynchronously .
mut self
mut self