mirror of
https://github.com/Revertron/Alfis
synced 2024-11-03 15:40:19 +00:00
Implemented right way to constrain zone difficulty.
This commit is contained in:
parent
d8ac1e3c32
commit
1d9833db0f
@ -1,5 +1,5 @@
|
||||
# Settings
|
||||
origin = ""
|
||||
origin = "00000087A1BA6F94781C77BBDA96CC548E1E7F502DB3EA3F103ACD9301813B43"
|
||||
key_file = "default.key"
|
||||
listen = "[::]:4244"
|
||||
public = false
|
||||
|
@ -29,12 +29,12 @@ pub struct Block {
|
||||
}
|
||||
|
||||
impl Block {
|
||||
pub fn new(transaction: Option<Transaction>, pub_key: Bytes, prev_block_hash: Bytes) -> Self {
|
||||
pub fn new(transaction: Option<Transaction>, pub_key: Bytes, prev_block_hash: Bytes, difficulty: u32) -> Self {
|
||||
Block {
|
||||
index: 0,
|
||||
timestamp: 0,
|
||||
version: 0,
|
||||
difficulty: 0,
|
||||
difficulty,
|
||||
random: 0,
|
||||
nonce: 0,
|
||||
transaction,
|
||||
|
@ -14,6 +14,7 @@ use crate::blockchain::hash_utils::*;
|
||||
use crate::settings::Settings;
|
||||
use crate::keys::check_public_key_strength;
|
||||
use std::cmp::{min, max};
|
||||
use crate::blockchain::transaction::{ZoneData, DomainData};
|
||||
|
||||
const DB_NAME: &str = "blockchain.db";
|
||||
const SQL_CREATE_TABLES: &str = "CREATE TABLE blocks (
|
||||
@ -309,6 +310,21 @@ impl Chain {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_zone_difficulty(&self, zone: &str) -> u32 {
|
||||
match self.get_domain_transaction(zone) {
|
||||
None => { u32::max_value() }
|
||||
Some(transaction) => {
|
||||
match serde_json::from_str::<ZoneData>(&transaction.data) {
|
||||
Ok(data) => { data.difficulty }
|
||||
Err(_) => {
|
||||
warn!("Wrong data for zone {}!", zone);
|
||||
u32::max_value()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn last_block(&self) -> Option<Block> {
|
||||
self.last_block.clone()
|
||||
}
|
||||
@ -395,6 +411,12 @@ impl Chain {
|
||||
return Bad;
|
||||
}
|
||||
}
|
||||
if let Ok(data) = serde_json::from_str::<DomainData>(&transaction.data) {
|
||||
if self.get_zone_difficulty(&data.zone) > block.difficulty {
|
||||
warn!("Block {:?} is mined with too low difficulty!", &block);
|
||||
return Bad;
|
||||
}
|
||||
}
|
||||
}
|
||||
match &self.last_block {
|
||||
None => {
|
||||
|
@ -1,5 +1,6 @@
|
||||
pub const CHAIN_VERSION: u32 = 1;
|
||||
|
||||
pub const ZONE_DIFFICULTY: u32 = 28;
|
||||
pub const BLOCK_DIFFICULTY: u32 = 24;
|
||||
pub const LOCKER_DIFFICULTY: u32 = 18;
|
||||
pub const KEYSTORE_DIFFICULTY: usize = 25;
|
||||
|
@ -4,6 +4,7 @@ use crate::dns::filter::DnsFilter;
|
||||
use crate::dns::protocol::{DnsPacket, QueryType, DnsRecord, DnsQuestion, ResultCode};
|
||||
#[allow(unused_imports)]
|
||||
use log::{trace, debug, info, warn, error};
|
||||
use crate::blockchain::transaction::DomainData;
|
||||
|
||||
pub struct BlockchainFilter {
|
||||
context: Arc<Mutex<Context>>
|
||||
@ -48,12 +49,12 @@ impl DnsFilter for BlockchainFilter {
|
||||
}
|
||||
Some(data) => {
|
||||
info!("Found data for domain {}", &search);
|
||||
let mut records: Vec<DnsRecord> = match serde_json::from_str(&data) {
|
||||
let mut data: DomainData = match serde_json::from_str(&data) {
|
||||
Err(_) => { return None; }
|
||||
Ok(records) => { records }
|
||||
Ok(data) => { data }
|
||||
};
|
||||
let mut answers: Vec<DnsRecord> = Vec::new();
|
||||
for mut record in records.iter_mut() {
|
||||
for mut record in data.records.iter_mut() {
|
||||
if record.get_querytype() == qtype {
|
||||
match &mut record {
|
||||
DnsRecord::A { domain, .. }
|
||||
@ -98,7 +99,7 @@ impl DnsFilter for BlockchainFilter {
|
||||
}
|
||||
if answers.is_empty() {
|
||||
// If there are no records found we search for *.domain.ltd record
|
||||
for mut record in records {
|
||||
for mut record in data.records {
|
||||
if record.get_querytype() == qtype {
|
||||
match record.get_domain() {
|
||||
None => {}
|
||||
|
@ -5,6 +5,7 @@ use serde::ser::SerializeStruct;
|
||||
|
||||
use crate::blockchain::hash_utils::*;
|
||||
use crate::bytes::Bytes;
|
||||
use crate::dns::protocol::DnsRecord;
|
||||
|
||||
extern crate serde;
|
||||
extern crate serde_json;
|
||||
@ -75,4 +76,22 @@ impl Serialize for Transaction {
|
||||
structure.serialize_field("pub_key", &self.pub_key)?;
|
||||
structure.end()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct DomainData {
|
||||
pub zone: String,
|
||||
pub records: Vec<DnsRecord>
|
||||
}
|
||||
|
||||
impl DomainData {
|
||||
pub fn new(zone: String, records: Vec<DnsRecord>) -> Self {
|
||||
Self { zone, records }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, PartialEq)]
|
||||
pub struct ZoneData {
|
||||
pub name: String,
|
||||
pub difficulty: u32
|
||||
}
|
@ -16,6 +16,7 @@ use simple_logger::SimpleLogger;
|
||||
use winapi::um::wincon::{ATTACH_PARENT_PROCESS, AttachConsole, FreeConsole};
|
||||
|
||||
use alfis::{Block, Bytes, Chain, Miner, Context, Network, Settings, dns_utils, Keystore};
|
||||
use alfis::blockchain::BLOCK_DIFFICULTY;
|
||||
|
||||
mod web_ui;
|
||||
|
||||
@ -126,7 +127,7 @@ fn create_genesis_if_needed(context: &Arc<Mutex<Context>>, miner: &Arc<Mutex<Min
|
||||
let origin = context.settings.origin.clone();
|
||||
if origin.eq("") && last_block.is_none() {
|
||||
// If blockchain is empty, we are going to mine a Genesis block
|
||||
let block = Block::new(None, context.get_keystore().get_public(), Bytes::default());
|
||||
let block = Block::new(None, context.get_keystore().get_public(), Bytes::default(), BLOCK_DIFFICULTY);
|
||||
miner.lock().unwrap().add_block(block);
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ use log::{debug, error, info, trace, warn};
|
||||
use num_cpus;
|
||||
|
||||
use crate::{Block, Bytes, Context, setup_miner_thread};
|
||||
use crate::blockchain::{BLOCK_DIFFICULTY, CHAIN_VERSION, LOCKER_DIFFICULTY, KEYSTORE_DIFFICULTY};
|
||||
use crate::blockchain::{CHAIN_VERSION, LOCKER_DIFFICULTY, KEYSTORE_DIFFICULTY};
|
||||
use crate::blockchain::enums::BlockQuality;
|
||||
use crate::blockchain::hash_utils::*;
|
||||
use crate::keys::check_public_key_strength;
|
||||
@ -84,7 +84,7 @@ impl Miner {
|
||||
}
|
||||
Event::ActionMineLocker { index, hash } => {
|
||||
if !mining.load(Ordering::SeqCst) {
|
||||
let mut block = Block::new(None, Bytes::default(), hash);
|
||||
let mut block = Block::new(None, Bytes::default(), hash, LOCKER_DIFFICULTY);
|
||||
block.index = index;
|
||||
blocks.lock().unwrap().push(block);
|
||||
cond_var.notify_all();
|
||||
@ -109,7 +109,6 @@ impl Miner {
|
||||
// If this block needs to be a locker
|
||||
if block.index > 0 && !block.prev_block_hash.is_empty() {
|
||||
info!("Mining locker block");
|
||||
block.difficulty = LOCKER_DIFFICULTY;
|
||||
block.pub_key = context.lock().unwrap().keystore.get_public();
|
||||
if !check_public_key_strength(&block.pub_key, KEYSTORE_DIFFICULTY) {
|
||||
warn!("Can not mine block with weak public key!");
|
||||
@ -131,7 +130,6 @@ impl Miner {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
block.difficulty = BLOCK_DIFFICULTY;
|
||||
block.index = context.lock().unwrap().chain.height() + 1;
|
||||
block.prev_block_hash = match context.lock().unwrap().chain.last_block() {
|
||||
None => { Bytes::default() }
|
||||
|
@ -64,6 +64,15 @@ pub fn check_domain(name: &str, allow_dots: bool) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub fn get_domain_zone(domain: &str) -> String {
|
||||
let parts: Vec<&str> = domain.rsplitn(2, ".").collect();
|
||||
if !parts.is_empty() {
|
||||
parts[0].to_owned()
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
}
|
||||
|
||||
fn split_n(s: &str, n: usize) -> Vec<&str> {
|
||||
(0..=(s.len() - n + 1) / 2)
|
||||
.map(|i| &s[2 * i..2 * i + n])
|
||||
|
@ -12,13 +12,14 @@ use web_view::Content;
|
||||
use log::{debug, error, info, LevelFilter, trace, warn};
|
||||
use serde::Deserialize;
|
||||
|
||||
use alfis::{Block, Bytes, Context, Keystore, Transaction};
|
||||
use alfis::{Block, Bytes, Context, Keystore, Transaction, get_domain_zone};
|
||||
use alfis::miner::Miner;
|
||||
use alfis::{keys, check_domain};
|
||||
use alfis::event::Event;
|
||||
use alfis::dns::protocol::DnsRecord;
|
||||
use alfis::blockchain::ZONE_MAX_LENGTH;
|
||||
use alfis::blockchain::{ZONE_MAX_LENGTH, ZONE_DIFFICULTY};
|
||||
use Cmd::*;
|
||||
use alfis::blockchain::transaction::DomainData;
|
||||
|
||||
pub fn run_interface(context: Arc<Mutex<Context>>, miner: Arc<Mutex<Miner>>) {
|
||||
let file_content = include_str!("webview/index.html");
|
||||
@ -158,27 +159,34 @@ pub fn run_interface(context: Arc<Mutex<Context>>, miner: Arc<Mutex<Miner>>) {
|
||||
if !check_domain(&name, true) {
|
||||
return Ok(());
|
||||
}
|
||||
if serde_json::from_str::<Vec<DnsRecord>>(&records).is_ok() {
|
||||
let (keystore, transaction) = {
|
||||
let context = context.lock().unwrap();
|
||||
(context.get_keystore(), context.chain.get_domain_transaction(&name))
|
||||
};
|
||||
match transaction {
|
||||
None => {
|
||||
create_domain(context.clone(), miner.clone(), &name, &records, &keystore);
|
||||
}
|
||||
Some(transaction) => {
|
||||
if transaction.pub_key == keystore.get_public() {
|
||||
create_domain(context.clone(), miner.clone(), &name, &records, &keystore);
|
||||
} else {
|
||||
warn!("Tried to mine not owned domain!");
|
||||
let _ = web_view.eval(&format!("showWarning('{}');", "You cannot change domain that you don't own!"));
|
||||
let rec_vec = serde_json::from_str::<Vec<DnsRecord>>(&records);
|
||||
match rec_vec {
|
||||
Ok(records) => {
|
||||
let zone = get_domain_zone(&name);
|
||||
let data = DomainData::new(zone.clone(), records);
|
||||
let (keystore, transaction, difficulty) = {
|
||||
let context = context.lock().unwrap();
|
||||
(context.get_keystore(), context.chain.get_domain_transaction(&name), context.chain.get_zone_difficulty(&name))
|
||||
};
|
||||
let data = serde_json::to_string(&data).unwrap();
|
||||
match transaction {
|
||||
None => {
|
||||
create_domain(context.clone(), miner.clone(), &name, &data, difficulty, &keystore);
|
||||
}
|
||||
Some(transaction) => {
|
||||
if transaction.pub_key == keystore.get_public() {
|
||||
create_domain(context.clone(), miner.clone(), &name, &data, difficulty, &keystore);
|
||||
} else {
|
||||
warn!("Tried to mine not owned domain!");
|
||||
let _ = web_view.eval(&format!("showWarning('{}');", "You cannot change domain that you don't own!"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
warn!("Error in DNS records for domain!");
|
||||
let _ = web_view.eval(&format!("showWarning('{}');", "Something wrong with your records! Please, correct the error and try again."));
|
||||
Err(e) => {
|
||||
warn!("Error in DNS records for domain!\n{}", e);
|
||||
let _ = web_view.eval(&format!("showWarning('{}');", "Something wrong with your records! Please, correct the error and try again."));
|
||||
}
|
||||
}
|
||||
}
|
||||
ChangeDomain { .. } => {}
|
||||
@ -208,11 +216,11 @@ pub fn run_interface(context: Arc<Mutex<Context>>, miner: Arc<Mutex<Miner>>) {
|
||||
};
|
||||
match transaction {
|
||||
None => {
|
||||
create_domain(context.clone(), miner.clone(), &name, &data, &keystore);
|
||||
create_domain(context.clone(), miner.clone(), &name, &data, ZONE_DIFFICULTY, &keystore);
|
||||
}
|
||||
Some(transaction) => {
|
||||
if transaction.pub_key == keystore.get_public() {
|
||||
create_domain(context.clone(), miner.clone(), &name, &data, &keystore);
|
||||
create_domain(context.clone(), miner.clone(), &name, &data, ZONE_DIFFICULTY, &keystore);
|
||||
} else {
|
||||
warn!("Tried to mine not owned domain!");
|
||||
let _ = web_view.eval(&format!("showWarning('{}');", "You cannot change domain that you don't own!"));
|
||||
@ -259,7 +267,7 @@ pub fn run_interface(context: Arc<Mutex<Context>>, miner: Arc<Mutex<Miner>>) {
|
||||
interface.exit();
|
||||
}
|
||||
|
||||
fn create_domain(context: Arc<Mutex<Context>>, miner: Arc<Mutex<Miner>>, name: &str, data: &str, 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();
|
||||
info!("Generating domain or zone {}", &name);
|
||||
if context.lock().unwrap().x_zones.has_zone(&name) {
|
||||
@ -268,7 +276,7 @@ fn create_domain(context: Arc<Mutex<Context>>, miner: Arc<Mutex<Miner>>, name: &
|
||||
}
|
||||
//let tags_vector: Vec<String> = tags.into().trim().split(",").map(|s| s.trim()).map(String::from).collect();
|
||||
let transaction = Transaction::from_str(name, "dns".to_owned(), data.to_owned(), keystore.get_public().clone());
|
||||
let block = Block::new(Some(transaction), keystore.get_public(), Bytes::default());
|
||||
let block = Block::new(Some(transaction), keystore.get_public(), Bytes::default(), difficulty);
|
||||
miner.lock().unwrap().add_block(block);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user