Added new option -l to write log messages to file. Changed old -l flag to -b.
This commit is contained in:
+2
-2
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "alfis"
|
||||
version = "0.4.7"
|
||||
version = "0.4.8"
|
||||
authors = ["Revertron <alfis@revertron.com>"]
|
||||
edition = "2018"
|
||||
build = "build.rs"
|
||||
@@ -12,7 +12,7 @@ repository = "https://github.com/Revertron/Alfis"
|
||||
[dependencies]
|
||||
getopts = "0.2.21"
|
||||
log = "0.4.14"
|
||||
simple_logger = "1.11.0"
|
||||
simplelog = "0.10"
|
||||
toml = "0.5.8"
|
||||
digest = "0.9.0"
|
||||
sha2 = "0.9.3"
|
||||
|
||||
@@ -32,3 +32,8 @@ pub const MAX_RECONNECTS: u32 = 5;
|
||||
|
||||
pub const CLASS_ZONE: &str = "zone";
|
||||
pub const CLASS_DOMAIN: &str = "domain";
|
||||
|
||||
/// Public nodes listen port
|
||||
pub const LISTEN_PORT: u16 = 4244;
|
||||
pub const UI_REFRESH_DELAY_MS: u128 = 250;
|
||||
pub const LOG_REFRESH_DELAY_SEC: u64 = 60;
|
||||
|
||||
+16
-6
@@ -1,14 +1,17 @@
|
||||
use std::num;
|
||||
use rand::Rng;
|
||||
|
||||
pub mod constants;
|
||||
pub use constants::*;
|
||||
use std::net::IpAddr;
|
||||
use std::num;
|
||||
|
||||
use mio::Token;
|
||||
use rand::Rng;
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
use thread_priority::*;
|
||||
|
||||
pub use constants::*;
|
||||
|
||||
use crate::dns::protocol::DnsRecord;
|
||||
|
||||
pub mod constants;
|
||||
|
||||
/// Convert bytes array to HEX format
|
||||
pub fn to_hex(buf: &[u8]) -> String {
|
||||
let mut result = String::new();
|
||||
@@ -95,6 +98,13 @@ pub fn is_yggdrasil(addr: &IpAddr) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Gets new token from old token, mutating the last
|
||||
pub fn next(current: &mut Token) -> Token {
|
||||
let next = current.0;
|
||||
current.0 += 1;
|
||||
Token(next)
|
||||
}
|
||||
|
||||
/// Checks if this record has IP from Yggdrasil network
|
||||
/// https://yggdrasil-network.github.io
|
||||
pub fn is_yggdrasil_record(record: &DnsRecord) -> bool {
|
||||
@@ -134,8 +144,8 @@ pub fn setup_miner_thread(cpu: u32) {
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::{check_domain, is_yggdrasil};
|
||||
use std::net::IpAddr;
|
||||
use crate::{check_domain, is_yggdrasil};
|
||||
|
||||
#[test]
|
||||
fn test_check_domain() {
|
||||
|
||||
+55
-16
@@ -9,14 +9,17 @@ use std::sync::{Arc, Mutex};
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
use getopts::Options;
|
||||
use getopts::{Options, Matches};
|
||||
#[allow(unused_imports)]
|
||||
use log::{debug, error, info, trace, warn, LevelFilter};
|
||||
use simple_logger::SimpleLogger;
|
||||
use simplelog::*;
|
||||
#[cfg(windows)]
|
||||
use winapi::um::wincon::{ATTACH_PARENT_PROCESS, AttachConsole, FreeConsole};
|
||||
|
||||
use alfis::{Block, Bytes, Chain, Miner, Context, Network, Settings, dns_utils, Keystore, ZONE_DIFFICULTY};
|
||||
use std::fs::OpenOptions;
|
||||
use std::process::exit;
|
||||
use std::io::{Seek, SeekFrom};
|
||||
|
||||
#[cfg(feature = "webgui")]
|
||||
mod web_ui;
|
||||
@@ -42,8 +45,9 @@ fn main() {
|
||||
opts.optflag("n", "nogui", "Run without graphic user interface (default for no gui builds)");
|
||||
opts.optflag("v", "verbose", "Show more debug messages");
|
||||
opts.optflag("d", "debug", "Show trace messages, more than debug");
|
||||
opts.optflag("l", "list", "List blocks from DB and exit");
|
||||
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("l", "log", "Write log to file", "FILE");
|
||||
opts.optopt("c", "config", "Path to config file", "FILE");
|
||||
opts.optopt("w", "work-dir", "Path to working directory", "DIRECTORY");
|
||||
opts.optopt("u", "upgrade", "Path to config file that you want to upgrade. Upgraded config will be printed to console.", "FILE");
|
||||
@@ -82,13 +86,6 @@ fn main() {
|
||||
#[cfg(not(feature = "webgui"))]
|
||||
let no_gui = true;
|
||||
|
||||
let mut level = LevelFilter::Info;
|
||||
if opt_matches.opt_present("v") {
|
||||
level = LevelFilter::Debug;
|
||||
}
|
||||
if opt_matches.opt_present("d") {
|
||||
level = LevelFilter::Trace;
|
||||
}
|
||||
let config_name = match opt_matches.opt_str("c") {
|
||||
None => { SETTINGS_FILENAME.to_owned() }
|
||||
Some(path) => { path }
|
||||
@@ -97,18 +94,14 @@ fn main() {
|
||||
env::set_current_dir(Path::new(&path)).expect(&format!("Unable to change working directory to '{}'", &path));
|
||||
}
|
||||
|
||||
SimpleLogger::new()
|
||||
.with_level(level)
|
||||
.with_module_level("mio::poll", LevelFilter::Warn)
|
||||
.init()
|
||||
.unwrap();
|
||||
setup_logger(&opt_matches);
|
||||
info!(target: LOG_TARGET_MAIN, "Starting ALFIS {}", env!("CARGO_PKG_VERSION"));
|
||||
|
||||
let settings = Settings::load(&config_name).expect(&format!("Cannot load settings from {}!", &config_name));
|
||||
info!(target: LOG_TARGET_MAIN, "Loaded settings: {:?}", &settings);
|
||||
let keystore = Keystore::from_file(&settings.key_file, "");
|
||||
let chain: Chain = Chain::new(&settings);
|
||||
if opt_matches.opt_present("l") {
|
||||
if opt_matches.opt_present("b") {
|
||||
for i in 1..(chain.height() + 1) {
|
||||
if let Some(block) = chain.get_block(i) {
|
||||
info!(target: LOG_TARGET_MAIN, "{:?}", &block);
|
||||
@@ -152,12 +145,58 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets up logger in accordance with command line options
|
||||
fn setup_logger(opt_matches: &Matches) {
|
||||
let mut level = LevelFilter::Info;
|
||||
if opt_matches.opt_present("v") {
|
||||
level = LevelFilter::Debug;
|
||||
}
|
||||
if opt_matches.opt_present("d") {
|
||||
level = LevelFilter::Trace;
|
||||
}
|
||||
let config = ConfigBuilder::new()
|
||||
.add_filter_ignore_str("mio::poll")
|
||||
.set_thread_level(LevelFilter::Off)
|
||||
.set_location_level(LevelFilter::Off)
|
||||
.set_target_level(LevelFilter::Error)
|
||||
.set_time_level(LevelFilter::Error)
|
||||
.set_time_to_local(true)
|
||||
.build();
|
||||
match opt_matches.opt_str("l") {
|
||||
None => {
|
||||
if let Err(e) = TermLogger::init(level, config, TerminalMode::Stdout, ColorChoice::Auto) {
|
||||
println!("Unable to initialize logger!\n{}", e);
|
||||
}
|
||||
}
|
||||
Some(path) => {
|
||||
let file = match OpenOptions::new().write(true).create(true).open(&path) {
|
||||
Ok(mut file) => {
|
||||
file.seek(SeekFrom::End(0)).unwrap();
|
||||
file
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Could not open log file '{}' for writing!\n{}", &path, e);
|
||||
exit(1);
|
||||
}
|
||||
};
|
||||
CombinedLogger::init(
|
||||
vec![
|
||||
TermLogger::new(level, config.clone(), TerminalMode::Stdout, ColorChoice::Auto),
|
||||
WriteLogger::new(level, config, file),
|
||||
]
|
||||
).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets own domains by current loaded keystore and writes them to log
|
||||
fn print_my_domains(context: &Arc<Mutex<Context>>) {
|
||||
let context = context.lock().unwrap();
|
||||
let domains = context.chain.get_my_domains(&context.keystore);
|
||||
debug!("Domains: {:?}", &domains);
|
||||
}
|
||||
|
||||
/// Creates genesis (origin) block if `origin` is empty in config and we don't have any blocks in DB
|
||||
fn create_genesis_if_needed(context: &Arc<Mutex<Context>>, miner: &Arc<Mutex<Miner>>) {
|
||||
// If there is no origin in settings and no blockchain in DB, generate genesis block
|
||||
let context = context.lock().unwrap();
|
||||
|
||||
+16
-18
@@ -3,26 +3,25 @@ extern crate serde_json;
|
||||
|
||||
use std::{io, thread};
|
||||
use std::io::{Read, Write};
|
||||
use std::net::{IpAddr, Shutdown, SocketAddr, SocketAddrV4};
|
||||
use std::sync::{Arc, Mutex, MutexGuard};
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||
#[allow(unused_imports)]
|
||||
use log::{debug, error, info, trace, warn};
|
||||
use mio::{Events, Interest, Poll, Registry, Token};
|
||||
use mio::event::Event;
|
||||
use mio::net::{TcpListener, TcpStream};
|
||||
#[allow(unused_imports)]
|
||||
use log::{trace, debug, info, warn, error};
|
||||
|
||||
use std::net::{SocketAddr, IpAddr, SocketAddrV4, Shutdown};
|
||||
use crate::{Context, Block, p2p::Message, p2p::State, p2p::Peer, p2p::Peers, is_yggdrasil};
|
||||
use crate::blockchain::types::BlockQuality;
|
||||
use crate::commons::CHAIN_VERSION;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use rand::random;
|
||||
|
||||
use crate::{Block, Context, p2p::Message, p2p::Peer, p2p::Peers, p2p::State};
|
||||
use crate::blockchain::types::BlockQuality;
|
||||
use crate::commons::*;
|
||||
|
||||
const SERVER: Token = Token(0);
|
||||
const POLL_TIMEOUT: Option<Duration> = Some(Duration::from_millis(1000));
|
||||
pub const LISTEN_PORT: u16 = 4244;
|
||||
const MAX_PACKET_SIZE: usize = 1 * 1024 * 1024; // 1 Mb
|
||||
const MAX_READ_BLOCK_TIME: u128 = 500;
|
||||
|
||||
@@ -63,7 +62,8 @@ impl Network {
|
||||
// Starting peer connections to bootstrap nodes
|
||||
peers.connect_peers(&peers_addrs, &poll.registry(), &mut unique_token, yggdrasil_only);
|
||||
|
||||
let mut peers_timer = Instant::now();
|
||||
let mut ui_timer = Instant::now();
|
||||
let mut log_timer = Instant::now();
|
||||
let mut bootstrap_timer = Instant::now();
|
||||
loop {
|
||||
if peers.get_peers_count() == 0 && bootstrap_timer.elapsed().as_secs() > 60 {
|
||||
@@ -138,7 +138,7 @@ impl Network {
|
||||
}
|
||||
events.clear();
|
||||
|
||||
if peers_timer.elapsed().as_millis() > 250 {
|
||||
if ui_timer.elapsed().as_millis() > UI_REFRESH_DELAY_MS {
|
||||
// Send pings to idle peers
|
||||
let (height, hash) = {
|
||||
let mut context = context.lock().unwrap();
|
||||
@@ -147,11 +147,15 @@ impl Network {
|
||||
if nodes > 0 {
|
||||
context.bus.post(crate::event::Event::NetworkStatus { nodes, blocks: height });
|
||||
}
|
||||
if log_timer.elapsed().as_secs() > LOG_REFRESH_DELAY_SEC {
|
||||
info!("Active nodes count: {}, blocks count: {}", nodes, height);
|
||||
log_timer = Instant::now();
|
||||
}
|
||||
(height, context.chain.last_hash())
|
||||
};
|
||||
peers.update(poll.registry(), height, hash);
|
||||
peers.connect_new_peers(poll.registry(), &mut unique_token, yggdrasil_only);
|
||||
peers_timer = Instant::now();
|
||||
ui_timer = Instant::now();
|
||||
}
|
||||
}
|
||||
if !running.load(Ordering::SeqCst) {
|
||||
@@ -557,12 +561,6 @@ fn check_block(block: &Block, prev: &Block) -> bool {
|
||||
prev.index == block.index - 1 && prev.hash == block.prev_block_hash
|
||||
}
|
||||
|
||||
pub(crate) fn next(current: &mut Token) -> Token {
|
||||
let next = current.0;
|
||||
current.0 += 1;
|
||||
Token(next)
|
||||
}
|
||||
|
||||
fn would_block(err: &io::Error) -> bool {
|
||||
err.kind() == io::ErrorKind::WouldBlock
|
||||
}
|
||||
|
||||
+12
-11
@@ -1,17 +1,18 @@
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::net::{SocketAddr, IpAddr, Shutdown, ToSocketAddrs};
|
||||
use mio::{Token, Interest, Registry};
|
||||
use std::net::{IpAddr, Shutdown, SocketAddr, ToSocketAddrs};
|
||||
|
||||
use chrono::Utc;
|
||||
#[allow(unused_imports)]
|
||||
use log::{debug, error, info, trace, warn};
|
||||
use mio::{Interest, Registry, Token};
|
||||
use mio::net::TcpStream;
|
||||
use crate::p2p::{Peer, State, Message};
|
||||
use crate::p2p::network::LISTEN_PORT;
|
||||
use crate::p2p::network::next;
|
||||
use rand::random;
|
||||
use rand::seq::IteratorRandom;
|
||||
#[allow(unused_imports)]
|
||||
use log::{trace, debug, info, warn, error};
|
||||
use crate::{Bytes, is_yggdrasil, commons};
|
||||
use crate::commons::MAX_RECONNECTS;
|
||||
use chrono::Utc;
|
||||
|
||||
use crate::{Bytes, commons};
|
||||
use crate::commons::*;
|
||||
use crate::p2p::{Message, Peer, State};
|
||||
use crate::commons::next;
|
||||
|
||||
pub struct Peers {
|
||||
peers: HashMap<Token, Peer>,
|
||||
@@ -90,7 +91,7 @@ impl Peers {
|
||||
peers.insert(peer.to_owned());
|
||||
peers
|
||||
});
|
||||
debug!("Got {} peers", peers.len());
|
||||
debug!("Got {} peers from exchange", peers.len());
|
||||
//debug!("Got {} peers: {:?}", peers.len(), &peers);
|
||||
// TODO make it return error if these peers are wrong and seem like an attack
|
||||
for peer in peers.iter() {
|
||||
|
||||
Reference in New Issue
Block a user