Changed identity format in transactions, now it will be double Sha256.

Added new checks for forked blocks.
Added options table.
Added posibility to replace blocks in DB by more appropriate forks.
Divided transactions table to domains and zones tables.
Added a timestamp to domains and zones table, it will give us possibility to purge old domains.
Changed difficulty check to check head and tail (sum of them) of the hash.
Added encrypted (by Chacha20) domain name to DomainData, added contacts and owners vectors for it too.
Added yggdrasil flag to ZoneData - it will restrict all IPs for domains in particular zone to Yggdrasil only.
Changed difficulties of various block types.
Added a temporary (for a run) unique ID to all handshakes.
Start of signing blocks mining will be after 60 seconds after full block.
Added mining status to statusbar.
This commit is contained in:
Revertron
2021-04-10 09:47:21 +02:00
parent e06088e0b0
commit a74a0733ac
24 changed files with 700 additions and 273 deletions
+27 -16
View File
@@ -16,9 +16,10 @@ use log::{trace, debug, info, warn, error};
use std::net::{SocketAddr, IpAddr, SocketAddrV4, Shutdown};
use std::collections::HashSet;
use crate::{Context, Block, p2p::Message, p2p::State, p2p::Peer, p2p::Peers, Bytes, is_yggdrasil};
use crate::blockchain::enums::BlockQuality;
use crate::blockchain::types::BlockQuality;
use crate::commons::CHAIN_VERSION;
use std::sync::atomic::{AtomicBool, Ordering};
use chrono::Utc;
const SERVER: Token = Token(0);
const POLL_TIMEOUT: Option<Duration> = Some(Duration::from_millis(3000));
@@ -49,7 +50,7 @@ impl Network {
let mut server = TcpListener::bind(addr).expect("Can't bind to address");
debug!("Started node listener on {}", server.local_addr().unwrap());
let mut events = Events::with_capacity(64);
let mut events = Events::with_capacity(1024);
let mut poll = Poll::new().expect("Unable to create poll");
poll.registry().register(&mut server, SERVER, Interest::READABLE).expect("Error registering poll");
let context = Arc::clone(&self.context);
@@ -132,7 +133,7 @@ impl Network {
}
events.clear();
if peers_timer.elapsed().as_millis() > 100 {
if peers_timer.elapsed().as_millis() > 500 {
// Send pings to idle peers
let (height, hash) = {
let mut context = context.lock().unwrap();
@@ -143,7 +144,7 @@ impl Network {
}
(height, context.chain.last_hash())
};
mine_locker_block(Arc::clone(&context));
mine_signing_block(Arc::clone(&context));
peers.send_pings(poll.registry(), height, hash);
peers.connect_new_peers(poll.registry(), &mut unique_token, yggdrasil_only);
peers_timer = Instant::now();
@@ -243,6 +244,7 @@ fn handle_connection_event(context: Arc<Mutex<Context>>, peers: &mut Peers, regi
if event.is_writable() {
//trace!("Socket {} is writable", event.token().0);
let my_id = peers.get_my_id().to_owned();
match peers.get_mut_peer(&event.token()) {
None => {}
Some(peer) => {
@@ -251,7 +253,7 @@ fn handle_connection_event(context: Arc<Mutex<Context>>, peers: &mut Peers, regi
debug!("Connected to peer {}, sending hello...", &peer.get_addr());
let data: String = {
let c = context.lock().unwrap();
let message = Message::hand(&c.app_version, &c.settings.origin, CHAIN_VERSION, c.settings.net.public, peer.get_rand());
let message = Message::hand(&c.app_version, &c.settings.origin, CHAIN_VERSION, c.settings.net.public, &my_id);
serde_json::to_string(&message).unwrap()
};
send_message(peer.get_stream(), &data.into_bytes()).unwrap_or_else(|e| warn!("Error sending hello {}", e));
@@ -471,10 +473,16 @@ fn handle_message(context: Arc<Mutex<Context>>, message: Message, peers: &mut Pe
}
BlockQuality::Twin => { debug!("Ignoring duplicate block {}", block.index); }
BlockQuality::Future => { debug!("Ignoring future block {}", block.index); }
BlockQuality::Bad => { debug!("Ignoring bad block {} with hash {:?}", block.index, block.hash); }
// TODO deal with forks
BlockQuality::Bad => {
// TODO save bad public keys to banned table
debug!("Ignoring bad block {} with hash {:?}", block.index, block.hash);
}
BlockQuality::Fork => {
debug!("Ignoring forked block {} with hash {:?}", block.index, block.hash);
debug!("Got forked block {} with hash {:?}", block.index, block.hash);
let last_block = context.chain.last_block().unwrap();
if block.is_better_than(&last_block) {
context.chain.replace_block(block.index, block).expect("Error replacing block with fork");
}
//let peer = peers.get_mut_peer(token).unwrap();
//deal_with_fork(context, peer, block);
}
@@ -487,21 +495,24 @@ fn handle_message(context: Arc<Mutex<Context>>, message: Message, peers: &mut Pe
}
/// Sends an Event to miner to start mining locker block if "locker" is our public key
fn mine_locker_block(context: Arc<Mutex<Context>>) {
fn mine_signing_block(context: Arc<Mutex<Context>>) {
let mut context = context.lock().unwrap();
if let Some(block) = context.chain.last_block() {
if let Some(block) = context.chain.get_last_full_block(None) {
if block.timestamp + 60 > Utc::now().timestamp() {
return;
}
if let Some(keystore) = &context.keystore {
if block.index < context.chain.max_height() {
trace!("No locker mining while syncing");
trace!("No signing while syncing");
return;
}
let lockers: HashSet<Bytes> = context.chain.get_block_lockers(&block).into_iter().collect();
if lockers.contains(&keystore.get_public()) {
info!("We have an honor to mine locker block!");
let signers: HashSet<Bytes> = context.chain.get_block_signers(&block).into_iter().collect();
if signers.contains(&keystore.get_public()) {
info!("We have an honor to mine signing block!");
let keystore = Box::new(keystore.clone());
context.bus.post(crate::event::Event::ActionMineLocker { index: block.index + 1, hash: block.hash, keystore });
} else if !lockers.is_empty() {
info!("Locker block must be mined by other nodes");
} else if !signers.is_empty() {
info!("Signing block must be mined by other nodes");
}
}
}
+5 -5
View File
@@ -2,14 +2,14 @@ use std::net::SocketAddr;
use std::collections::HashMap;
use mio::net::TcpStream;
use crate::p2p::State;
use crate::{Block, commons};
use crate::Block;
#[derive(Debug)]
pub struct Peer {
addr: SocketAddr,
stream: TcpStream,
state: State,
rand: String,
id: String,
height: u64,
inbound: bool,
public: bool,
@@ -26,7 +26,7 @@ impl Peer {
addr,
stream,
state,
rand: commons::random_string(6),
id: String::new(),
height: 0,
inbound,
public: false,
@@ -58,8 +58,8 @@ impl Peer {
self.state = state;
}
pub fn get_rand(&self) -> &str {
&self.rand
pub fn get_id(&self) -> &str {
&self.id
}
pub fn set_height(&mut self, height: u64) {
+9 -9
View File
@@ -9,20 +9,21 @@ use rand::random;
use rand::seq::IteratorRandom;
#[allow(unused_imports)]
use log::{trace, debug, info, warn, error};
use crate::{Bytes, is_yggdrasil};
use crate::{Bytes, is_yggdrasil, commons};
use crate::commons::MAX_RECONNECTS;
pub struct Peers {
peers: HashMap<Token, Peer>,
new_peers: Vec<SocketAddr>,
ignored: HashSet<IpAddr>
ignored: HashSet<IpAddr>,
my_id: String
}
const PING_PERIOD: u64 = 60;
impl Peers {
pub fn new() -> Self {
Peers { peers: HashMap::new(), new_peers: Vec::new(), ignored: HashSet::new() }
Peers { peers: HashMap::new(), new_peers: Vec::new(), ignored: HashSet::new(), my_id: commons::random_string(6) }
}
pub fn add_peer(&mut self, token: Token, peer: Peer) {
@@ -133,13 +134,12 @@ impl Peers {
}
}
pub fn get_my_id(&self) -> &str {
&self.my_id
}
pub fn is_our_own_connect(&self, rand: &str) -> bool {
match self.peers.values().find(|p| p.get_rand() == rand) {
None => { false }
Some(p) => {
!p.is_inbound()
}
}
self.my_id.eq(rand)
}
pub fn get_peers_for_exchange(&self, peer_address: &SocketAddr) -> Vec<String> {