Implemented P2P traffic encryption.
Changed serialization format of P2P messages. Refactored P2P network code.
This commit is contained in:
+4
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "alfis"
|
name = "alfis"
|
||||||
version = "0.5.9"
|
version = "0.6.0"
|
||||||
authors = ["Revertron <alfis@revertron.com>"]
|
authors = ["Revertron <alfis@revertron.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
@@ -18,7 +18,9 @@ toml = "0.5.8"
|
|||||||
digest = "0.9.0"
|
digest = "0.9.0"
|
||||||
sha2 = "0.9.5"
|
sha2 = "0.9.5"
|
||||||
ed25519-dalek = "1.0.1"
|
ed25519-dalek = "1.0.1"
|
||||||
|
x25519-dalek = "1.1.1"
|
||||||
ecies-ed25519 = "0.5.1"
|
ecies-ed25519 = "0.5.1"
|
||||||
|
chacha20poly1305 = "0.8.0"
|
||||||
signature = "1.3.0"
|
signature = "1.3.0"
|
||||||
blakeout = "0.3.0"
|
blakeout = "0.3.0"
|
||||||
num_cpus = "1.13.0"
|
num_cpus = "1.13.0"
|
||||||
@@ -26,6 +28,7 @@ byteorder = "1.4.3"
|
|||||||
serde = { version = "1.0.126", features = ["derive"] }
|
serde = { version = "1.0.126", features = ["derive"] }
|
||||||
serde_json = "1.0.64"
|
serde_json = "1.0.64"
|
||||||
bincode = "1.3.3"
|
bincode = "1.3.3"
|
||||||
|
serde_cbor = "0.11.1"
|
||||||
base64 = "0.13.0"
|
base64 = "0.13.0"
|
||||||
num-bigint = "0.4.0"
|
num-bigint = "0.4.0"
|
||||||
num-traits = "0.2.14"
|
num-traits = "0.2.14"
|
||||||
|
|||||||
@@ -61,13 +61,23 @@ impl Block {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn from_bytes(data: &[u8]) -> serde_cbor::Result<Self> {
|
||||||
|
serde_cbor::from_slice(data)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_genesis(&self) -> bool {
|
pub fn is_genesis(&self) -> bool {
|
||||||
self.index == 1 &&
|
self.index == 1 &&
|
||||||
matches!(Transaction::get_type(&self.transaction), TransactionType::Origin) &&
|
matches!(Transaction::get_type(&self.transaction), TransactionType::Origin) &&
|
||||||
self.prev_block_hash == Bytes::default()
|
self.prev_block_hash == Bytes::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Serializes block to CBOR for network
|
||||||
pub fn as_bytes(&self) -> Vec<u8> {
|
pub fn as_bytes(&self) -> Vec<u8> {
|
||||||
|
serde_cbor::to_vec(&self).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Serializes block to bincode format for hashing.
|
||||||
|
pub fn as_bytes_compact(&self) -> Vec<u8> {
|
||||||
bincode::serialize(&self).unwrap()
|
bincode::serialize(&self).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+27
-1
@@ -1010,8 +1010,10 @@ impl SignersCache {
|
|||||||
pub mod tests {
|
pub mod tests {
|
||||||
use log::LevelFilter;
|
use log::LevelFilter;
|
||||||
use simplelog::{ColorChoice, ConfigBuilder, TerminalMode, TermLogger};
|
use simplelog::{ColorChoice, ConfigBuilder, TerminalMode, TermLogger};
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use log::{debug, error, info, trace, warn};
|
||||||
|
|
||||||
use crate::{Chain, Settings};
|
use crate::{Chain, Settings, Block};
|
||||||
|
|
||||||
fn init_logger() {
|
fn init_logger() {
|
||||||
let config = ConfigBuilder::new()
|
let config = ConfigBuilder::new()
|
||||||
@@ -1035,4 +1037,28 @@ pub mod tests {
|
|||||||
chain.check_chain(u64::MAX);
|
chain.check_chain(u64::MAX);
|
||||||
assert_eq!(chain.get_height(), 149);
|
assert_eq!(chain.get_height(), 149);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn check_serde() {
|
||||||
|
let settings = Settings::default();
|
||||||
|
let chain = Chain::new(&settings, "./tests/blockchain.db");
|
||||||
|
|
||||||
|
// Check the first block, its transaction doesn't have identity
|
||||||
|
let block = chain.get_block(1).unwrap();
|
||||||
|
let buf = serde_cbor::to_vec(&block).unwrap();
|
||||||
|
let block2: Block = serde_cbor::from_slice(&buf[..]).unwrap();
|
||||||
|
assert_eq!(block, block2);
|
||||||
|
|
||||||
|
// Check second block, it is common "full" block with domain
|
||||||
|
let block = chain.get_block(2).unwrap();
|
||||||
|
let buf = serde_cbor::to_vec(&block).unwrap();
|
||||||
|
let block2: Block = serde_cbor::from_slice(&buf[..]).unwrap();
|
||||||
|
assert_eq!(block, block2);
|
||||||
|
|
||||||
|
// Check block 36, it is an "empty" block, used to sign full blocks
|
||||||
|
let block = chain.get_block(36).unwrap();
|
||||||
|
let buf = serde_cbor::to_vec(&block).unwrap();
|
||||||
|
let block2: Block = serde_cbor::from_slice(&buf[..]).unwrap();
|
||||||
|
assert_eq!(block, block2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -9,7 +9,7 @@ pub fn check_block_hash(block: &Block) -> bool {
|
|||||||
let mut copy: Block = block.clone();
|
let mut copy: Block = block.clone();
|
||||||
copy.hash = Bytes::default();
|
copy.hash = Bytes::default();
|
||||||
copy.signature = Bytes::default();
|
copy.signature = Bytes::default();
|
||||||
blakeout_data(©.as_bytes()) == block.hash
|
blakeout_data(©.as_bytes_compact()) == block.hash
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Hashes data by given hasher
|
/// Hashes data by given hasher
|
||||||
@@ -23,7 +23,7 @@ pub fn blakeout_data(data: &[u8]) -> Bytes {
|
|||||||
pub fn check_block_signature(block: &Block) -> bool {
|
pub fn check_block_signature(block: &Block) -> bool {
|
||||||
let mut copy = block.clone();
|
let mut copy = block.clone();
|
||||||
copy.signature = Bytes::default();
|
copy.signature = Bytes::default();
|
||||||
Keystore::check(©.as_bytes(), ©.pub_key, &block.signature)
|
Keystore::check(©.as_bytes_compact(), ©.pub_key, &block.signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Hashes some identity (domain in case of DNS). If you give it a public key, it will hash with it as well.
|
/// Hashes some identity (domain in case of DNS). If you give it a public key, it will hash with it as well.
|
||||||
|
|||||||
@@ -49,11 +49,6 @@ impl Transaction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_bytes(&self) -> Vec<u8> {
|
|
||||||
// Let it panic if something is not okay
|
|
||||||
serde_json::to_vec(&self).unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_string(&self) -> String {
|
pub fn to_string(&self) -> String {
|
||||||
// Let it panic if something is not okay
|
// Let it panic if something is not okay
|
||||||
serde_json::to_string(&self).unwrap()
|
serde_json::to_string(&self).unwrap()
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
use std::net::IpAddr;
|
use std::net::IpAddr;
|
||||||
use std::num;
|
use std::num;
|
||||||
|
|
||||||
use mio::Token;
|
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
use thread_priority::*;
|
use thread_priority::*;
|
||||||
@@ -116,13 +115,6 @@ pub fn is_yggdrasil(addr: &IpAddr) -> bool {
|
|||||||
false
|
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
|
/// Checks if this record has IP from Yggdrasil network
|
||||||
/// https://yggdrasil-network.github.io
|
/// https://yggdrasil-network.github.io
|
||||||
pub fn is_yggdrasil_record(record: &DnsRecord) -> bool {
|
pub fn is_yggdrasil_record(record: &DnsRecord) -> bool {
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
use chacha20poly1305::{ChaCha20Poly1305, Key, Nonce};
|
||||||
|
use chacha20poly1305::aead::{Aead, NewAead};
|
||||||
|
use std::fmt::{Debug, Formatter};
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
pub const ZERO_NONCE: [u8; 12] = [0u8; 12];
|
||||||
|
const FAILURE: &str = "encryption failure!";
|
||||||
|
|
||||||
|
/// A small wrap-up to use Chacha20 encryption for domain names.
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Chacha {
|
||||||
|
cipher: ChaCha20Poly1305,
|
||||||
|
nonce: [u8; 12]
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Chacha {
|
||||||
|
pub fn new(key: &[u8], nonce: &[u8]) -> Self {
|
||||||
|
let key = Key::from_slice(key);
|
||||||
|
let cipher = ChaCha20Poly1305::new(key);
|
||||||
|
let mut buf = [0u8; 12];
|
||||||
|
buf.copy_from_slice(nonce);
|
||||||
|
Chacha { cipher, nonce: buf }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn encrypt(&self, data: &[u8]) -> Vec<u8> {
|
||||||
|
let nonce = Nonce::from(self.nonce.clone());
|
||||||
|
self.cipher.encrypt(&nonce, data.as_ref()).expect(FAILURE)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn decrypt(&self, data: &[u8]) -> Vec<u8> {
|
||||||
|
let nonce = Nonce::from(self.nonce.clone());
|
||||||
|
self.cipher.decrypt(&nonce, data.as_ref()).expect(FAILURE)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_nonce(&self) -> &[u8; 12] {
|
||||||
|
&self.nonce
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Debug for Chacha {
|
||||||
|
fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
|
||||||
|
fmt.write_str("ChaCha20Poly1305")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::crypto::Chacha;
|
||||||
|
use crate::{to_hex};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
pub fn test_chacha() {
|
||||||
|
let buf = b"178135D209C697625E3EC71DA5C760382E54936F824EE5083908DA66B14ECE18";
|
||||||
|
let chacha1 = Chacha::new(b"178135D209C697625E3EC71DA5C76038", &buf[..12]);
|
||||||
|
let bytes1 = chacha1.encrypt(b"TEST");
|
||||||
|
println!("{}", to_hex(&bytes1));
|
||||||
|
|
||||||
|
let chacha2 = Chacha::new(b"178135D209C697625E3EC71DA5C76038", &buf[..12]);
|
||||||
|
let bytes2 = chacha2.decrypt(&bytes1);
|
||||||
|
assert_eq!(String::from_utf8(bytes2).unwrap(), "TEST");
|
||||||
|
|
||||||
|
let bytes2 = chacha2.encrypt(b"TEST");
|
||||||
|
|
||||||
|
assert_eq!(bytes1, bytes2);
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-1
@@ -1,3 +1,6 @@
|
|||||||
mod crypto_box;
|
mod crypto_box;
|
||||||
|
mod chacha;
|
||||||
|
|
||||||
pub use crypto_box::CryptoBox;
|
pub use crypto_box::CryptoBox;
|
||||||
|
pub use chacha::Chacha;
|
||||||
|
pub use chacha::ZERO_NONCE;
|
||||||
+5
-1
@@ -184,7 +184,11 @@ fn main() {
|
|||||||
let miner: Arc<Mutex<Miner>> = Arc::new(Mutex::new(miner_obj));
|
let miner: Arc<Mutex<Miner>> = Arc::new(Mutex::new(miner_obj));
|
||||||
|
|
||||||
let mut network = Network::new(Arc::clone(&context));
|
let mut network = Network::new(Arc::clone(&context));
|
||||||
network.start().expect("Error starting network component");
|
thread::spawn(move || {
|
||||||
|
// Give UI some time to appear :)
|
||||||
|
thread::sleep(Duration::from_millis(1000));
|
||||||
|
network.start();
|
||||||
|
});
|
||||||
|
|
||||||
create_genesis_if_needed(&context, &miner);
|
create_genesis_if_needed(&context, &miner);
|
||||||
if no_gui {
|
if no_gui {
|
||||||
|
|||||||
+2
-2
@@ -280,7 +280,7 @@ impl Miner {
|
|||||||
Some(mut block) => {
|
Some(mut block) => {
|
||||||
let index = block.index;
|
let index = block.index;
|
||||||
let mut context = context.lock().unwrap();
|
let mut context = context.lock().unwrap();
|
||||||
block.signature = Bytes::from_bytes(&job.keystore.sign(&block.as_bytes()));
|
block.signature = Bytes::from_bytes(&job.keystore.sign(&block.as_bytes_compact()));
|
||||||
let mut success = false;
|
let mut success = false;
|
||||||
if context.chain.check_new_block(&block) != BlockQuality::Good {
|
if context.chain.check_new_block(&block) != BlockQuality::Good {
|
||||||
warn!("Error adding mined block!");
|
warn!("Error adding mined block!");
|
||||||
@@ -341,7 +341,7 @@ fn find_hash(context: Arc<Mutex<Context>>, mut block: Block, running: Arc<Atomic
|
|||||||
block.nonce = nonce;
|
block.nonce = nonce;
|
||||||
|
|
||||||
digest.reset();
|
digest.reset();
|
||||||
digest.update(&block.as_bytes());
|
digest.update(&block.as_bytes_compact());
|
||||||
let diff = hash_difficulty(digest.result());
|
let diff = hash_difficulty(digest.result());
|
||||||
if diff >= target_diff {
|
if diff >= target_diff {
|
||||||
block.hash = Bytes::from_bytes(digest.result());
|
block.hash = Bytes::from_bytes(digest.result());
|
||||||
|
|||||||
+10
-28
@@ -7,8 +7,8 @@ use crate::Bytes;
|
|||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub enum Message {
|
pub enum Message {
|
||||||
Error,
|
Error,
|
||||||
Hand { #[serde(default = "default_version")] app_version: String, origin: String, version: u32, public: bool, #[serde(default)] rand: String },
|
Hand { app_version: String, origin: String, version: u32, public: bool, rand_id: String, },
|
||||||
Shake { #[serde(default = "default_version")] app_version: String, origin: String, version: u32, ok: bool, height: u64 },
|
Shake { app_version: String, origin: String, version: u32, public: bool, rand_id: String, height: u64 },
|
||||||
Ping { height: u64, hash: Bytes },
|
Ping { height: u64, hash: Bytes },
|
||||||
Pong { height: u64, hash: Bytes },
|
Pong { height: u64, hash: Bytes },
|
||||||
Twin,
|
Twin,
|
||||||
@@ -16,24 +16,23 @@ pub enum Message {
|
|||||||
GetPeers,
|
GetPeers,
|
||||||
Peers { peers: Vec<String> },
|
Peers { peers: Vec<String> },
|
||||||
GetBlock { index: u64 },
|
GetBlock { index: u64 },
|
||||||
Block { index: u64, block: String },
|
Block { index: u64, block: Vec<u8> },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Message {
|
impl Message {
|
||||||
pub fn from_bytes(bytes: Vec<u8>) -> Result<Self, ()> {
|
pub fn from_bytes(bytes: Vec<u8>) -> Result<Self, ()> {
|
||||||
let text = String::from_utf8(bytes).unwrap_or(String::from("Error{}"));
|
match serde_cbor::from_slice(bytes.as_slice()) {
|
||||||
match serde_json::from_str(&text) {
|
|
||||||
Ok(cmd) => Ok(cmd),
|
Ok(cmd) => Ok(cmd),
|
||||||
Err(_) => Err(())
|
Err(_) => Err(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hand(app_version: &str, origin: &str, version: u32, public: bool, rand: &str) -> Self {
|
pub fn hand(app_version: &str, origin: &str, version: u32, public: bool, rand_id: &str) -> Self {
|
||||||
Message::Hand { app_version: app_version.to_owned(), origin: origin.to_owned(), version, public, rand: rand.to_owned() }
|
Message::Hand { app_version: app_version.to_owned(), origin: origin.to_owned(), version, public, rand_id: rand_id.to_owned() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shake(app_version: &str, origin: &str, version: u32, ok: bool, height: u64) -> Self {
|
pub fn shake(app_version: &str, origin: &str, version: u32, public: bool, rand_id: &str, height: u64) -> Self {
|
||||||
Message::Shake { app_version: app_version.to_owned(), origin: origin.to_owned(), version, ok, height }
|
Message::Shake { app_version: app_version.to_owned(), origin: origin.to_owned(), version, public, rand_id: rand_id.to_owned(), height }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ping(height: u64, hash: Bytes) -> Self {
|
pub fn ping(height: u64, hash: Bytes) -> Self {
|
||||||
@@ -44,24 +43,7 @@ impl Message {
|
|||||||
Message::Pong { height, hash }
|
Message::Pong { height, hash }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn block(height: u64, str: String) -> Self {
|
pub fn block(height: u64, block: Vec<u8>) -> Self {
|
||||||
Message::Block { index: height, block: str }
|
Message::Block { index: height, block }
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn default_version() -> String {
|
|
||||||
String::from("0.0.0")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use crate::p2p::Message;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
pub fn test_hand() {
|
|
||||||
assert!(serde_json::from_str::<Message>("\"Error\"").is_ok());
|
|
||||||
assert!(serde_json::from_str::<Message>("{\"Hand\":{\"origin\":\"\",\"version\":1,\"public\":false,\"rand\":\"123\"}}").is_ok());
|
|
||||||
assert!(serde_json::from_str::<Message>("{\"Hand\":{\"origin\":\"\",\"version\":1,\"public\":false}}").is_ok());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
+683
-441
File diff suppressed because it is too large
Load Diff
@@ -3,6 +3,7 @@ use std::collections::HashMap;
|
|||||||
use mio::net::TcpStream;
|
use mio::net::TcpStream;
|
||||||
use crate::p2p::State;
|
use crate::p2p::State;
|
||||||
use crate::Block;
|
use crate::Block;
|
||||||
|
use crate::crypto::Chacha;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Peer {
|
pub struct Peer {
|
||||||
@@ -16,6 +17,7 @@ pub struct Peer {
|
|||||||
active: bool,
|
active: bool,
|
||||||
reconnects: u32,
|
reconnects: u32,
|
||||||
received_block: u64,
|
received_block: u64,
|
||||||
|
cipher: Option<Chacha>,
|
||||||
fork: HashMap<u64, Block>
|
fork: HashMap<u64, Block>
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,10 +34,26 @@ impl Peer {
|
|||||||
active: false,
|
active: false,
|
||||||
reconnects: 0,
|
reconnects: 0,
|
||||||
received_block: 0,
|
received_block: 0,
|
||||||
|
cipher: None,
|
||||||
fork: HashMap::new()
|
fork: HashMap::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_cipher(&mut self, cipher: Chacha) {
|
||||||
|
self.cipher = Some(cipher);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_cipher(&self) -> &Option<Chacha> {
|
||||||
|
&self.cipher
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_nonce(&self) -> &[u8; 12] {
|
||||||
|
match &self.cipher {
|
||||||
|
None => { &crate::crypto::ZERO_NONCE }
|
||||||
|
Some(chacha) => { chacha.get_nonce() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_addr(&self) -> SocketAddr {
|
pub fn get_addr(&self) -> SocketAddr {
|
||||||
self.addr.clone()
|
self.addr.clone()
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-1
@@ -12,7 +12,6 @@ use rand::seq::IteratorRandom;
|
|||||||
use crate::{Bytes, commons};
|
use crate::{Bytes, commons};
|
||||||
use crate::commons::*;
|
use crate::commons::*;
|
||||||
use crate::p2p::{Message, Peer, State};
|
use crate::p2p::{Message, Peer, State};
|
||||||
use crate::commons::next;
|
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
const PING_PERIOD: u64 = 30;
|
const PING_PERIOD: u64 = 30;
|
||||||
@@ -84,6 +83,12 @@ impl Peers {
|
|||||||
State::Twin => {
|
State::Twin => {
|
||||||
info!("Peer connection {} to {:?} is a twin", &token.0, &peer.get_addr());
|
info!("Peer connection {} to {:?} is a twin", &token.0, &peer.get_addr());
|
||||||
}
|
}
|
||||||
|
State::ServerHandshake => {
|
||||||
|
info!("Peer connection {} from {:?} didn't shake hands", &token.0, &peer.get_addr());
|
||||||
|
}
|
||||||
|
State::HandshakeFinished => {
|
||||||
|
info!("Peer connection {} from {:?} shaked hands, but then failed", &token.0, &peer.get_addr());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.peers.remove(token);
|
self.peers.remove(token);
|
||||||
@@ -193,6 +198,15 @@ impl Peers {
|
|||||||
count
|
count
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_tween_connect(&self, id: &str) -> bool {
|
||||||
|
for (_, peer) in self.peers.iter() {
|
||||||
|
if peer.active() && peer.get_id() == id {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_peers_banned_count(&self) -> usize {
|
pub fn get_peers_banned_count(&self) -> usize {
|
||||||
self.ignored.len()
|
self.ignored.len()
|
||||||
}
|
}
|
||||||
@@ -401,6 +415,13 @@ impl Peers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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)
|
||||||
|
}
|
||||||
|
|
||||||
fn skip_private_addr(addr: &SocketAddr) -> bool {
|
fn skip_private_addr(addr: &SocketAddr) -> bool {
|
||||||
if addr.ip().is_loopback() {
|
if addr.ip().is_loopback() {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
+4
-2
@@ -5,6 +5,8 @@ use crate::p2p::Message;
|
|||||||
pub enum State {
|
pub enum State {
|
||||||
Connecting,
|
Connecting,
|
||||||
Connected,
|
Connected,
|
||||||
|
ServerHandshake,
|
||||||
|
HandshakeFinished,
|
||||||
Idle { from: Instant },
|
Idle { from: Instant },
|
||||||
Message { data: Vec<u8> },
|
Message { data: Vec<u8> },
|
||||||
Error,
|
Error,
|
||||||
@@ -25,8 +27,8 @@ impl State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn message(message: Message) -> Self {
|
pub fn message(message: Message) -> Self {
|
||||||
let response = serde_json::to_string(&message).unwrap();
|
let data = serde_cbor::to_vec(&message).unwrap();
|
||||||
State::Message {data: Vec::from(response.as_bytes()) }
|
State::Message { data }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_idle(&self) -> bool {
|
pub fn is_idle(&self) -> bool {
|
||||||
|
|||||||
Reference in New Issue
Block a user