Merge branch 'master' into fix_236

This commit is contained in:
NikVolf 2016-11-30 20:03:49 +03:00
commit 3c4dd55999
13 changed files with 140 additions and 28 deletions

View File

@ -15,7 +15,6 @@ use std::collections::HashSet;
use std::collections::BTreeSet;
use ser::{Serializable, serialize};
use heapsize::HeapSizeOf;
use db::TransactionMetaProvider;
/// Transactions ordering strategy
#[cfg_attr(feature="cargo-clippy", allow(enum_variant_names))]
@ -713,7 +712,7 @@ impl PreviousTransactionOutputProvider for MemoryPool {
.cloned()
}
fn is_spent(&self, prevout: &OutPoint) -> bool {
fn is_spent(&self, _prevout: &OutPoint) -> bool {
false
}
}

View File

@ -1,8 +1,8 @@
use std::net::SocketAddr;
use std::path::PathBuf;
use std::{net, path};
use net::Config as NetConfig;
use util::InternetProtocol;
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct Config {
/// Number of threads used by p2p thread pool.
pub threads: usize,
@ -13,9 +13,11 @@ pub struct Config {
/// Configuration for every connection.
pub connection: NetConfig,
/// Connect only ot these nodes.
pub peers: Vec<SocketAddr>,
pub peers: Vec<net::SocketAddr>,
/// Connect to these nodes to retrieve peer addresses, and disconnect.
pub seeds: Vec<String>,
/// p2p/nodes.csv file path
pub node_table_path: PathBuf,
pub node_table_path: path::PathBuf,
/// Internet protocol.
pub internet_protocol: InternetProtocol,
}

View File

@ -32,5 +32,5 @@ pub use config::Config;
pub use net::Config as NetConfig;
pub use p2p::P2P;
pub use event_loop::{event_loop, forever};
pub use util::{PeerId, PeerInfo};
pub use util::{PeerId, PeerInfo, InternetProtocol};
pub use protocol::{InboundSyncConnection, InboundSyncConnectionRef, OutboundSyncConnection, OutboundSyncConnectionRef, LocalSyncNode, LocalSyncNodeRef};

View File

@ -1,4 +1,4 @@
use std::{io, net, error, time, path};
use std::{io, net, error, time};
use std::sync::Arc;
use parking_lot::RwLock;
use futures::{Future, finished, failed, BoxFuture};
@ -35,12 +35,12 @@ pub struct Context {
/// Local synchronization node.
local_sync_node: LocalSyncNodeRef,
/// Node table path.
node_table_path: path::PathBuf,
config: Config,
}
impl Context {
/// Creates new context with reference to local sync node, thread pool and event loop.
pub fn new(local_sync_node: LocalSyncNodeRef, pool_handle: CpuPool, remote: Remote, config: &Config) -> Result<Self, Box<error::Error>> {
pub fn new(local_sync_node: LocalSyncNodeRef, pool_handle: CpuPool, remote: Remote, config: Config) -> Result<Self, Box<error::Error>> {
let context = Context {
connections: Default::default(),
connection_counter: ConnectionCounter::new(config.inbound_connections, config.outbound_connections),
@ -48,7 +48,7 @@ impl Context {
pool: pool_handle,
remote: remote,
local_sync_node: local_sync_node,
node_table_path: config.node_table_path.clone(),
config: config,
};
Ok(context)
@ -79,7 +79,7 @@ impl Context {
/// Returns addresses of recently active nodes. Sorted and limited to 1000.
pub fn node_table_entries(&self) -> Vec<Node> {
self.node_table.read().recently_active_nodes()
self.node_table.read().recently_active_nodes(self.config.internet_protocol)
}
/// Updates node table.
@ -104,7 +104,7 @@ impl Context {
let used_addresses = context.connections.addresses();
let max = (ic.1 + oc.1) as usize;
let needed = context.connection_counter.outbound_connections_needed() as usize;
let peers = context.node_table.read().nodes_with_services(&Services::default(), max);
let peers = context.node_table.read().nodes_with_services(&Services::default(), context.config.internet_protocol, max);
let addresses = peers.into_iter()
.map(|peer| peer.address())
.filter(|address| !used_addresses.contains(address))
@ -116,7 +116,7 @@ impl Context {
Context::connect::<NormalSessionFactory>(context.clone(), address, config.clone());
}
if let Err(_err) = context.node_table.read().save_to_file(&context.node_table_path) {
if let Err(_err) = context.node_table.read().save_to_file(&context.config.node_table_path) {
error!("Saving node table to disk failed");
}
@ -398,7 +398,7 @@ impl P2P {
pub fn new(config: Config, local_sync_node: LocalSyncNodeRef, handle: Handle) -> Result<Self, Box<error::Error>> {
let pool = CpuPool::new(config.threads);
let context = try!(Context::new(local_sync_node, pool.clone(), handle.remote().clone(), &config));
let context = try!(Context::new(local_sync_node, pool.clone(), handle.remote().clone(), config.clone()));
let p2p = P2P {
event_loop_handle: handle.clone(),

View File

@ -0,0 +1,59 @@
use std::{str, net};
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum InternetProtocol {
Any,
IpV4,
IpV6,
}
impl Default for InternetProtocol {
fn default() -> Self {
InternetProtocol::Any
}
}
impl str::FromStr for InternetProtocol {
type Err = &'static str;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"ipv4" => Ok(InternetProtocol::IpV4),
"ipv6" => Ok(InternetProtocol::IpV6),
_ => Err("Invalid internet protocol"),
}
}
}
impl InternetProtocol {
pub fn is_allowed(&self, addr: &net::SocketAddr) -> bool {
match *self {
InternetProtocol::Any => true,
InternetProtocol::IpV4 => match *addr {
net::SocketAddr::V4(_) => true,
_ => false,
},
InternetProtocol::IpV6 => match *addr {
net::SocketAddr::V6(_) => true,
_ => false,
}
}
}
}
#[cfg(test)]
mod tests {
use super::InternetProtocol;
#[test]
fn test_default_internet_protocol() {
assert_eq!(InternetProtocol::default(), InternetProtocol::Any);
}
#[test]
fn test_parsing_internet_protocol() {
assert_eq!(InternetProtocol::IpV4, "ipv4".parse().unwrap());
assert_eq!(InternetProtocol::IpV6, "ipv6".parse().unwrap());
assert!("sa".parse::<InternetProtocol>().is_err());
}
}

View File

@ -1,10 +1,12 @@
pub mod nonce;
pub mod time;
mod internet_protocol;
mod node_table;
mod peer;
mod response_queue;
mod synchronizer;
pub use self::internet_protocol::InternetProtocol;
pub use self::node_table::{NodeTable, Node};
pub use self::peer::{PeerId, PeerInfo, Direction};
pub use self::response_queue::{ResponseQueue, Responses};

View File

@ -7,6 +7,7 @@ use csv;
use message::common::{Services, NetAddress};
use message::types::addr::AddressEntry;
use util::time::{Time, RealTime};
use util::InternetProtocol;
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Node {
@ -254,8 +255,9 @@ impl<T> NodeTable<T> where T: Time {
}
/// Returnes most reliable nodes with desired services.
pub fn nodes_with_services(&self, services: &Services, limit: usize) -> Vec<Node> {
pub fn nodes_with_services(&self, services: &Services, protocol: InternetProtocol, limit: usize) -> Vec<Node> {
self.by_score.iter()
.filter(|node| protocol.is_allowed(&node.0.addr))
.filter(|node| node.0.services.includes(services))
.map(|node| node.0.clone())
.take(limit)
@ -270,8 +272,9 @@ impl<T> NodeTable<T> where T: Time {
/// Let's do the same.
///
/// https://en.bitcoin.it/wiki/Protocol_documentation#addr
pub fn recently_active_nodes(&self) -> Vec<Node> {
pub fn recently_active_nodes(&self, protocol: InternetProtocol) -> Vec<Node> {
self.by_time.iter()
.filter(|node| protocol.is_allowed(&node.0.addr))
.map(|node| node.0.clone())
.take(1000)
.collect()
@ -350,6 +353,7 @@ impl<T> NodeTable<T> where T: Time {
mod tests {
use std::net::SocketAddr;
use message::common::Services;
use util::InternetProtocol;
use util::time::{IncrementalTime, ZeroTime};
use super::NodeTable;
@ -362,7 +366,7 @@ mod tests {
table.insert(s0, Services::default());
table.insert(s1, Services::default());
table.insert(s2, Services::default());
let nodes = table.nodes_with_services(&Services::default(), 2);
let nodes = table.nodes_with_services(&Services::default(), InternetProtocol::default(), 2);
assert_eq!(nodes.len(), 2);
assert_eq!(nodes[0].addr, s2);
assert_eq!(nodes[0].time, 2);
@ -390,7 +394,7 @@ mod tests {
table.note_used(&s1);
table.note_failure(&s2);
table.note_failure(&s3);
let nodes = table.nodes_with_services(&Services::default(), 10);
let nodes = table.nodes_with_services(&Services::default(), InternetProtocol::default(), 10);
assert_eq!(nodes.len(), 5);
assert_eq!(nodes[0].addr, s1);
@ -413,7 +417,7 @@ mod tests {
assert_eq!(nodes[4].time, 3);
assert_eq!(nodes[4].failures, 1);
let nodes = table.recently_active_nodes();
let nodes = table.recently_active_nodes(InternetProtocol::default());
assert_eq!(nodes.len(), 5);
assert_eq!(nodes[0].addr, s1);

View File

@ -38,6 +38,11 @@ args:
- db-cache:
long: db-cache
help: Sets db cache size
- only-net:
long: only-net
value_name: NET
help: Only connect to nodes in network <NET> (ipv4 or ipv6)
takes_value: true
subcommands:
- import:
about: Import blocks from bitcoin core database

View File

@ -27,8 +27,9 @@ pub fn start(cfg: config::Config) -> Result<(), String> {
relay: false,
},
peers: cfg.connect.map_or_else(|| vec![], |x| vec![x]),
seeds: cfg.seednode.map_or_else(|| vec![], |x| vec![x]),
seeds: cfg.seednodes,
node_table_path: nodes_path,
internet_protocol: cfg.internet_protocol,
};
let sync_handle = el.handle();

View File

@ -1,13 +1,15 @@
use std::net;
use clap;
use network::Magic;
use p2p::InternetProtocol;
use seednodes::{mainnet_seednodes, testnet_seednodes};
use {USER_AGENT, REGTEST_USER_AGENT};
pub struct Config {
pub magic: Magic,
pub port: u16,
pub connect: Option<net::SocketAddr>,
pub seednode: Option<String>,
pub seednodes: Vec<String>,
pub print_to_console: bool,
pub inbound_connections: u32,
pub outbound_connections: u32,
@ -15,6 +17,7 @@ pub struct Config {
pub db_cache: usize,
pub data_dir: Option<String>,
pub user_agent: String,
pub internet_protocol: InternetProtocol,
}
pub const DEFAULT_DB_CACHE: usize = 512;
@ -59,9 +62,13 @@ pub fn parse(matches: &clap::ArgMatches) -> Result<Config, String> {
None => None,
};
let seednode = match matches.value_of("seednode") {
Some(s) => Some(try!(s.parse().map_err(|_| "Invalid seednode".to_owned()))),
None => None,
let seednodes = match matches.value_of("seednode") {
Some(s) => vec![try!(s.parse().map_err(|_| "Invalid seednode".to_owned()))],
None => match magic {
Magic::Mainnet => mainnet_seednodes().into_iter().map(Into::into).collect(),
Magic::Testnet => testnet_seednodes().into_iter().map(Into::into).collect(),
Magic::Other(_) | Magic::Regtest => Vec::new(),
},
};
let db_cache = match matches.value_of("db-cache") {
@ -74,18 +81,24 @@ pub fn parse(matches: &clap::ArgMatches) -> Result<Config, String> {
None => None,
};
let only_net = match matches.value_of("only-net") {
Some(s) => try!(s.parse()),
None => InternetProtocol::default(),
};
let config = Config {
print_to_console: print_to_console,
magic: magic,
port: port,
connect: connect,
seednode: seednode,
seednodes: seednodes,
inbound_connections: in_connections,
outbound_connections: out_connections,
p2p_threads: p2p_threads,
db_cache: db_cache,
data_dir: data_dir,
user_agent: user_agent.to_string(),
internet_protocol: only_net,
};
Ok(config)

View File

@ -19,6 +19,7 @@ extern crate import;
mod commands;
mod config;
mod seednodes;
mod util;
use app_dirs::AppInfo;

26
pbtc/seednodes.rs Normal file
View File

@ -0,0 +1,26 @@
pub fn mainnet_seednodes() -> Vec<&'static str> {
vec![
// Pieter Wuille
"seed.bitcoin.sipa.be:8333",
// Matt Corallo
"dnsseed.bluematt.me:8333",
// Luke Dashjr
"dnsseed.bitcoin.dashjr.org:8333",
// Christian Decker
"seed.bitcoinstats.com:8333",
// Jeff Garzik
"bitseed.xf2.org:8333",
// Jonas Schnelli
"seed.bitcoin.jonasschnelli.ch:8333"
]
}
pub fn testnet_seednodes() -> Vec<&'static str> {
vec![
"testnet-seed.bitcoin.jonasschnelli.ch:18333",
"seed.tbtc.petertodd.org:18333",
"testnet-seed.bluematt.me:18333",
"testnet-seed.bitcoin.schildbach.de:18333"
]
}

View File

@ -206,7 +206,7 @@ impl PreviousTransactionOutputProvider for EmptyTransactionOutputProvider {
None
}
fn is_spent(&self, prevout: &OutPoint) -> bool {
fn is_spent(&self, _prevout: &OutPoint) -> bool {
false
}
}