Added success notifications from miner.

This commit is contained in:
Revertron
2021-03-25 20:55:09 +01:00
parent f21f299fb5
commit fc90706213
7 changed files with 106 additions and 45 deletions
+2 -2
View File
@@ -3,9 +3,9 @@ use crate::{Bytes, Keystore};
#[derive(Clone, PartialEq, Debug)] #[derive(Clone, PartialEq, Debug)]
pub enum Event { pub enum Event {
MinerStarted, MinerStarted,
MinerStopped, MinerStopped { success: bool, full: bool },
KeyGeneratorStarted, KeyGeneratorStarted,
KeyGeneratorStopped, KeyGeneratorStopped { success: bool },
KeyCreated { path: String, public: String, hash: String }, KeyCreated { path: String, public: String, hash: String },
KeyLoaded { path: String, public: String, hash: String }, KeyLoaded { path: String, public: String, hash: String },
KeySaved { path: String, public: String, hash: String }, KeySaved { path: String, public: String, hash: String },
+3 -1
View File
@@ -163,6 +163,7 @@ pub fn create_key(context: Arc<Mutex<Context>>) {
let miners_count = miners_count.clone(); let miners_count = miners_count.clone();
thread::spawn(move || { thread::spawn(move || {
miners_count.fetch_add(1, atomic::Ordering::SeqCst); miners_count.fetch_add(1, atomic::Ordering::SeqCst);
let mut success = false;
match generate_key(KEYSTORE_DIFFICULTY, mining.clone()) { match generate_key(KEYSTORE_DIFFICULTY, mining.clone()) {
None => { None => {
debug!("Keystore mining finished"); debug!("Keystore mining finished");
@@ -174,11 +175,12 @@ pub fn create_key(context: Arc<Mutex<Context>>) {
info!("Key mined successfully: {:?}, hash: {}", &keystore.get_public(), &hash); info!("Key mined successfully: {:?}, hash: {}", &keystore.get_public(), &hash);
context.bus.post(Event::KeyCreated { path: keystore.get_path().to_owned(), public: keystore.get_public().to_string(), hash }); context.bus.post(Event::KeyCreated { path: keystore.get_path().to_owned(), public: keystore.get_public().to_string(), hash });
context.set_keystore(Some(keystore)); context.set_keystore(Some(keystore));
success = true;
} }
} }
let miners = miners_count.fetch_sub(1, atomic::Ordering::SeqCst) - 1; let miners = miners_count.fetch_sub(1, atomic::Ordering::SeqCst) - 1;
if miners == 0 { if miners == 0 {
context.lock().unwrap().bus.post(Event::KeyGeneratorStopped); context.lock().unwrap().bus.post(Event::KeyGeneratorStopped { success });
} }
}); });
} }
+7 -4
View File
@@ -113,7 +113,7 @@ impl Miner {
job.block.pub_key = job.keystore.get_public(); job.block.pub_key = job.keystore.get_public();
if !check_public_key_strength(&job.block.pub_key, KEYSTORE_DIFFICULTY) { if !check_public_key_strength(&job.block.pub_key, KEYSTORE_DIFFICULTY) {
warn!("Can not mine block with weak public key!"); warn!("Can not mine block with weak public key!");
context.lock().unwrap().bus.post(Event::MinerStopped); context.lock().unwrap().bus.post(Event::MinerStopped { success: false, full: false });
mining.store(false, Ordering::SeqCst); mining.store(false, Ordering::SeqCst);
return; return;
} }
@@ -124,7 +124,7 @@ impl Miner {
// If we were doing something else and got new block before we could mine this block // If we were doing something else and got new block before we could mine this block
if last_block.index > job.block.index || last_block.hash != job.block.prev_block_hash { if last_block.index > job.block.index || last_block.hash != job.block.prev_block_hash {
warn!("We missed block to lock"); warn!("We missed block to lock");
context.lock().unwrap().bus.post(Event::MinerStopped); context.lock().unwrap().bus.post(Event::MinerStopped { success: false, full: false });
mining.store(false, Ordering::SeqCst); mining.store(false, Ordering::SeqCst);
return; return;
} }
@@ -150,6 +150,7 @@ impl Miner {
let live_threads = Arc::clone(&live_threads); let live_threads = Arc::clone(&live_threads);
thread::spawn(move || { thread::spawn(move || {
live_threads.fetch_add(1, Ordering::SeqCst); live_threads.fetch_add(1, Ordering::SeqCst);
let full = job.block.transaction.is_some();
match find_hash(Arc::clone(&context), job.block, Arc::clone(&mining)) { match find_hash(Arc::clone(&context), job.block, Arc::clone(&mining)) {
None => { None => {
debug!("Mining was cancelled"); debug!("Mining was cancelled");
@@ -157,13 +158,14 @@ impl Miner {
// 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 == 1 { if count == 1 {
let mut context = context.lock().unwrap(); let mut context = context.lock().unwrap();
context.bus.post(Event::MinerStopped); context.bus.post(Event::MinerStopped { success: false, full });
} }
}, },
Some(mut block) => { Some(mut block) => {
let index = block.index; let index = block.index;
let mut context = context.lock().unwrap(); let mut context = context.lock().unwrap();
block.signature = Bytes::from_bytes(&job.keystore.sign(&block.as_bytes())); block.signature = Bytes::from_bytes(&job.keystore.sign(&block.as_bytes()));
let mut success = false;
if context.chain.check_new_block(&block) != BlockQuality::Good { if context.chain.check_new_block(&block) != BlockQuality::Good {
warn!("Error adding mined block!"); warn!("Error adding mined block!");
if index == 0 { if index == 0 {
@@ -174,8 +176,9 @@ impl Miner {
context.settings.origin = block.hash.to_string(); context.settings.origin = block.hash.to_string();
} }
context.chain.add_block(block); context.chain.add_block(block);
success = true;
} }
context.bus.post(Event::MinerStopped); context.bus.post(Event::MinerStopped { success, full });
mining.store(false, Ordering::SeqCst); mining.store(false, Ordering::SeqCst);
}, },
} }
+30 -2
View File
@@ -190,13 +190,33 @@ fn action_loaded(context: &Arc<Mutex<Context>>, web_view: &mut WebView<()>) {
status.mining = true; status.mining = true;
String::from("setLeftStatusBarText('Mining...'); showMiningIndicator(true, false);") String::from("setLeftStatusBarText('Mining...'); showMiningIndicator(true, false);")
} }
Event::MinerStopped | Event::KeyGeneratorStopped => { Event::MinerStopped {success, full} => {
status.mining = false; status.mining = false;
if status.syncing { let mut s = if status.syncing {
String::from("setLeftStatusBarText('Syncing...'); showMiningIndicator(true, true);") String::from("setLeftStatusBarText('Syncing...'); showMiningIndicator(true, true);")
} else { } else {
String::from("setLeftStatusBarText('Idle'); showMiningIndicator(false, false);") String::from("setLeftStatusBarText('Idle'); showMiningIndicator(false, false);")
};
if full {
match success {
true => { s.push_str(" showSuccess('Block successfully mined!')"); }
false => { s.push_str(" showSuccess('Mining unsuccessful, sorry.')"); }
}
} }
s
}
Event::KeyGeneratorStopped {success} => {
status.mining = false;
let mut s = if status.syncing {
String::from("setLeftStatusBarText('Syncing...'); showMiningIndicator(true, true);")
} else {
String::from("setLeftStatusBarText('Idle'); showMiningIndicator(false, false);")
};
match success {
true => { s.push_str(" showSuccess('Key pair successfully mined!<br>Don`t forget to save!')"); }
false => { s.push_str(" showSuccess('Key mining got nothing, sorry.')"); }
}
s
} }
Event::Syncing { have, height } => { Event::Syncing { have, height } => {
status.syncing = true; status.syncing = true;
@@ -321,6 +341,14 @@ fn show_warning(web_view: &mut WebView<()>, text: &str) {
} }
} }
fn show_success(web_view: &mut WebView<()>, text: &str) {
let str = text.replace('\'', "\\'");
match web_view.eval(&format!("showSuccess('{}');", &str)) {
Ok(_) => {}
Err(_) => { warn!("Error showing success!"); }
}
}
fn create_domain(context: Arc<Mutex<Context>>, miner: Arc<Mutex<Miner>>, name: &str, data: &str, difficulty: u32, keystore: &Keystore) { fn create_domain(context: Arc<Mutex<Context>>, miner: Arc<Mutex<Miner>>, name: &str, data: &str, difficulty: u32, keystore: &Keystore) {
let name = name.to_owned(); let name = name.to_owned();
info!("Generating domain or zone {}", &name); info!("Generating domain or zone {}", &name);
+6 -1
View File
@@ -191,10 +191,15 @@
</div> </div>
<div class="notification is-warning is-hidden" id="notification_warning"> <div class="notification is-warning is-hidden" id="notification_warning">
<button class="delete" id="close"></button> <button class="delete" id="warning_close"></button>
<p id="warning_text"></p> <p id="warning_text"></p>
</div> </div>
<div class="notification is-success is-hidden" id="notification_success">
<button class="delete" id="success_close"></button>
<p id="success_text"></p>
</div>
<div class="footer is-family-code"> <div class="footer is-family-code">
<div class="level"> <div class="level">
<div class="level-left"> <div class="level-left">
+48 -35
View File
@@ -36,8 +36,8 @@ function refresh_records_list() {
var text = "<div class=\"field is-grouped\">" + var text = "<div class=\"field is-grouped\">" +
"<input class=\"input\" type=\"text\" value=\"{1}\" readonly>" + "<input class=\"input\" type=\"text\" value=\"{1}\" readonly>" +
"<input class=\"input ml-3 has-text-centered\" type=\"text\" size=\"6\" style=\"width: 15%;\" value=\"{2}\" readonly>" + "<input class=\"input ml-3 has-text-centered\" type=\"text\" size=\"6\" style=\"width: 20%;\" value=\"{2}\" readonly>" +
"<input class=\"input ml-3 has-text-centered\" type=\"text\" size=\"6\" style=\"width: 15%;\" value=\"{3}\" readonly>" + "<input class=\"input ml-3 has-text-centered\" type=\"text\" size=\"6\" style=\"width: 20%;\" value=\"{3}\" readonly>" +
"<input class=\"input ml-3\" type=\"text\" value=\"{4}\" readonly>" + "<input class=\"input ml-3\" type=\"text\" value=\"{4}\" readonly>" +
"<button class=\"button is-danger is-outlined ml-3\" id=\"record_delete\" onclick=\"delRecord({5});\">" + "<button class=\"button is-danger is-outlined ml-3\" id=\"record_delete\" onclick=\"delRecord({5});\">" +
" <span class=\"icon is-small\"><i class=\"fas fa-times\"></i></span>" + " <span class=\"icon is-small\"><i class=\"fas fa-times\"></i></span>" +
@@ -55,38 +55,38 @@ function refresh_records_list() {
} }
function showNewRecordDialog() { function showNewRecordDialog() {
button_positive = document.getElementById("new_record_positive_button"); var button_positive = document.getElementById("new_record_positive_button");
button_positive.onclick = function() { button_positive.onclick = function() {
checkRecord(get_record_from_dialog()); checkRecord(get_record_from_dialog());
}; };
button_negative = document.getElementById("new_record_negative_button"); var button_negative = document.getElementById("new_record_negative_button");
button_negative.onclick = function() { button_negative.onclick = function() {
dialog = document.getElementById("new_record_dialog"); var dialog = document.getElementById("new_record_dialog");
dialog.className = "modal"; dialog.className = "modal";
refresh_records_list(); refresh_records_list();
} }
dialog = document.getElementById("new_record_dialog"); var dialog = document.getElementById("new_record_dialog");
dialog.className = "modal is-active"; dialog.className = "modal is-active";
} }
function get_record_from_dialog() { function get_record_from_dialog() {
record_name = document.getElementById("record_name").value.toLowerCase(); var record_name = document.getElementById("record_name").value.toLowerCase();
record_type = document.getElementById("record_type").value; var record_type = document.getElementById("record_type").value;
record_ttl = parseInt(document.getElementById("record_ttl").value); var record_ttl = parseInt(document.getElementById("record_ttl").value);
record_data = document.getElementById("record_data").value; var record_data = document.getElementById("record_data").value;
if (record_type == "CNAME" || record_type == "NS") { if (record_type == "CNAME" || record_type == "NS") {
return { type: record_type, domain: record_name, ttl: record_ttl, host: record_data } return { type: record_type, domain: record_name, ttl: record_ttl, host: record_data }
} else if (record_type == "MX") { } else if (record_type == "MX") {
record_priority = parseInt(document.getElementById("record_priority").value); var record_priority = parseInt(document.getElementById("record_priority").value);
return { type: record_type, domain: record_name, ttl: record_ttl, priority: record_priority, host: record_data } return { type: record_type, domain: record_name, ttl: record_ttl, priority: record_priority, host: record_data }
} else if (record_type == "TXT") { } else if (record_type == "TXT") {
return { type: record_type, domain: record_name, ttl: record_ttl, data: record_data } return { type: record_type, domain: record_name, ttl: record_ttl, data: record_data }
} else if (record_type == "SRV") { } else if (record_type == "SRV") {
record_priority = parseInt(document.getElementById("record_priority").value); var record_priority = parseInt(document.getElementById("record_priority").value);
record_weight = parseInt(document.getElementById("record_weight").value); var record_weight = parseInt(document.getElementById("record_weight").value);
record_port = parseInt(document.getElementById("record_port").value); var record_port = parseInt(document.getElementById("record_port").value);
return { type: record_type, domain: record_name, ttl: record_ttl, priority: record_priority, weight: record_weight, port: record_port, host: record_data } return { type: record_type, domain: record_name, ttl: record_ttl, priority: record_priority, weight: record_weight, port: record_port, host: record_data }
} }
return { type: record_type, domain: record_name, ttl: record_ttl, addr: record_data } return { type: record_type, domain: record_name, ttl: record_ttl, addr: record_data }
@@ -115,7 +115,7 @@ function checkRecord(data) {
function recordOkay(okay) { function recordOkay(okay) {
if (okay) { if (okay) {
addRecord(get_record_from_dialog()); // It will refresh list addRecord(get_record_from_dialog()); // It will refresh list
dialog = document.getElementById("new_record_dialog"); var dialog = document.getElementById("new_record_dialog");
dialog.className = "modal"; dialog.className = "modal";
} else { } else {
showWarning('Record is not valid!'); showWarning('Record is not valid!');
@@ -123,8 +123,8 @@ function recordOkay(okay) {
} }
function createDomain() { function createDomain() {
new_domain = document.getElementById("new_domain").value.toLowerCase(); var new_domain = document.getElementById("new_domain").value.toLowerCase();
new_dom_records = JSON.stringify(recordsBuffer); var new_dom_records = JSON.stringify(recordsBuffer);
external.invoke(JSON.stringify({cmd: 'mineDomain', name: new_domain, records: new_dom_records})); external.invoke(JSON.stringify({cmd: 'mineDomain', name: new_domain, records: new_dom_records}));
} }
@@ -133,8 +133,8 @@ function domainMiningStarted() {
} }
function createZone() { function createZone() {
new_zone = document.getElementById("new_zone").value; var new_zone = document.getElementById("new_zone").value;
difficulty = document.getElementById("new_zone_difficulty").value; var difficulty = document.getElementById("new_zone_difficulty").value;
obj = {}; obj = {};
obj.name = new_zone; obj.name = new_zone;
obj.difficulty = parseInt(difficulty); obj.difficulty = parseInt(difficulty);
@@ -151,9 +151,9 @@ function onDomainChange(element) {
} }
function domainAvailable(available) { function domainAvailable(available) {
input = document.getElementById("new_domain"); var input = document.getElementById("new_domain");
button = document.getElementById("new_domain_button"); var button = document.getElementById("new_domain_button");
button2 = document.getElementById("add_record_button"); var button2 = document.getElementById("add_record_button");
if (available) { if (available) {
input.className = "input"; input.className = "input";
button.disabled = false button.disabled = false
@@ -166,8 +166,8 @@ function domainAvailable(available) {
} }
function onZoneChange() { function onZoneChange() {
button = document.getElementById("new_zone_button"); var button = document.getElementById("new_zone_button");
diff = document.getElementById("new_zone_difficulty"); var diff = document.getElementById("new_zone_difficulty");
d = parseInt(diff.value); d = parseInt(diff.value);
// Checking for NaN first // Checking for NaN first
if (d != d || d < 20 || d > 50) { if (d != d || d < 20 || d > 50) {
@@ -175,18 +175,18 @@ function onZoneChange() {
diff.className = "input is-danger"; diff.className = "input is-danger";
} else { } else {
diff.className = "input"; diff.className = "input";
input = document.getElementById("new_zone"); var input = document.getElementById("new_zone");
external.invoke(JSON.stringify({cmd: 'checkZone', name: input.value})); external.invoke(JSON.stringify({cmd: 'checkZone', name: input.value}));
} }
} }
function zoneAvailable(available) { function zoneAvailable(available) {
input = document.getElementById("new_zone"); var input = document.getElementById("new_zone");
button = document.getElementById("new_zone_button"); var button = document.getElementById("new_zone_button");
if (available) { if (available) {
input.className = "input"; input.className = "input";
button.disabled = false; button.disabled = false;
diff = document.getElementById("new_zone_difficulty"); var diff = document.getElementById("new_zone_difficulty");
d = parseInt(diff.value); d = parseInt(diff.value);
// Checking for NaN first // Checking for NaN first
if (d != d || d < 20 || d > 50) { if (d != d || d < 20 || d > 50) {
@@ -200,33 +200,33 @@ function zoneAvailable(available) {
} }
function showModalDialog(text, callback) { function showModalDialog(text, callback) {
message = document.getElementById("modal_text"); var message = document.getElementById("modal_text");
message.textContent = text; message.textContent = text;
button_positive = document.getElementById("modal_positive_button"); var button_positive = document.getElementById("modal_positive_button");
button_positive.onclick = function() { button_positive.onclick = function() {
callback(); callback();
dialog = document.getElementById("modal_dialog"); dialog = document.getElementById("modal_dialog");
dialog.className = "modal"; dialog.className = "modal";
}; };
button_negative = document.getElementById("modal_negative_button"); var button_negative = document.getElementById("modal_negative_button");
button_negative.onclick = function() { button_negative.onclick = function() {
dialog = document.getElementById("modal_dialog"); dialog = document.getElementById("modal_dialog");
dialog.className = "modal"; dialog.className = "modal";
} }
dialog = document.getElementById("modal_dialog"); var dialog = document.getElementById("modal_dialog");
dialog.className = "modal is-active"; dialog.className = "modal is-active";
} }
function showWarning(text) { function showWarning(text) {
warning = document.getElementById("notification_warning"); var warning = document.getElementById("notification_warning");
message = document.getElementById("warning_text"); var message = document.getElementById("warning_text");
message.innerHTML = text; message.innerHTML = text;
warning.className = "notification is-warning"; warning.className = "notification is-warning";
button = document.getElementById("close"); var button = document.getElementById("warning_close");
button.onclick = function() { button.onclick = function() {
message.value = ""; message.value = "";
warning.className = "notification is-warning is-hidden"; warning.className = "notification is-warning is-hidden";
@@ -234,6 +234,19 @@ function showWarning(text) {
setTimeout(button.onclick, 5000); setTimeout(button.onclick, 5000);
} }
function showSuccess(text) {
var warning = document.getElementById("notification_success");
var message = document.getElementById("success_text");
message.innerHTML = text;
warning.className = "notification is-success";
var button = document.getElementById("success_close");
button.onclick = function() {
message.value = "";
warning.className = "notification is-success is-hidden";
}
}
function showMiningIndicator(visible, blue) { function showMiningIndicator(visible, blue) {
var indicator = document.getElementById("busy_indicator"); var indicator = document.getElementById("busy_indicator");
var parent = document.getElementById("indicator_parent"); var parent = document.getElementById("indicator_parent");
+10
View File
@@ -6,10 +6,20 @@
position: absolute; position: absolute;
z-index: 100; z-index: 100;
width: 50%; width: 50%;
}
.notification.is-warning {
position: absolute;
top: 10pt; top: 10pt;
right: 10pt; right: 10pt;
} }
.notification.is-success {
position: absolute;
bottom: 10pt;
right: 10pt;
}
.footer { .footer {
background-color: #f4f4f4; background-color: #f4f4f4;
padding: 0.2rem 0.5rem 0.2rem 0.5rem; padding: 0.2rem 0.5rem 0.2rem 0.5rem;