bc_utils/
wsactor.rs

1//!
2//! Web Socket runner for the Blockchain Application.<br>
3//! This is to monitor long running process.<br>
4//! Specifically mining_txn.
5//!
6
7use crate::mining::mine_block;
8use actix::prelude::*;
9use actix_web_actors::ws;
10use serde::Deserialize;
11
12///
13/// Struct MiningProgressWebSocket.
14///
15pub struct MiningProgressWebSocket {
16    pub message: String,
17    pub previous_hash: String,
18    pub difficulty: usize,
19}
20
21///
22/// Struct MiningParams.
23///
24#[derive(Deserialize)]
25struct MiningParams {
26    data: String,
27    previous_hash: String,
28    difficulty: usize,
29}
30
31impl MiningProgressWebSocket {
32    pub fn new(message: String, previous_hash: String, difficulty: usize) -> Self {
33        MiningProgressWebSocket {
34            message,
35            previous_hash,
36            difficulty,
37        }
38    }
39}
40
41impl Actor for MiningProgressWebSocket {
42    type Context = ws::WebsocketContext<Self>;
43}
44
45impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for MiningProgressWebSocket {
46    fn handle(&mut self, msg: Result<ws::Message, ws::ProtocolError>, ctx: &mut Self::Context) {
47        match msg {
48            Ok(ws::Message::Ping(msg)) => ctx.pong(&msg),
49            Ok(ws::Message::Text(text)) => {
50                // Deserialize incoming message (parameters sent by the client)
51                if let Ok(mining_params) = serde_json::from_str::<MiningParams>(&text) {
52                    // Here we extract and use the parameters
53                    self.message = mining_params.data.clone();
54                    self.previous_hash = mining_params.previous_hash.clone();
55                    self.difficulty = mining_params.difficulty;
56
57                    ctx.text("Mining started with provided parameters.");
58
59                    let addr = ctx.address();
60                    // Start the mining process with the provided parameters
61                    std::thread::spawn(move || {
62                        mine_block(
63                            &mining_params.data,          // Borrow as `&str`
64                            &mining_params.previous_hash, // Borrow as `&str`
65                            mining_params.difficulty,
66                            Some(addr),
67                        );
68                    });
69                } else {
70                    ctx.text("Invalid parameters.");
71                }
72            }
73            _ => (),
74        }
75    }
76}
77
78///
79/// Struct NonceUpdate.
80///
81#[derive(Message)]
82#[rtype(result = "()")]
83pub struct NonceUpdate {
84    pub nonce: u64,
85    pub hash: String,
86}
87
88impl Handler<NonceUpdate> for MiningProgressWebSocket {
89    type Result = ();
90
91    fn handle(&mut self, msg: NonceUpdate, ctx: &mut Self::Context) {
92        ctx.text(format!(
93            "Mining in progress...\n\nNonce: {:>2}, Hash: {:?}",
94            msg.nonce, msg.hash
95        ));
96    }
97}
98
99///
100/// Struct MiningComplete.
101///
102#[derive(Message)]
103#[rtype(result = "()")]
104pub struct MiningComplete {
105    pub nonce: u64,
106    pub hash: String,
107}
108
109impl Handler<MiningComplete> for MiningProgressWebSocket {
110    type Result = ();
111
112    fn handle(&mut self, msg: MiningComplete, ctx: &mut Self::Context) {
113        ctx.text(format!(
114            "Mining completed!\n\nNonce: {:>2}\nHash: {}",
115            msg.nonce, msg.hash
116        ));
117        ctx.stop();
118    }
119}