Finished the work on status bar. All status information is in sync now.
This commit is contained in:
+1
-1
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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"); }
|
||||||
|
|||||||
Reference in New Issue
Block a user