Merge branch 'master' into fix_236
This commit is contained in:
commit
3c4dd55999
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -19,6 +19,7 @@ extern crate import;
|
|||
|
||||
mod commands;
|
||||
mod config;
|
||||
mod seednodes;
|
||||
mod util;
|
||||
|
||||
use app_dirs::AppInfo;
|
||||
|
|
|
@ -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"
|
||||
]
|
||||
}
|
|
@ -206,7 +206,7 @@ impl PreviousTransactionOutputProvider for EmptyTransactionOutputProvider {
|
|||
None
|
||||
}
|
||||
|
||||
fn is_spent(&self, prevout: &OutPoint) -> bool {
|
||||
fn is_spent(&self, _prevout: &OutPoint) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue