Finished the work on status bar. All status information is in sync now.

This commit is contained in:
Revertron
2021-02-28 22:17:03 +01:00
parent 2356f363f9
commit 1045777ee5
5 changed files with 92 additions and 49 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "alfis" name = "alfis"
version = "0.1.5" version = "0.1.6"
authors = ["Revertron <alfis@revertron.com>"] authors = ["Revertron <alfis@revertron.com>"]
edition = "2018" edition = "2018"
build = "build.rs" build = "build.rs"
+3 -3
View File
@@ -10,7 +10,7 @@ pub enum Event {
NewBlockReceived, NewBlockReceived,
BlockchainChanged, BlockchainChanged,
ActionStopMining, ActionStopMining,
StatsCount { nodes: usize, blocks: u64 }, NetworkStatus { nodes: usize, blocks: u64 },
SyncStarted { have: u64, height: u64 }, Syncing { have: u64, height: u64 },
ActionIdle, SyncFinished,
} }
+55 -11
View File
@@ -180,8 +180,9 @@ fn run_interface(context: Arc<Mutex<Context>>, miner: Arc<Mutex<Miner>>) {
debug!("Command {}", arg); debug!("Command {}", arg);
match serde_json::from_str(arg).unwrap() { match serde_json::from_str(arg).unwrap() {
Loaded => { Loaded => {
web_view.eval("showMiningIndicator(false);").expect("Error evaluating!"); web_view.eval("showMiningIndicator(false, false);").expect("Error evaluating!");
let handle = web_view.handle(); let handle = web_view.handle();
let mut status = Status::new();
let mut c = context.lock().unwrap(); let mut c = context.lock().unwrap();
c.bus.register(move |_uuid, e| { c.bus.register(move |_uuid, e| {
debug!("Got event from bus {:?}", &e); debug!("Got event from bus {:?}", &e);
@@ -189,18 +190,46 @@ fn run_interface(context: Arc<Mutex<Context>>, miner: Arc<Mutex<Miner>>) {
Event::KeyCreated { path, public } => { format!("keystoreChanged('{}', '{}');", &path, &public) } Event::KeyCreated { path, public } => { format!("keystoreChanged('{}', '{}');", &path, &public) }
Event::KeyLoaded { path, public } => { format!("keystoreChanged('{}', '{}');", &path, &public) } Event::KeyLoaded { path, public } => { format!("keystoreChanged('{}', '{}');", &path, &public) }
Event::KeySaved { path, public } => { format!("keystoreChanged('{}', '{}');", &path, &public) } Event::KeySaved { path, public } => { format!("keystoreChanged('{}', '{}');", &path, &public) }
Event::MinerStarted => { format!("showMiningIndicator({}, false);", true) } Event::MinerStarted => {
Event::KeyGeneratorStarted => { format!("showMiningIndicator({}, false);", true) } status.mining = true;
Event::MinerStopped => { format!("showMiningIndicator({}, false);", false) } String::from("setLeftStatusBarText('Mining...'); showMiningIndicator(true, false);")
Event::KeyGeneratorStopped => { format!("showMiningIndicator({}, false);", false) }
Event::SyncStarted { have, height } => {
format!("setLeftStatusBarText('Synchronizing {}/{}'); showMiningIndicator(true, true);", have, height)
} }
Event::ActionIdle => { Event::KeyGeneratorStarted => {
format!("setLeftStatusBarText('Idle'); showMiningIndicator(false, true);") status.mining = true;
String::from("setLeftStatusBarText('Mining...'); showMiningIndicator(true, false);")
} }
Event::StatsCount { nodes, blocks } => { Event::MinerStopped | Event::KeyGeneratorStopped => {
format!("setRightStatusBarText('Nodes: {}, Blocks: {}')", nodes, blocks) status.mining = false;
if status.syncing {
String::from("setLeftStatusBarText('Syncing...'); showMiningIndicator(true, true);")
} else {
String::from("setLeftStatusBarText('Idle'); showMiningIndicator(false, false);")
}
}
Event::Syncing { have, height } => {
status.syncing = true;
status.synced_blocks = have;
status.sync_height = height;
if status.mining {
String::from("setLeftStatusBarText('Mining...'); showMiningIndicator(true, false);")
} else {
format!("setLeftStatusBarText('Synchronizing {}/{}'); showMiningIndicator(true, true);", have, height)
}
}
Event::SyncFinished => {
status.syncing = false;
if status.mining {
String::from("setLeftStatusBarText('Mining...'); showMiningIndicator(true, false);")
} else {
format!("setLeftStatusBarText('Idle'); showMiningIndicator(false, false);")
}
}
Event::NetworkStatus { nodes, blocks } => {
if status.mining || status.syncing || nodes < 3 {
format!("setRightStatusBarText('Nodes: {}, Blocks: {}')", nodes, blocks)
} else {
format!("setLeftStatusBarText('Idle'); setRightStatusBarText('Nodes: {}, Blocks: {}')", nodes, blocks)
}
} }
_ => { String::new() } _ => { String::new() }
}; };
@@ -477,6 +506,21 @@ pub enum Cmd {
StopMining, StopMining,
} }
struct Status {
pub mining: bool,
pub syncing: bool,
pub synced_blocks: u64,
pub sync_height: u64,
pub nodes_connected: usize,
pub chain_height: u64
}
impl Status {
fn new() -> Self {
Status { mining: false, syncing: false, synced_blocks: 0, sync_height: 0, nodes_connected: 0, chain_height: 0 }
}
}
fn inline_style(s: &str) -> String { fn inline_style(s: &str) -> String {
format!(r#"<style type="text/css">{}</style>"#, s) format!(r#"<style type="text/css">{}</style>"#, s)
} }
+27 -27
View File
@@ -38,8 +38,8 @@ impl Miner {
} }
pub fn stop(&mut self) { pub fn stop(&mut self) {
self.mining.store(false, Ordering::Relaxed); self.mining.store(false, Ordering::SeqCst);
self.running.store(false, Ordering::Relaxed); self.running.store(false, Ordering::SeqCst);
self.cond_var.notify_all(); self.cond_var.notify_all();
} }
@@ -62,7 +62,7 @@ impl Miner {
if lock.len() > 0 { if lock.len() > 0 {
info!("Got new transaction to mine"); info!("Got new transaction to mine");
let transaction = lock.remove(0); let transaction = lock.remove(0);
mining.store(true, Ordering::Relaxed); mining.store(true, Ordering::SeqCst);
Miner::mine_internal(context.clone(), transactions.clone(), transaction, mining.clone(), cond_var.clone()); Miner::mine_internal(context.clone(), transactions.clone(), transaction, mining.clone(), cond_var.clone());
} else { } else {
let _ = cond_var.wait(lock).expect("Error in wait lock!"); let _ = cond_var.wait(lock).expect("Error in wait lock!");
@@ -72,7 +72,7 @@ impl Miner {
let mining = self.mining.clone(); let mining = self.mining.clone();
self.context.lock().unwrap().bus.register(move |_uuid, e| { self.context.lock().unwrap().bus.register(move |_uuid, e| {
if e == Event::ActionStopMining { if e == Event::ActionStopMining {
mining.store(false, Ordering::Relaxed); mining.store(false, Ordering::SeqCst);
} }
true true
}); });
@@ -123,17 +123,15 @@ impl Miner {
let live_threads = live_threads.clone(); let live_threads = live_threads.clone();
let cond_var = cond_var.clone(); let cond_var = cond_var.clone();
thread::spawn(move || { thread::spawn(move || {
live_threads.fetch_add(1, Ordering::Relaxed); live_threads.fetch_add(1, Ordering::SeqCst);
match find_hash(&mut Sha256::new(), block, mining.clone()) { match find_hash(&mut Sha256::new(), block, mining.clone()) {
None => { None => {
debug!("Mining did not find suitable hash or was stopped"); debug!("Mining was cancelled");
let count = live_threads.fetch_sub(1, Ordering::Relaxed); let count = live_threads.fetch_sub(1, Ordering::SeqCst);
// If this is the last thread, but mining was not stopped by another thread // If this is the last thread, but mining was not stopped by another thread
if count == 0 && mining.load(Ordering::Relaxed) { if count == 1 {
// If all threads came empty with mining we return transaction to the queue let mut context = context.lock().unwrap();
transactions.lock().unwrap().push(transaction); context.bus.post(Event::MinerStopped);
mining.store(false, Ordering::Relaxed);
cond_var.notify_one();
} }
}, },
Some(block) => { Some(block) => {
@@ -146,7 +144,7 @@ impl Miner {
} }
} }
context.bus.post(Event::MinerStopped); context.bus.post(Event::MinerStopped);
mining.store(false, Ordering::Relaxed); mining.store(false, Ordering::SeqCst);
}, },
} }
}); });
@@ -156,21 +154,23 @@ impl Miner {
fn find_hash(digest: &mut dyn Digest, mut block: Block, running: Arc<AtomicBool>) -> Option<Block> { fn find_hash(digest: &mut dyn Digest, mut block: Block, running: Arc<AtomicBool>) -> Option<Block> {
let mut buf: [u8; 32] = [0; 32]; let mut buf: [u8; 32] = [0; 32];
block.random = rand::random(); loop {
debug!("Mining block {}", serde_json::to_string(&block).unwrap()); block.random = rand::random();
for nonce in 0..std::u64::MAX { debug!("Mining block {}", serde_json::to_string(&block).unwrap());
if !running.load(Ordering::Relaxed) { for nonce in 0..std::u64::MAX {
return None; if !running.load(Ordering::Relaxed) {
} return None;
block.timestamp = Utc::now().timestamp(); }
block.nonce = nonce; block.timestamp = Utc::now().timestamp();
block.nonce = nonce;
digest.reset(); digest.reset();
digest.input(serde_json::to_string(&block).unwrap().as_bytes()); digest.input(serde_json::to_string(&block).unwrap().as_bytes());
digest.result(&mut buf); digest.result(&mut buf);
if hash_is_good(&buf, block.difficulty) { if hash_is_good(&buf, block.difficulty) {
block.hash = Bytes::from_bytes(&buf); block.hash = Bytes::from_bytes(&buf);
return Some(block); return Some(block);
}
} }
} }
None None
+6 -7
View File
@@ -93,7 +93,7 @@ impl Network {
let _ = peers.close_peer(poll.registry(), &token); let _ = peers.close_peer(poll.registry(), &token);
let mut context = context.lock().unwrap(); let mut context = context.lock().unwrap();
let blocks_count = context.blockchain.height(); let blocks_count = context.blockchain.height();
context.bus.post(crate::event::Event::StatsCount { nodes: peers.get_peers_active_count(), blocks: blocks_count }); context.bus.post(crate::event::Event::NetworkStatus { nodes: peers.get_peers_active_count(), blocks: blocks_count });
} }
} }
} }
@@ -283,10 +283,10 @@ fn handle_message(context: Arc<Mutex<Context>>, message: Message, peers: &mut Pe
peer.set_active(true); peer.set_active(true);
let mut context = context.lock().unwrap(); let mut context = context.lock().unwrap();
let blocks_count = context.blockchain.height(); let blocks_count = context.blockchain.height();
context.bus.post(crate::event::Event::StatsCount { nodes: active_count, blocks: blocks_count }); context.bus.post(crate::event::Event::NetworkStatus { nodes: active_count + 1, blocks: blocks_count });
if peer.is_higher(my_height) { if peer.is_higher(my_height) {
context.blockchain.update_max_height(height); context.blockchain.update_max_height(height);
context.bus.post(crate::event::Event::SyncStarted { have: my_height, height}); context.bus.post(crate::event::Event::Syncing { have: my_height, height});
State::message(Message::GetBlock { index: my_height }) State::message(Message::GetBlock { index: my_height })
} else { } else {
State::message(Message::GetPeers) State::message(Message::GetPeers)
@@ -315,8 +315,7 @@ fn handle_message(context: Arc<Mutex<Context>>, message: Message, peers: &mut Pe
} else { } else {
let mut context = context.lock().unwrap(); let mut context = context.lock().unwrap();
let blocks_count = context.blockchain.height(); let blocks_count = context.blockchain.height();
context.bus.post(crate::event::Event::ActionIdle); context.bus.post(crate::event::Event::NetworkStatus { nodes: peers.get_peers_active_count(), blocks: blocks_count });
context.bus.post(crate::event::Event::StatsCount { nodes: peers.get_peers_active_count(), blocks: blocks_count });
State::idle() State::idle()
} }
} }
@@ -352,9 +351,9 @@ fn handle_message(context: Arc<Mutex<Context>>, message: Message, peers: &mut Pe
context.bus.post(crate::event::Event::BlockchainChanged); context.bus.post(crate::event::Event::BlockchainChanged);
// If it was the last block to sync // If it was the last block to sync
if my_height == max_height { if my_height == max_height {
context.bus.post(crate::event::Event::ActionIdle); context.bus.post(crate::event::Event::SyncFinished);
} else { } else {
context.bus.post(crate::event::Event::SyncStarted { have: my_height, height: max_height}); context.bus.post(crate::event::Event::Syncing { have: my_height, height: max_height});
} }
} }
Err(_) => { warn!("Discarded received block"); } Err(_) => { warn!("Discarded received block"); }