Implemented mining zone screen. Added a lot of user input checks.
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "alfis"
|
name = "alfis"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
authors = ["Revertron <alfis@revertron.com>"]
|
authors = ["Revertron <alfis@revertron.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
|||||||
+48
-8
@@ -22,7 +22,7 @@ use simple_logger::{SimpleLogger};
|
|||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use log::{trace, debug, info, warn, error, LevelFilter};
|
use log::{trace, debug, info, warn, error, LevelFilter};
|
||||||
|
|
||||||
use alfis::{Blockchain, Bytes, Context, Keystore, Transaction};
|
use alfis::{Blockchain, Bytes, Context, Keystore, Transaction, check_domain};
|
||||||
use alfis::event::Event;
|
use alfis::event::Event;
|
||||||
use alfis::miner::Miner;
|
use alfis::miner::Miner;
|
||||||
use alfis::p2p::Network;
|
use alfis::p2p::Network;
|
||||||
@@ -50,7 +50,8 @@ fn main() {
|
|||||||
AttachConsole(ATTACH_PARENT_PROCESS);
|
AttachConsole(ATTACH_PARENT_PROCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Starting ALFIS 0.1.0");
|
let version = env!("CARGO_PKG_VERSION");
|
||||||
|
println!("Starting ALFIS {}", version);
|
||||||
let args: Vec<String> = env::args().collect();
|
let args: Vec<String> = env::args().collect();
|
||||||
let program = args[0].clone();
|
let program = args[0].clone();
|
||||||
|
|
||||||
@@ -165,10 +166,12 @@ fn run_interface(context: Arc<Mutex<Context>>, miner: Arc<Mutex<Miner>>) {
|
|||||||
let scripts = inline_script(include_str!("webview/scripts.js"));
|
let scripts = inline_script(include_str!("webview/scripts.js"));
|
||||||
|
|
||||||
let html = Content::Html(file_content.to_owned().replace("{styles}", &styles).replace("{scripts}", &scripts));
|
let html = Content::Html(file_content.to_owned().replace("{styles}", &styles).replace("{scripts}", &scripts));
|
||||||
|
let title = format!("ALFIS {}", env!("CARGO_PKG_VERSION"));
|
||||||
let mut interface = web_view::builder()
|
let mut interface = web_view::builder()
|
||||||
.title("ALFIS 0.1.0")
|
.title(&title)
|
||||||
.content(html)
|
.content(html)
|
||||||
.size(1024, 720)
|
.size(1023, 720)
|
||||||
|
.min_size(895, 350)
|
||||||
.resizable(true)
|
.resizable(true)
|
||||||
.debug(false)
|
.debug(false)
|
||||||
.user_data(())
|
.user_data(())
|
||||||
@@ -242,18 +245,22 @@ fn run_interface(context: Arc<Mutex<Context>>, miner: Arc<Mutex<Miner>>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
CheckDomain { name} => {
|
CheckDomain { name} => {
|
||||||
|
let name = name.to_lowercase();
|
||||||
let c = context.lock().unwrap();
|
let c = context.lock().unwrap();
|
||||||
let available = c.get_blockchain().is_domain_available(&name, &c.get_keystore());
|
let available = c.get_blockchain().is_domain_available(&name, &c.get_keystore());
|
||||||
web_view.eval(&format!("domainAvailable({})", available)).expect("Error evaluating!");
|
web_view.eval(&format!("domainAvailable({})", available)).expect("Error evaluating!");
|
||||||
}
|
}
|
||||||
CreateDomain { name, records, .. } => {
|
CreateDomain { name, records, .. } => {
|
||||||
debug!("Got records: {}", records);
|
debug!("Got records: {}", records);
|
||||||
|
let name = name.to_lowercase();
|
||||||
|
if !check_domain(&name, true) {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
if serde_json::from_str::<Vec<DnsRecord>>(&records).is_ok() {
|
if serde_json::from_str::<Vec<DnsRecord>>(&records).is_ok() {
|
||||||
let keystore = {
|
let (keystore, transaction) = {
|
||||||
let guard = context.lock().unwrap();
|
let context = context.lock().unwrap();
|
||||||
guard.get_keystore()
|
(context.get_keystore(), context.blockchain.get_domain_transaction(&name))
|
||||||
};
|
};
|
||||||
let transaction = { context.lock().unwrap().blockchain.get_domain_transaction(&name) };
|
|
||||||
match transaction {
|
match transaction {
|
||||||
None => {
|
None => {
|
||||||
create_domain(miner.clone(), name, records, &keystore);
|
create_domain(miner.clone(), name, records, &keystore);
|
||||||
@@ -275,6 +282,37 @@ fn run_interface(context: Arc<Mutex<Context>>, miner: Arc<Mutex<Miner>>) {
|
|||||||
ChangeDomain { .. } => {}
|
ChangeDomain { .. } => {}
|
||||||
RenewDomain { .. } => {}
|
RenewDomain { .. } => {}
|
||||||
TransferDomain { .. } => {}
|
TransferDomain { .. } => {}
|
||||||
|
CheckZone { name} => {
|
||||||
|
let name = name.to_lowercase();
|
||||||
|
if !check_domain(&name, false) {
|
||||||
|
web_view.eval("zoneAvailable(false)").expect("Error evaluating!");
|
||||||
|
} else {
|
||||||
|
let c = context.lock().unwrap();
|
||||||
|
let available = c.get_blockchain().is_domain_available(&name, &c.get_keystore());
|
||||||
|
web_view.eval(&format!("zoneAvailable({})", available)).expect("Error evaluating!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CreateZone { name, data } => {
|
||||||
|
let name = name.to_lowercase();
|
||||||
|
let data = data.to_lowercase();
|
||||||
|
let (keystore, transaction) = {
|
||||||
|
let context = context.lock().unwrap();
|
||||||
|
(context.get_keystore(), context.blockchain.get_domain_transaction(&name))
|
||||||
|
};
|
||||||
|
match transaction {
|
||||||
|
None => {
|
||||||
|
create_domain(miner.clone(), name, data, &keystore);
|
||||||
|
}
|
||||||
|
Some(transaction) => {
|
||||||
|
if transaction.pub_key == keystore.get_public() {
|
||||||
|
create_domain(miner.clone(), name, data, &keystore);
|
||||||
|
} else {
|
||||||
|
warn!("Tried to mine not owned domain!");
|
||||||
|
let _ = web_view.eval(&format!("showWarning('{}');", "You cannot change domain that you don't own!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
StopMining => {
|
StopMining => {
|
||||||
context.lock().unwrap().bus.post(Event::ActionStopMining);
|
context.lock().unwrap().bus.post(Event::ActionStopMining);
|
||||||
}
|
}
|
||||||
@@ -419,6 +457,8 @@ pub enum Cmd {
|
|||||||
LoadKey{},
|
LoadKey{},
|
||||||
CreateKey{},
|
CreateKey{},
|
||||||
SaveKey{},
|
SaveKey{},
|
||||||
|
CheckZone{name: String},
|
||||||
|
CreateZone{name: String, data: String},
|
||||||
CheckDomain{name: String},
|
CheckDomain{name: String},
|
||||||
CreateDomain{name: String, records: String, tags: String},
|
CreateDomain{name: String, records: String, tags: String},
|
||||||
ChangeDomain{name: String, records: String, tags: String},
|
ChangeDomain{name: String, records: String, tags: String},
|
||||||
|
|||||||
+1
-1
@@ -67,7 +67,7 @@ impl Peers {
|
|||||||
|
|
||||||
if self.peers
|
if self.peers
|
||||||
.iter()
|
.iter()
|
||||||
.find(|(token, peer)| peer.get_addr() == addr)
|
.find(|(_token, peer)| peer.get_addr() == addr)
|
||||||
.is_some() {
|
.is_some() {
|
||||||
debug!("Skipping address from exchange: {}", &addr);
|
debug!("Skipping address from exchange: {}", &addr);
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -19,6 +19,38 @@ pub fn from_hex(string: &str) -> Result<Vec<u8>, num::ParseIntError> {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn check_domain(name: &str, allow_dots: bool) -> bool {
|
||||||
|
if name.starts_with('.') || name.starts_with('-') || name.ends_with('.') || name.ends_with('-') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
let mut last_dot = false;
|
||||||
|
let mut last_hyphen = false;
|
||||||
|
for char in name.chars() {
|
||||||
|
if allow_dots && char == '.' {
|
||||||
|
if last_dot {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
last_dot = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if char == '-' {
|
||||||
|
if last_hyphen {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
last_hyphen = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
last_dot = false;
|
||||||
|
last_hyphen = false;
|
||||||
|
if !char.is_alphanumeric() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
fn split_n(s: &str, n: usize) -> Vec<&str> {
|
fn split_n(s: &str, n: usize) -> Vec<&str> {
|
||||||
(0..=(s.len() - n + 1) / 2)
|
(0..=(s.len() - n + 1) / 2)
|
||||||
.map(|i| &s[2 * i..2 * i + n])
|
.map(|i| &s[2 * i..2 * i + n])
|
||||||
@@ -54,3 +86,23 @@ pub fn random_string(length: usize) -> String {
|
|||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use crate::check_domain;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_check_domain() {
|
||||||
|
assert!(check_domain("abc0", false));
|
||||||
|
assert!(!check_domain("ab.c", false));
|
||||||
|
assert!(check_domain("a.b.c", true));
|
||||||
|
assert!(!check_domain("ab..c", true));
|
||||||
|
assert!(check_domain("a-b.c", true));
|
||||||
|
assert!(!check_domain("a--b.c", true));
|
||||||
|
assert!(check_domain("a-0-b.c", true));
|
||||||
|
assert!(!check_domain("-ab.c", true));
|
||||||
|
assert!(!check_domain("ab.c-", true));
|
||||||
|
assert!(!check_domain(".ab.c", true));
|
||||||
|
assert!(!check_domain("ab.c-", true));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -128,6 +128,7 @@
|
|||||||
<p class="menu-label">Domain management</p>
|
<p class="menu-label">Domain management</p>
|
||||||
<ul class="menu-list">
|
<ul class="menu-list">
|
||||||
<li><a onclick="openTab(this, 'dom_new')">Mine domain</a></li>
|
<li><a onclick="openTab(this, 'dom_new')">Mine domain</a></li>
|
||||||
|
<li><a onclick="openTab(this, 'zone_new')">Mine zone</a></li>
|
||||||
<!--<li><a onclick="openTab(this, 'dom_edit')">Manage domain</a></li>
|
<!--<li><a onclick="openTab(this, 'dom_edit')">Manage domain</a></li>
|
||||||
<li><a onclick="openTab(this, 'dom_renew')">Renew domain</a></li>
|
<li><a onclick="openTab(this, 'dom_renew')">Renew domain</a></li>
|
||||||
<li><a onclick="openTab(this, 'dom_transfer')">Transfer domain</a></li>-->
|
<li><a onclick="openTab(this, 'dom_transfer')">Transfer domain</a></li>-->
|
||||||
@@ -209,6 +210,37 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="content is-hidden" id="zone_new">
|
||||||
|
<form action="#">
|
||||||
|
|
||||||
|
<div class="columns">
|
||||||
|
<div class="column">
|
||||||
|
<div class="field">
|
||||||
|
<label class="label">Zone name</label>
|
||||||
|
<div class="control">
|
||||||
|
<input class="input" type="text" placeholder="ygg" id="new_zone" oninput="onZoneChange()">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<div class="field">
|
||||||
|
<label class="label">Difficulty (for all domains in zone)</label>
|
||||||
|
<div class="control">
|
||||||
|
<input class="input" type="number" placeholder="20" id="new_zone_difficulty" oninput="onZoneChange()">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field is-grouped">
|
||||||
|
<div class="control">
|
||||||
|
<button class="button is-link" id="new_zone_button" onclick="createZone();" disabled>Mine zone</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="content is-hidden" id="dom_edit">
|
<div class="content is-hidden" id="dom_edit">
|
||||||
<form action="#">
|
<form action="#">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
|
|||||||
+46
-2
@@ -131,7 +131,17 @@ function createDomain() {
|
|||||||
recordsBuffer = [];
|
recordsBuffer = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeDomain() {
|
function createZone() {
|
||||||
|
new_zone = document.getElementById("new_zone").value;
|
||||||
|
difficulty = document.getElementById("new_zone_difficulty").value;
|
||||||
|
obj = {};
|
||||||
|
obj.name = new_zone;
|
||||||
|
obj.difficulty = difficulty;
|
||||||
|
data = JSON.stringify(obj);
|
||||||
|
external.invoke(JSON.stringify({cmd: 'createZone', name: new_zone, data: data}));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*function changeDomain() {
|
||||||
domain = document.getElementById("change_domain").value;
|
domain = document.getElementById("change_domain").value;
|
||||||
dom_records = document.getElementById("change_domain_records").value;
|
dom_records = document.getElementById("change_domain_records").value;
|
||||||
dom_tags = document.getElementById("change_domain_records").value;
|
dom_tags = document.getElementById("change_domain_records").value;
|
||||||
@@ -148,7 +158,7 @@ function transferDomain() {
|
|||||||
domain = document.getElementById("transfer_domain").value;
|
domain = document.getElementById("transfer_domain").value;
|
||||||
new_owner = document.getElementById("transfer_domain_transfer_owner").value;
|
new_owner = document.getElementById("transfer_domain_transfer_owner").value;
|
||||||
external.invoke(JSON.stringify({cmd: 'transferDomain', name: domain, owner: new_owner}));
|
external.invoke(JSON.stringify({cmd: 'transferDomain', name: domain, owner: new_owner}));
|
||||||
}
|
}*/
|
||||||
|
|
||||||
function sendAction(param) {
|
function sendAction(param) {
|
||||||
external.invoke(JSON.stringify(param));
|
external.invoke(JSON.stringify(param));
|
||||||
@@ -170,6 +180,40 @@ function domainAvailable(available) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onZoneChange() {
|
||||||
|
button = document.getElementById("new_zone_button");
|
||||||
|
diff = document.getElementById("new_zone_difficulty");
|
||||||
|
d = parseInt(diff.value);
|
||||||
|
// Checking for NaN first
|
||||||
|
if (d != d || d < 20 || d > 50) {
|
||||||
|
button.disabled = true;
|
||||||
|
diff.className = "input is-danger";
|
||||||
|
} else {
|
||||||
|
diff.className = "input";
|
||||||
|
input = document.getElementById("new_zone");
|
||||||
|
external.invoke(JSON.stringify({cmd: 'checkZone', name: input.value}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function zoneAvailable(available) {
|
||||||
|
input = document.getElementById("new_zone");
|
||||||
|
button = document.getElementById("new_zone_button");
|
||||||
|
if (available) {
|
||||||
|
input.className = "input";
|
||||||
|
button.disabled = false;
|
||||||
|
diff = document.getElementById("new_zone_difficulty");
|
||||||
|
d = parseInt(diff.value);
|
||||||
|
// Checking for NaN first
|
||||||
|
if (d != d || d < 20 || d > 50) {
|
||||||
|
button.disabled = true;
|
||||||
|
diff.className = "input is-danger";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
input.className = "input is-danger";
|
||||||
|
button.disabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function showModalDialog(text, callback) {
|
function showModalDialog(text, callback) {
|
||||||
message = document.getElementById("modal_text");
|
message = document.getElementById("modal_text");
|
||||||
message.textContent = text;
|
message.textContent = text;
|
||||||
|
|||||||
Reference in New Issue
Block a user