2
0
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:
Revertron 2021-03-17 14:55:05 +01:00
parent d8ac1e3c32
commit 1d9833db0f
10 changed files with 95 additions and 36 deletions

View File

@ -1,5 +1,5 @@
# Settings
origin = ""
origin = "00000087A1BA6F94781C77BBDA96CC548E1E7F502DB3EA3F103ACD9301813B43"
key_file = "default.key"
listen = "[::]:4244"
public = false

View File

@ -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,

View File

@ -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 => {

View File

@ -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;

View File

@ -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 => {}

View File

@ -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
}

View File

@ -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);
}
}

View File

@ -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() }

View File

@ -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])

View File

@ -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);
}