Fixed signers' calculation loop. Fixed block checks. Added trace logging level. Updated dependencies.

pull/246/head
Revertron 2 years ago
parent 84fc3e8d4a
commit 410bc9b7e4

99
Cargo.lock generated

@ -84,7 +84,7 @@ dependencies = [
[[package]]
name = "alfis"
version = "0.7.0"
version = "0.7.1"
dependencies = [
"base64",
"bincode",
@ -759,34 +759,14 @@ dependencies = [
[[package]]
name = "mio"
version = "0.8.2"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9"
checksum = "713d550d9b44d89174e066b7a6217ae06234c10cb47819a88290d2b353c31799"
dependencies = [
"libc",
"log",
"miow",
"ntapi",
"wasi 0.11.0+wasi-snapshot-preview1",
"winapi",
]
[[package]]
name = "miow"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
dependencies = [
"winapi",
]
[[package]]
name = "ntapi"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44"
dependencies = [
"winapi",
"windows-sys",
]
[[package]]
@ -911,9 +891,9 @@ checksum = "c3ca011bd0129ff4ae15cd04c4eef202cadf6c51c21e47aba319b4e0501db741"
[[package]]
name = "proc-macro2"
version = "1.0.30"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edc3358ebc67bc8b7fa0c007f945b0b18226f78437d61bec735a9eb96b61ee70"
checksum = "9027b48e9d4c9175fa2218adf3557f91c1137021739951d4932f5f8268ac48aa"
dependencies = [
"unicode-xid",
]
@ -1058,18 +1038,18 @@ checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012"
[[package]]
name = "serde"
version = "1.0.136"
version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789"
checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_bytes"
version = "0.11.5"
version = "0.11.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16ae07dd2f88a366f15bd0632ba725227018c69a1c8550a927324f8eb8368bb9"
checksum = "212e73464ebcde48d723aa02eb270ba62eff38a9b732df31f33f1b4e145f3a54"
dependencies = [
"serde",
]
@ -1086,9 +1066,9 @@ dependencies = [
[[package]]
name = "serde_derive"
version = "1.0.136"
version = "1.0.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9"
checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be"
dependencies = [
"proc-macro2",
"quote",
@ -1224,9 +1204,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
[[package]]
name = "syn"
version = "1.0.80"
version = "1.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d010a1623fbd906d51d650a9916aaefc05ffa0e4053ff7fe601167f3e715d194"
checksum = "04066589568b72ec65f42d65a1a52436e954b168773148893c020269563decf2"
dependencies = [
"proc-macro2",
"quote",
@ -1339,9 +1319,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
name = "toml"
version = "0.5.8"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
dependencies = [
"serde",
]
@ -1438,9 +1418,9 @@ checksum = "5a1f0175e03a0973cf4afd476bef05c26e228520400eb1fd473ad417b1c00ffb"
[[package]]
name = "uuid"
version = "0.8.2"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7"
checksum = "8cfcd319456c4d6ea10087ed423473267e1a071f3bc0aa89f80d60997843c6f0"
dependencies = [
"getrandom 0.2.3",
"serde",
@ -1642,6 +1622,49 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
dependencies = [
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_msvc"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
[[package]]
name = "windows_i686_gnu"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
[[package]]
name = "windows_i686_msvc"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
[[package]]
name = "windows_x86_64_gnu"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
[[package]]
name = "windows_x86_64_msvc"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
[[package]]
name = "winres"
version = "0.1.12"

@ -1,6 +1,6 @@
[package]
name = "alfis"
version = "0.7.0"
version = "0.7.1"
authors = ["Revertron <alfis@revertron.com>"]
edition = "2021"
build = "build.rs"
@ -14,7 +14,7 @@ exclude = ["blockchain.db", "alfis.toml"]
getopts = "0.2.21"
log = "0.4.16"
simplelog = "0.11.2"
toml = "0.5.8"
toml = "0.5.9"
digest = "0.10.2"
sha2 = "0.10.2"
ed25519-dalek = "1.0"
@ -25,7 +25,7 @@ signature = "1.5"
blakeout = "0.3.0"
num_cpus = "1.13.1"
byteorder = "1.4.3"
serde = { version = "1.0.136", features = ["derive"] }
serde = { version = "1.0.137", features = ["derive"] }
serde_json = "1.0.79"
bincode = "1.3.3"
serde_cbor = "0.11.2"
@ -36,8 +36,8 @@ chrono = { version = "0.4.19", features = ["serde"] }
rand = { version = "0.8.5", package = "rand" }
rand-old = { package = "rand", version = "0.7.0" } # For ed25519-dalek
sqlite = "0.26.0"
uuid = { version = "0.8.2", features = ["serde", "v4"] }
mio = { version = "0.8.2", features = ["os-poll", "net"] }
uuid = { version = "1.0.0", features = ["serde", "v4"] }
mio = { version = "0.8.3", features = ["os-poll", "net"] }
ureq = { version = "2.4", optional = true }
lru = "0.7.5"
derive_more = "0.99.17"
@ -59,7 +59,7 @@ thread-priority = "0.8.2"
winres = "0.1.12"
[dev-dependencies]
serde_bytes = "0.11.5"
serde_bytes = "0.11.6"
serde_derive = "1.0.126"
[profile.release]

@ -36,7 +36,7 @@ const SQL_GET_BLOCK_BY_ID: &str = "SELECT * FROM blocks WHERE id=? LIMIT 1;";
const SQL_GET_LAST_FULL_BLOCK: &str = "SELECT * FROM blocks WHERE id < ? AND `transaction`<>'' ORDER BY id DESC LIMIT 1;";
const SQL_GET_LAST_FULL_BLOCK_FOR_KEY: &str = "SELECT * FROM blocks WHERE id < ? AND `transaction`<>'' AND pub_key = ? ORDER BY id DESC LIMIT 1;";
const SQL_GET_DOMAIN_OWNER_BY_ID: &str = "SELECT signing FROM domains WHERE id < ? AND identity = ? ORDER BY id DESC LIMIT 1;";
const SQL_GET_DOMAIN_BY_ID: &str = "SELECT * FROM domains WHERE identity = ? ORDER BY id DESC LIMIT 1;";
const SQL_GET_DOMAIN_BY_ID: &str = "SELECT * FROM domains WHERE identity = ? AND id < ? ORDER BY id DESC LIMIT 1;";
const SQL_GET_DOMAINS_BY_KEY: &str = "SELECT timestamp, identity, data, signing FROM domains WHERE signing = ? ORDER BY id;";
const SQL_GET_DOMAINS_COUNT: &str = "SELECT count(DISTINCT identity) FROM domains;";
const SQL_GET_USERS_COUNT: &str = "SELECT count(DISTINCT pub_key) FROM blocks;";
@ -606,12 +606,13 @@ impl Chain {
None
}
pub fn get_domain_update_time(&self, identity_hash: &Bytes) -> Option<i64> {
pub fn get_domain_update_time(&self, identity_hash: &Bytes, height: u64, time: i64) -> Option<i64> {
let mut statement = self.db.prepare(SQL_GET_DOMAIN_BY_ID).unwrap();
statement.bind(1, identity_hash.as_slice()).expect("Error in bind");
statement.bind(2, height as i64 ).expect("Error in bind");
if let State::Row = statement.next().unwrap() {
let timestamp = statement.read::<i64>(1).unwrap();
if timestamp < Utc::now().timestamp() - DOMAIN_LIFETIME {
if timestamp < time - DOMAIN_LIFETIME {
// This domain is too old
return None;
}
@ -620,7 +621,7 @@ impl Chain {
None
}
pub fn get_domain_transaction_by_id(&self, identity_hash: &Bytes) -> Option<Transaction> {
pub fn get_domain_transaction_by_id(&self, identity_hash: &Bytes, height: u64) -> Option<Transaction> {
if self.get_domain_renewal_time(identity_hash).is_none() {
// Domain has expired
return None;
@ -628,6 +629,7 @@ impl Chain {
let mut statement = self.db.prepare(SQL_GET_DOMAIN_BY_ID).unwrap();
statement.bind(1, identity_hash.as_slice()).expect("Error in bind");
statement.bind(2, height as i64).expect("Error in bind");
if let State::Row = statement.next().unwrap() {
let timestamp = statement.read::<i64>(1).unwrap();
if timestamp < Utc::now().timestamp() - DOMAIN_LIFETIME {
@ -652,7 +654,7 @@ impl Chain {
return None;
}
let identity_hash = hash_identity(domain, None);
if let Some(transaction) = self.get_domain_transaction_by_id(&identity_hash) {
if let Some(transaction) = self.get_domain_transaction_by_id(&identity_hash, self.get_height()) {
debug!("Found transaction for domain {}: {:?}", domain, &transaction);
if transaction.check_identity(domain) {
return Some(transaction);
@ -704,6 +706,7 @@ impl Chain {
let pub_key = keystore.get_public();
let mut statement = self.db.prepare(SQL_GET_DOMAINS_BY_KEY).unwrap();
statement.bind(1, &**pub_key).expect("Error in bind");
let height = self.get_height();
while let State::Row = statement.next().unwrap() {
let timestamp = statement.read::<i64>(0).unwrap();
let identity = Bytes::from_bytes(&statement.read::<Vec<u8>>(1).unwrap());
@ -711,7 +714,7 @@ impl Chain {
let signing = Bytes::from_bytes(&statement.read::<Vec<u8>>(3).unwrap());
// Get the last transaction for this id and check if it is still ours
if let Some(transaction) = self.get_domain_transaction_by_id(&identity) {
if let Some(transaction) = self.get_domain_transaction_by_id(&identity, height) {
if transaction.signing != signing {
trace!("Identity {:?} is not ours anymore, skipping", &identity);
continue;
@ -818,10 +821,10 @@ impl Chain {
SIGNER_DIFFICULTY
}
}
Some(t) => self.get_difficulty_for_transaction(t)
Some(t) => self.get_difficulty_for_transaction(t, block.index, block.timestamp)
};
if block.difficulty < difficulty {
warn!("Block difficulty is lower than needed");
warn!("Block difficulty is lower than needed: {} < {}", block.difficulty, difficulty);
return Bad;
}
if hash_difficulty(&block.hash) < block.difficulty {
@ -987,11 +990,11 @@ impl Chain {
true
}
fn get_difficulty_for_transaction(&self, transaction: &Transaction) -> u32 {
fn get_difficulty_for_transaction(&self, transaction: &Transaction, height: u64, time: i64) -> u32 {
match transaction.class.as_ref() {
CLASS_DOMAIN => {
// If this domain is already in blockchain we approve slightly smaller difficulty
let discount = self.get_identity_discount(&transaction.identity, false);
let discount = self.get_identity_discount(&transaction.identity, false, height, time);
// TODO move this check somewhere appropriate
return match serde_json::from_str::<DomainData>(&transaction.data) {
Ok(_) => DOMAIN_DIFFICULTY - discount,
@ -1006,8 +1009,8 @@ impl Chain {
}
}
pub fn get_identity_discount(&self, identity: &Bytes, renewal: bool) -> u32 {
match self.get_domain_update_time(identity) {
pub fn get_identity_discount(&self, identity: &Bytes, renewal: bool, height: u64, time: i64) -> u32 {
match self.get_domain_update_time(identity, height, time) {
None => 0u32,
Some(timestamp) => {
if renewal || self.get_height() < BLOCKS_WITHOUT_DISCOUNT {
@ -1039,9 +1042,11 @@ impl Chain {
}
let mut set = HashSet::new();
let tail = block.signature.get_tail_u64();
let mut tail = block.signature.get_tail_u64();
let mut count = 1;
let mut mitigated = false;
let window = block.index - 1; // Without the last block
trace!("Calculating signers, tail: {}, window: {}", tail, window);
while set.len() < BLOCK_SIGNERS_ALL as usize {
let index = (tail.wrapping_mul(count) % window) + 1; // We want it to start from 1
if let Some(b) = self.get_block(index) {
@ -1057,8 +1062,12 @@ impl Chain {
}
}
count += 1;
if !mitigated && count > 25 {
tail = tail / 13;
mitigated = true;
}
}
trace!("Got signers for block {}: {:?}", block.index, &result);
debug!("Got signers for block {}: {:?}, loop count {}", block.index, &result, count);
let mut signers = self.signers.borrow_mut();
signers.index = block.index;
signers.signers = result.clone();

@ -35,6 +35,7 @@ pub const DB_NAME: &str = "blockchain.db";
pub const CLASS_ORIGIN: &str = "origin";
pub const CLASS_DOMAIN: &str = "domain";
pub const ALFIS_DEBUG: &str = "ALFIS_DEBUG";
pub const ALFIS_TRACE: &str = "ALFIS_TRACE";
/// Public nodes listen port
pub const LISTEN_PORT: u16 = 4244;
@ -48,4 +49,4 @@ pub const MIN_CONNECTED_NODES_START_SYNC: usize = 4;
pub const MAX_READ_BLOCK_TIME: u128 = 100;
pub const MAX_RECONNECTS: u32 = 5;
pub const MAX_IDLE_SECONDS: u64 = 180;
pub const MAX_NODES: usize = 15;
pub const MAX_NODES: usize = 25;

@ -24,9 +24,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
use alfis::event::Event;
use alfis::eventbus::{post, register};
use alfis::keystore::create_key;
use alfis::{
dns_utils, Block, Bytes, Chain, Context, Keystore, Miner, Network, Settings, Transaction, ALFIS_DEBUG, DB_NAME, ORIGIN_DIFFICULTY
};
use alfis::{dns_utils, Block, Bytes, Chain, Context, Keystore, Miner, Network, Settings, Transaction, ALFIS_DEBUG, ALFIS_TRACE, DB_NAME, ORIGIN_DIFFICULTY};
#[cfg(feature = "webgui")]
mod web_ui;
@ -53,7 +51,8 @@ fn main() {
opts.optflag("h", "help", "Print this help menu");
opts.optflag("n", "nogui", "Run without graphic user interface (default for no gui builds)");
opts.optflag("v", "version", "Print version and exit");
opts.optflag("d", "debug", "Show trace messages, more than debug");
opts.optflag("d", "debug", "Show debug messages, more than usual");
opts.optflag("t", "trace", "Show trace messages, more than debug");
opts.optflag("b", "blocks", "List blocks from DB and exit");
opts.optflag("g", "generate", "Generate new config file. Generated config will be printed to console.");
opts.optopt("k", "gen-key", "Generate new keys and save them to file.", "FILE");
@ -248,6 +247,9 @@ fn main() {
fn setup_logger(opt_matches: &Matches, console_attached: bool) {
let mut level = LevelFilter::Info;
if opt_matches.opt_present("d") || env::var(ALFIS_DEBUG).is_ok() {
level = LevelFilter::Debug;
}
if opt_matches.opt_present("t") || env::var(ALFIS_TRACE).is_ok() {
level = LevelFilter::Trace;
}
let config = ConfigBuilder::new()

@ -132,7 +132,7 @@ impl Miner {
info!("Replacing current mining job with signing job!");
// We cancel current job, waiting for threads to finish
mining.store(false, Ordering::SeqCst);
thread::sleep(Duration::from_millis(100));
sleep(Duration::from_millis(100));
// Return current job to queue
jobs.insert(0, current_job.take().unwrap());

@ -17,7 +17,7 @@ use alfis::event::Event;
use alfis::eventbus::{post, register};
use alfis::miner::Miner;
use alfis::{keystore, Block, Bytes, Context, Keystore, Transaction};
use chrono::{DateTime, Local};
use chrono::{DateTime, Local, Utc};
#[allow(unused_imports)]
use log::{debug, error, info, trace, warn, LevelFilter};
use serde::{Deserialize, Serialize};
@ -574,7 +574,8 @@ fn create_domain(context: Arc<Mutex<Context>>, miner: Arc<Mutex<Miner>>, class:
};
let transaction = Transaction::from_str(name, class.to_owned(), data, signing, encryption);
// If this domain is already in blockchain we approve slightly smaller difficulty
let discount = context.lock().unwrap().chain.get_identity_discount(&transaction.identity, renewal);
let height = context.lock().unwrap().chain.get_height();
let discount = context.lock().unwrap().chain.get_identity_discount(&transaction.identity, renewal, height, Utc::now().timestamp());
let block = Block::new(Some(transaction), keystore.get_public(), Bytes::default(), difficulty - discount);
miner.lock().unwrap().add_block(block, keystore.clone());
}

Loading…
Cancel
Save