mirror of
https://github.com/mimblewimble/grin.git
synced 2025-02-08 12:21:09 +03:00
Add a peers_preferred option in Grin (#1401)
* Preferred peers option * Move P2P configuration into proper config part * Fix tests
This commit is contained in:
parent
2251a82404
commit
8cd1b23f7a
14 changed files with 174 additions and 109 deletions
26
grin.toml
26
grin.toml
|
@ -25,14 +25,6 @@ api_http_addr = "127.0.0.1:13413"
|
||||||
|
|
||||||
db_root = ".grin"
|
db_root = ".grin"
|
||||||
|
|
||||||
#How to seed this server, can be None, List, WebStatic or DNSSeed
|
|
||||||
#
|
|
||||||
#seeding_type = "None"
|
|
||||||
|
|
||||||
#If seeding_type = List, the list of peers to connect to.
|
|
||||||
#
|
|
||||||
#seeds = ["192.168.0.1:13414","192.168.0.2:13414"]
|
|
||||||
|
|
||||||
#The chain type, which defines the genesis block and the set of cuckoo
|
#The chain type, which defines the genesis block and the set of cuckoo
|
||||||
#parameters used for mining. Can be:
|
#parameters used for mining. Can be:
|
||||||
#AutomatedTesting - For CI builds and instant blockchain creation
|
#AutomatedTesting - For CI builds and instant blockchain creation
|
||||||
|
@ -51,10 +43,6 @@ chain_type = "Testnet3"
|
||||||
#run the node in "full archive" mode (default is fast-sync, pruned node)
|
#run the node in "full archive" mode (default is fast-sync, pruned node)
|
||||||
#archive_mode = false
|
#archive_mode = false
|
||||||
|
|
||||||
#7 = Bit flags for FULL_NODE, this structure needs to be changed
|
|
||||||
#internally to make it more configurable
|
|
||||||
capabilities = [7]
|
|
||||||
|
|
||||||
#skip waiting for sync on startup, (optional param, mostly for testing)
|
#skip waiting for sync on startup, (optional param, mostly for testing)
|
||||||
skip_sync_wait = false
|
skip_sync_wait = false
|
||||||
|
|
||||||
|
@ -98,11 +86,25 @@ stem_probability = 90
|
||||||
host = "0.0.0.0"
|
host = "0.0.0.0"
|
||||||
port = 13414
|
port = 13414
|
||||||
|
|
||||||
|
#How to seed this server, can be None, List, WebStatic or DNSSeed
|
||||||
|
#
|
||||||
|
#seeding_type = "None"
|
||||||
|
|
||||||
|
#If seeding_type = List, the list of peers to connect to.
|
||||||
|
#
|
||||||
|
#seeds = ["192.168.0.1:13414","192.168.0.2:13414"]
|
||||||
|
|
||||||
|
#7 = Bit flags for FULL_NODE, this structure needs to be changed
|
||||||
|
#internally to make it more configurable
|
||||||
|
capabilities = [7]
|
||||||
|
|
||||||
#hardcoded peer lists for allow/deny
|
#hardcoded peer lists for allow/deny
|
||||||
#will *only* connect to peers in allow list
|
#will *only* connect to peers in allow list
|
||||||
#peers_allow = ["192.168.0.1:13414", "192.168.0.2:13414"]
|
#peers_allow = ["192.168.0.1:13414", "192.168.0.2:13414"]
|
||||||
#will *never* connect to peers in deny list
|
#will *never* connect to peers in deny list
|
||||||
#peers_deny = ["192.168.0.3:13414", "192.168.0.4:13414"]
|
#peers_deny = ["192.168.0.3:13414", "192.168.0.4:13414"]
|
||||||
|
#a list of preferred peers to connect to
|
||||||
|
#peers_preferred = ["192.168.0.1:13414","192.168.0.2:13414"]
|
||||||
|
|
||||||
#how long a banned peer should stay banned
|
#how long a banned peer should stay banned
|
||||||
#ban_window = 10800
|
#ban_window = 10800
|
||||||
|
|
|
@ -54,5 +54,7 @@ pub use peer::Peer;
|
||||||
pub use peers::Peers;
|
pub use peers::Peers;
|
||||||
pub use serv::{DummyAdapter, Server};
|
pub use serv::{DummyAdapter, Server};
|
||||||
pub use store::{PeerData, State};
|
pub use store::{PeerData, State};
|
||||||
pub use types::{Capabilities, ChainAdapter, Direction, Error, P2PConfig, PeerInfo, ReasonForBan,
|
pub use types::{
|
||||||
TxHashSetRead, MAX_BLOCK_HEADERS, MAX_LOCATORS, MAX_PEER_ADDRS};
|
Capabilities, ChainAdapter, Direction, Error, P2PConfig, PeerInfo, ReasonForBan, Seeding,
|
||||||
|
TxHashSetRead, MAX_BLOCK_HEADERS, MAX_LOCATORS, MAX_PEER_ADDRS,
|
||||||
|
};
|
||||||
|
|
|
@ -161,8 +161,7 @@ impl Peer {
|
||||||
/// Send the ban reason before banning
|
/// Send the ban reason before banning
|
||||||
pub fn send_ban_reason(&self, ban_reason: ReasonForBan) {
|
pub fn send_ban_reason(&self, ban_reason: ReasonForBan) {
|
||||||
let ban_reason_msg = BanReason { ban_reason };
|
let ban_reason_msg = BanReason { ban_reason };
|
||||||
match self
|
match self.connection
|
||||||
.connection
|
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.send(ban_reason_msg, msg::Type::BanReason)
|
.send(ban_reason_msg, msg::Type::BanReason)
|
||||||
|
|
|
@ -109,8 +109,7 @@ impl Peers {
|
||||||
|
|
||||||
/// Get vec of peers we are currently connected to.
|
/// Get vec of peers we are currently connected to.
|
||||||
pub fn connected_peers(&self) -> Vec<Arc<RwLock<Peer>>> {
|
pub fn connected_peers(&self) -> Vec<Arc<RwLock<Peer>>> {
|
||||||
let mut res = self
|
let mut res = self.peers
|
||||||
.peers
|
|
||||||
.read()
|
.read()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.values()
|
.values()
|
||||||
|
|
|
@ -169,9 +169,10 @@ impl MessageHandler for Protocol {
|
||||||
let headers = adapter.locate_headers(loc.hashes);
|
let headers = adapter.locate_headers(loc.hashes);
|
||||||
|
|
||||||
// serialize and send all the headers over
|
// serialize and send all the headers over
|
||||||
Ok(Some(
|
Ok(Some(msg.respond(
|
||||||
msg.respond(Type::Headers, Headers { headers: headers }),
|
Type::Headers,
|
||||||
))
|
Headers { headers: headers },
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// "header first" block propagation - if we have not yet seen this block
|
// "header first" block propagation - if we have not yet seen this block
|
||||||
|
@ -275,8 +276,7 @@ impl MessageHandler for Protocol {
|
||||||
);
|
);
|
||||||
|
|
||||||
let tmp_zip = File::open(tmp)?;
|
let tmp_zip = File::open(tmp)?;
|
||||||
let res = self
|
let res = self.adapter
|
||||||
.adapter
|
|
||||||
.txhashset_write(sm_arch.hash, tmp_zip, self.addr);
|
.txhashset_write(sm_arch.hash, tmp_zip, self.addr);
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
|
|
|
@ -96,10 +96,24 @@ pub struct P2PConfig {
|
||||||
pub host: IpAddr,
|
pub host: IpAddr,
|
||||||
pub port: u16,
|
pub port: u16,
|
||||||
|
|
||||||
|
/// Method used to get the list of seed nodes for initial bootstrap.
|
||||||
|
#[serde(default)]
|
||||||
|
pub seeding_type: Seeding,
|
||||||
|
|
||||||
|
/// The list of seed nodes, if using Seeding as a seed type
|
||||||
|
pub seeds: Option<Vec<String>>,
|
||||||
|
|
||||||
|
/// Capabilities expose by this node, also conditions which other peers this
|
||||||
|
/// node will have an affinity toward when connection.
|
||||||
|
pub capabilities: Capabilities,
|
||||||
|
|
||||||
pub peers_allow: Option<Vec<String>>,
|
pub peers_allow: Option<Vec<String>>,
|
||||||
|
|
||||||
pub peers_deny: Option<Vec<String>>,
|
pub peers_deny: Option<Vec<String>>,
|
||||||
|
|
||||||
|
/// The list of preferred peers that we will try to connect to
|
||||||
|
pub peers_preferred: Option<Vec<String>>,
|
||||||
|
|
||||||
pub ban_window: Option<i64>,
|
pub ban_window: Option<i64>,
|
||||||
|
|
||||||
pub peer_max_count: Option<u32>,
|
pub peer_max_count: Option<u32>,
|
||||||
|
@ -114,8 +128,12 @@ impl Default for P2PConfig {
|
||||||
P2PConfig {
|
P2PConfig {
|
||||||
host: ipaddr,
|
host: ipaddr,
|
||||||
port: 13414,
|
port: 13414,
|
||||||
|
capabilities: Capabilities::FULL_NODE,
|
||||||
|
seeding_type: Seeding::default(),
|
||||||
|
seeds: None,
|
||||||
peers_allow: None,
|
peers_allow: None,
|
||||||
peers_deny: None,
|
peers_deny: None,
|
||||||
|
peers_preferred: None,
|
||||||
ban_window: None,
|
ban_window: None,
|
||||||
peer_max_count: None,
|
peer_max_count: None,
|
||||||
peer_min_preferred_count: None,
|
peer_min_preferred_count: None,
|
||||||
|
@ -151,6 +169,27 @@ impl P2PConfig {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Type of seeding the server will use to find other peers on the network.
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||||
|
pub enum Seeding {
|
||||||
|
/// No seeding, mostly for tests that programmatically connect
|
||||||
|
None,
|
||||||
|
/// A list of seed addresses provided to the server
|
||||||
|
List,
|
||||||
|
/// Automatically download a text file with a list of server addresses
|
||||||
|
WebStatic,
|
||||||
|
/// Automatically get a list of seeds from multiple DNS
|
||||||
|
DNSSeed,
|
||||||
|
/// Mostly for tests, where connections are initiated programmatically
|
||||||
|
Programmatic,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Seeding {
|
||||||
|
fn default() -> Seeding {
|
||||||
|
Seeding::DNSSeed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
/// Options for what type of interaction a peer supports
|
/// Options for what type of interaction a peer supports
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
|
@ -206,7 +245,7 @@ pub struct PeerInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The full txhashset data along with indexes required for a consumer to
|
/// The full txhashset data along with indexes required for a consumer to
|
||||||
/// rewind to a consistant requested state.
|
/// rewind to a consistent requested state.
|
||||||
pub struct TxHashSetRead {
|
pub struct TxHashSetRead {
|
||||||
/// Output tree index the receiver should rewind to
|
/// Output tree index the receiver should rewind to
|
||||||
pub output_index: u64,
|
pub output_index: u64,
|
||||||
|
|
|
@ -164,8 +164,7 @@ impl p2p::ChainAdapter for NetToChainAdapter {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let chain = self
|
let chain = self.chain
|
||||||
.chain
|
|
||||||
.upgrade()
|
.upgrade()
|
||||||
.expect("failed to upgrade weak ref to chain");
|
.expect("failed to upgrade weak ref to chain");
|
||||||
|
|
||||||
|
@ -438,8 +437,7 @@ impl NetToChainAdapter {
|
||||||
// we have a fast sync'd node and are sent a block older than our horizon,
|
// we have a fast sync'd node and are sent a block older than our horizon,
|
||||||
// only sync can do something with that
|
// only sync can do something with that
|
||||||
if b.header.height
|
if b.header.height
|
||||||
< head
|
< head.height
|
||||||
.height
|
|
||||||
.saturating_sub(global::cut_through_horizon() as u64)
|
.saturating_sub(global::cut_through_horizon() as u64)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -103,27 +103,6 @@ impl Default for ChainValidationMode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Type of seeding the server will use to find other peers on the network.
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
|
||||||
pub enum Seeding {
|
|
||||||
/// No seeding, mostly for tests that programmatically connect
|
|
||||||
None,
|
|
||||||
/// A list of seed addresses provided to the server
|
|
||||||
List,
|
|
||||||
/// Automatically download a text file with a list of server addresses
|
|
||||||
WebStatic,
|
|
||||||
/// Automatically get a list of seeds from multiple DNS
|
|
||||||
DNSSeed,
|
|
||||||
/// Mostly for tests, where connections are initiated programmatically
|
|
||||||
Programmatic,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Seeding {
|
|
||||||
fn default() -> Seeding {
|
|
||||||
Seeding::DNSSeed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Full server configuration, aggregating configurations required for the
|
/// Full server configuration, aggregating configurations required for the
|
||||||
/// different components.
|
/// different components.
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||||
|
@ -145,19 +124,6 @@ pub struct ServerConfig {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub chain_validation_mode: ChainValidationMode,
|
pub chain_validation_mode: ChainValidationMode,
|
||||||
|
|
||||||
/// Method used to get the list of seed nodes for initial bootstrap.
|
|
||||||
#[serde(default)]
|
|
||||||
pub seeding_type: Seeding,
|
|
||||||
|
|
||||||
/// TODO - move this into p2p_config?
|
|
||||||
/// The list of seed nodes, if using Seeding as a seed type
|
|
||||||
pub seeds: Option<Vec<String>>,
|
|
||||||
|
|
||||||
/// TODO - move this into p2p_config?
|
|
||||||
/// Capabilities expose by this node, also conditions which other peers this
|
|
||||||
/// node will have an affinity toward when connection.
|
|
||||||
pub capabilities: p2p::Capabilities,
|
|
||||||
|
|
||||||
/// Configuration for the peer-to-peer server
|
/// Configuration for the peer-to-peer server
|
||||||
pub p2p_config: p2p::P2PConfig,
|
pub p2p_config: p2p::P2PConfig,
|
||||||
|
|
||||||
|
@ -201,9 +167,6 @@ impl Default for ServerConfig {
|
||||||
ServerConfig {
|
ServerConfig {
|
||||||
db_root: ".grin".to_string(),
|
db_root: ".grin".to_string(),
|
||||||
api_http_addr: "127.0.0.1:13413".to_string(),
|
api_http_addr: "127.0.0.1:13413".to_string(),
|
||||||
capabilities: p2p::Capabilities::FULL_NODE,
|
|
||||||
seeding_type: Seeding::default(),
|
|
||||||
seeds: None,
|
|
||||||
p2p_config: p2p::P2PConfig::default(),
|
p2p_config: p2p::P2PConfig::default(),
|
||||||
dandelion_config: pool::DandelionConfig::default(),
|
dandelion_config: pool::DandelionConfig::default(),
|
||||||
stratum_mining_config: Some(StratumServerConfig::default()),
|
stratum_mining_config: Some(StratumServerConfig::default()),
|
||||||
|
|
|
@ -42,6 +42,7 @@ pub fn connect_and_monitor(
|
||||||
capabilities: p2p::Capabilities,
|
capabilities: p2p::Capabilities,
|
||||||
dandelion_config: DandelionConfig,
|
dandelion_config: DandelionConfig,
|
||||||
seed_list: Box<Fn() -> Vec<SocketAddr> + Send>,
|
seed_list: Box<Fn() -> Vec<SocketAddr> + Send>,
|
||||||
|
preferred_peers: Option<Vec<SocketAddr>>,
|
||||||
stop: Arc<AtomicBool>,
|
stop: Arc<AtomicBool>,
|
||||||
) {
|
) {
|
||||||
let _ = thread::Builder::new()
|
let _ = thread::Builder::new()
|
||||||
|
@ -54,7 +55,12 @@ pub fn connect_and_monitor(
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
|
|
||||||
// check seeds first
|
// check seeds first
|
||||||
connect_to_seeds(peers.clone(), tx.clone(), seed_list);
|
connect_to_seeds_and_preferred_peers(
|
||||||
|
peers.clone(),
|
||||||
|
tx.clone(),
|
||||||
|
seed_list,
|
||||||
|
preferred_peers.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
let mut prev = Utc::now() - Duration::seconds(60);
|
let mut prev = Utc::now() - Duration::seconds(60);
|
||||||
loop {
|
loop {
|
||||||
|
@ -72,6 +78,7 @@ pub fn connect_and_monitor(
|
||||||
p2p_server.config.clone(),
|
p2p_server.config.clone(),
|
||||||
capabilities,
|
capabilities,
|
||||||
tx.clone(),
|
tx.clone(),
|
||||||
|
preferred_peers.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
update_dandelion_relay(peers.clone(), dandelion_config.clone());
|
update_dandelion_relay(peers.clone(), dandelion_config.clone());
|
||||||
|
@ -93,6 +100,7 @@ fn monitor_peers(
|
||||||
config: p2p::P2PConfig,
|
config: p2p::P2PConfig,
|
||||||
capabilities: p2p::Capabilities,
|
capabilities: p2p::Capabilities,
|
||||||
tx: mpsc::Sender<SocketAddr>,
|
tx: mpsc::Sender<SocketAddr>,
|
||||||
|
preferred_peers_list: Option<Vec<SocketAddr>>,
|
||||||
) {
|
) {
|
||||||
// regularly check if we need to acquire more peers and if so, gets
|
// regularly check if we need to acquire more peers and if so, gets
|
||||||
// them from db
|
// them from db
|
||||||
|
@ -142,15 +150,31 @@ fn monitor_peers(
|
||||||
|
|
||||||
// loop over connected peers
|
// loop over connected peers
|
||||||
// ask them for their list of peers
|
// ask them for their list of peers
|
||||||
|
let mut connected_peers: Vec<SocketAddr> = vec![];
|
||||||
for p in peers.connected_peers() {
|
for p in peers.connected_peers() {
|
||||||
if let Ok(p) = p.try_read() {
|
if let Ok(p) = p.try_read() {
|
||||||
debug!(LOGGER, "monitor_peers: ask {} for more peers", p.info.addr);
|
debug!(LOGGER, "monitor_peers: ask {} for more peers", p.info.addr);
|
||||||
let _ = p.send_peer_request(capabilities);
|
let _ = p.send_peer_request(capabilities);
|
||||||
|
connected_peers.push(p.info.addr)
|
||||||
} else {
|
} else {
|
||||||
warn!(LOGGER, "monitor_peers: failed to get read lock on peer");
|
warn!(LOGGER, "monitor_peers: failed to get read lock on peer");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Attempt to connect to preferred peers if there is some
|
||||||
|
match preferred_peers_list {
|
||||||
|
Some(preferred_peers) => {
|
||||||
|
for mut p in preferred_peers {
|
||||||
|
if !connected_peers.is_empty() {
|
||||||
|
if connected_peers.contains(&p) {
|
||||||
|
tx.send(p).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => debug!(LOGGER, "monitor_peers: no preferred peers"),
|
||||||
|
}
|
||||||
|
|
||||||
// find some peers from our db
|
// find some peers from our db
|
||||||
// and queue them up for a connection attempt
|
// and queue them up for a connection attempt
|
||||||
let new_peers = peers.find_peers(
|
let new_peers = peers.find_peers(
|
||||||
|
@ -183,21 +207,28 @@ fn update_dandelion_relay(peers: Arc<p2p::Peers>, dandelion_config: DandelionCon
|
||||||
|
|
||||||
// Check if we have any pre-existing peer in db. If so, start with those,
|
// Check if we have any pre-existing peer in db. If so, start with those,
|
||||||
// otherwise use the seeds provided.
|
// otherwise use the seeds provided.
|
||||||
fn connect_to_seeds(
|
fn connect_to_seeds_and_preferred_peers(
|
||||||
peers: Arc<p2p::Peers>,
|
peers: Arc<p2p::Peers>,
|
||||||
tx: mpsc::Sender<SocketAddr>,
|
tx: mpsc::Sender<SocketAddr>,
|
||||||
seed_list: Box<Fn() -> Vec<SocketAddr>>,
|
seed_list: Box<Fn() -> Vec<SocketAddr>>,
|
||||||
|
peers_preferred_list: Option<Vec<SocketAddr>>,
|
||||||
) {
|
) {
|
||||||
// check if we have some peers in db
|
// check if we have some peers in db
|
||||||
let peers = peers.find_peers(p2p::State::Healthy, p2p::Capabilities::FULL_HIST, 100);
|
let peers = peers.find_peers(p2p::State::Healthy, p2p::Capabilities::FULL_HIST, 100);
|
||||||
|
|
||||||
// if so, get their addresses, otherwise use our seeds
|
// if so, get their addresses, otherwise use our seeds
|
||||||
let peer_addrs = if peers.len() > 3 {
|
let mut peer_addrs = if peers.len() > 3 {
|
||||||
peers.iter().map(|p| p.addr).collect::<Vec<_>>()
|
peers.iter().map(|p| p.addr).collect::<Vec<_>>()
|
||||||
} else {
|
} else {
|
||||||
seed_list()
|
seed_list()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// If we have preferred peers add them to the connection
|
||||||
|
match peers_preferred_list {
|
||||||
|
Some(mut peers_preferred) => peer_addrs.append(&mut peers_preferred),
|
||||||
|
None => debug!(LOGGER, "No preferred peers"),
|
||||||
|
};
|
||||||
|
|
||||||
if peer_addrs.len() == 0 {
|
if peer_addrs.len() == 0 {
|
||||||
warn!(LOGGER, "No seeds were retrieved.");
|
warn!(LOGGER, "No seeds were retrieved.");
|
||||||
}
|
}
|
||||||
|
@ -274,8 +305,7 @@ pub fn dns_seeds() -> Box<Fn() -> Vec<SocketAddr> + Send> {
|
||||||
pub fn web_seeds() -> Box<Fn() -> Vec<SocketAddr> + Send> {
|
pub fn web_seeds() -> Box<Fn() -> Vec<SocketAddr> + Send> {
|
||||||
Box::new(|| {
|
Box::new(|| {
|
||||||
let text: String = api::client::get(SEEDS_URL).expect("Failed to resolve seeds");
|
let text: String = api::client::get(SEEDS_URL).expect("Failed to resolve seeds");
|
||||||
let addrs = text
|
let addrs = text.split_whitespace()
|
||||||
.split_whitespace()
|
|
||||||
.map(|s| s.parse().unwrap())
|
.map(|s| s.parse().unwrap())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
debug!(LOGGER, "Retrieved seed addresses: {:?}", addrs);
|
debug!(LOGGER, "Retrieved seed addresses: {:?}", addrs);
|
||||||
|
@ -293,3 +323,18 @@ pub fn predefined_seeds(addrs_str: Vec<String>) -> Box<Fn() -> Vec<SocketAddr> +
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convenience function when the seed list is immediately known. Mostly used
|
||||||
|
/// for tests.
|
||||||
|
pub fn preferred_peers(addrs_str: Vec<String>) -> Option<Vec<SocketAddr>> {
|
||||||
|
if addrs_str.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(
|
||||||
|
addrs_str
|
||||||
|
.iter()
|
||||||
|
.map(|s| s.parse().unwrap())
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -23,10 +23,11 @@ use std::{thread, time};
|
||||||
|
|
||||||
use api;
|
use api;
|
||||||
use chain;
|
use chain;
|
||||||
use common::adapters::{ChainToPoolAndNetAdapter, NetToChainAdapter, PoolToChainAdapter,
|
use common::adapters::{
|
||||||
PoolToNetAdapter};
|
ChainToPoolAndNetAdapter, NetToChainAdapter, PoolToChainAdapter, PoolToNetAdapter,
|
||||||
|
};
|
||||||
use common::stats::{DiffBlock, DiffStats, PeerStats, ServerStateInfo, ServerStats};
|
use common::stats::{DiffBlock, DiffStats, PeerStats, ServerStateInfo, ServerStats};
|
||||||
use common::types::{Error, Seeding, ServerConfig, StratumServerConfig, SyncState};
|
use common::types::{Error, ServerConfig, StratumServerConfig, SyncState};
|
||||||
use core::core::hash::Hashed;
|
use core::core::hash::Hashed;
|
||||||
use core::core::target::Difficulty;
|
use core::core::target::Difficulty;
|
||||||
use core::{consensus, genesis, global, pow};
|
use core::{consensus, genesis, global, pow};
|
||||||
|
@ -105,8 +106,16 @@ impl Server {
|
||||||
};
|
};
|
||||||
|
|
||||||
// If archive mode is enabled then the flags should contains the FULL_HIST flag
|
// If archive mode is enabled then the flags should contains the FULL_HIST flag
|
||||||
if archive_mode && !config.capabilities.contains(p2p::Capabilities::FULL_HIST) {
|
if archive_mode
|
||||||
config.capabilities.insert(p2p::Capabilities::FULL_HIST);
|
&& !config
|
||||||
|
.p2p_config
|
||||||
|
.capabilities
|
||||||
|
.contains(p2p::Capabilities::FULL_HIST)
|
||||||
|
{
|
||||||
|
config
|
||||||
|
.p2p_config
|
||||||
|
.capabilities
|
||||||
|
.insert(p2p::Capabilities::FULL_HIST);
|
||||||
}
|
}
|
||||||
|
|
||||||
let stop = Arc::new(AtomicBool::new(false));
|
let stop = Arc::new(AtomicBool::new(false));
|
||||||
|
@ -122,9 +131,9 @@ impl Server {
|
||||||
let sync_state = Arc::new(SyncState::new());
|
let sync_state = Arc::new(SyncState::new());
|
||||||
|
|
||||||
let chain_adapter = Arc::new(ChainToPoolAndNetAdapter::new(
|
let chain_adapter = Arc::new(ChainToPoolAndNetAdapter::new(
|
||||||
sync_state.clone(),
|
sync_state.clone(),
|
||||||
tx_pool.clone(),
|
tx_pool.clone(),
|
||||||
));
|
));
|
||||||
|
|
||||||
let genesis = match config.chain_type {
|
let genesis = match config.chain_type {
|
||||||
global::ChainTypes::Testnet1 => genesis::genesis_testnet1(),
|
global::ChainTypes::Testnet1 => genesis::genesis_testnet1(),
|
||||||
|
@ -165,7 +174,7 @@ impl Server {
|
||||||
|
|
||||||
let p2p_server = Arc::new(p2p::Server::new(
|
let p2p_server = Arc::new(p2p::Server::new(
|
||||||
db_env,
|
db_env,
|
||||||
config.capabilities,
|
config.p2p_config.capabilities,
|
||||||
config.p2p_config.clone(),
|
config.p2p_config.clone(),
|
||||||
net_adapter.clone(),
|
net_adapter.clone(),
|
||||||
genesis.hash(),
|
genesis.hash(),
|
||||||
|
@ -177,25 +186,34 @@ impl Server {
|
||||||
pool_net_adapter.init(Arc::downgrade(&p2p_server.peers));
|
pool_net_adapter.init(Arc::downgrade(&p2p_server.peers));
|
||||||
net_adapter.init(Arc::downgrade(&p2p_server.peers));
|
net_adapter.init(Arc::downgrade(&p2p_server.peers));
|
||||||
|
|
||||||
if config.seeding_type.clone() != Seeding::Programmatic {
|
if config.p2p_config.seeding_type.clone() != p2p::Seeding::Programmatic {
|
||||||
let seeder = match config.seeding_type.clone() {
|
let seeder = match config.p2p_config.seeding_type.clone() {
|
||||||
Seeding::None => {
|
p2p::Seeding::None => {
|
||||||
warn!(
|
warn!(
|
||||||
LOGGER,
|
LOGGER,
|
||||||
"No seed configured, will stay solo until connected to"
|
"No seed configured, will stay solo until connected to"
|
||||||
);
|
);
|
||||||
seed::predefined_seeds(vec![])
|
seed::predefined_seeds(vec![])
|
||||||
}
|
}
|
||||||
Seeding::List => seed::predefined_seeds(config.seeds.as_mut().unwrap().clone()),
|
p2p::Seeding::List => {
|
||||||
Seeding::DNSSeed => seed::dns_seeds(),
|
seed::predefined_seeds(config.p2p_config.seeds.as_mut().unwrap().clone())
|
||||||
Seeding::WebStatic => seed::web_seeds(),
|
}
|
||||||
|
p2p::Seeding::DNSSeed => seed::dns_seeds(),
|
||||||
|
p2p::Seeding::WebStatic => seed::web_seeds(),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let peers_preferred = match config.p2p_config.peers_preferred.clone() {
|
||||||
|
Some(peers_preferred) => seed::preferred_peers(peers_preferred),
|
||||||
|
None => None,
|
||||||
|
};
|
||||||
|
|
||||||
seed::connect_and_monitor(
|
seed::connect_and_monitor(
|
||||||
p2p_server.clone(),
|
p2p_server.clone(),
|
||||||
config.capabilities,
|
config.p2p_config.capabilities,
|
||||||
config.dandelion_config.clone(),
|
config.dandelion_config.clone(),
|
||||||
seeder,
|
seeder,
|
||||||
|
peers_preferred,
|
||||||
stop.clone(),
|
stop.clone(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -266,7 +284,7 @@ impl Server {
|
||||||
|
|
||||||
/// Ping all peers, mostly useful for tests to have connected peers share
|
/// Ping all peers, mostly useful for tests to have connected peers share
|
||||||
/// their heights
|
/// their heights
|
||||||
pub fn ping_peers(&self)-> Result<(), Error> {
|
pub fn ping_peers(&self) -> Result<(), Error> {
|
||||||
let head = self.chain.head()?;
|
let head = self.chain.head()?;
|
||||||
self.p2p.peers.check_all(head.total_difficulty, head.height);
|
self.p2p.peers.check_all(head.total_difficulty, head.height);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -292,12 +310,7 @@ impl Server {
|
||||||
let _ = thread::Builder::new()
|
let _ = thread::Builder::new()
|
||||||
.name("stratum_server".to_string())
|
.name("stratum_server".to_string())
|
||||||
.spawn(move || {
|
.spawn(move || {
|
||||||
stratum_server.run_loop(
|
stratum_server.run_loop(stratum_stats, cuckoo_size as u32, proof_size, sync_state);
|
||||||
stratum_stats,
|
|
||||||
cuckoo_size as u32,
|
|
||||||
proof_size,
|
|
||||||
sync_state,
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -469,17 +469,23 @@ impl SyncInfo {
|
||||||
let (timeout, latest_height, prev_height) = self.prev_header_sync;
|
let (timeout, latest_height, prev_height) = self.prev_header_sync;
|
||||||
|
|
||||||
// received all necessary headers, can ask for more
|
// received all necessary headers, can ask for more
|
||||||
let all_headers_received = header_head.height >= prev_height + (p2p::MAX_BLOCK_HEADERS as u64) - 4;
|
let all_headers_received =
|
||||||
|
header_head.height >= prev_height + (p2p::MAX_BLOCK_HEADERS as u64) - 4;
|
||||||
// no headers processed and we're past timeout, need to ask for more
|
// no headers processed and we're past timeout, need to ask for more
|
||||||
let stalling = header_head.height == latest_height && now > timeout;
|
let stalling = header_head.height == latest_height && now > timeout;
|
||||||
|
|
||||||
if all_headers_received || stalling {
|
if all_headers_received || stalling {
|
||||||
self.prev_header_sync = (now + Duration::seconds(10), header_head.height, header_head.height);
|
self.prev_header_sync = (
|
||||||
|
now + Duration::seconds(10),
|
||||||
|
header_head.height,
|
||||||
|
header_head.height,
|
||||||
|
);
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
// resetting the timeout as long as we progress
|
// resetting the timeout as long as we progress
|
||||||
if header_head.height > latest_height {
|
if header_head.height > latest_height {
|
||||||
self.prev_header_sync = (now + Duration::seconds(2), header_head.height, prev_height);
|
self.prev_header_sync =
|
||||||
|
(now + Duration::seconds(2), header_head.height, prev_height);
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,6 @@ mod mining;
|
||||||
mod webwallet;
|
mod webwallet;
|
||||||
|
|
||||||
pub use common::stats::{DiffBlock, PeerStats, ServerStats, StratumStats, WorkerStats};
|
pub use common::stats::{DiffBlock, PeerStats, ServerStats, StratumStats, WorkerStats};
|
||||||
pub use common::types::{Seeding, ServerConfig, StratumServerConfig};
|
pub use common::types::{ServerConfig, StratumServerConfig};
|
||||||
pub use grin::server::Server;
|
pub use grin::server::Server;
|
||||||
pub use webwallet::server::start_webwallet_server;
|
pub use webwallet::server::start_webwallet_server;
|
||||||
|
|
|
@ -179,11 +179,11 @@ impl LocalServerContainer {
|
||||||
pub fn run_server(&mut self, duration_in_seconds: u64) -> servers::Server {
|
pub fn run_server(&mut self, duration_in_seconds: u64) -> servers::Server {
|
||||||
let api_addr = format!("{}:{}", self.config.base_addr, self.config.api_server_port);
|
let api_addr = format!("{}:{}", self.config.base_addr, self.config.api_server_port);
|
||||||
|
|
||||||
let mut seeding_type = servers::Seeding::None;
|
let mut seeding_type = p2p::Seeding::None;
|
||||||
let mut seeds = Vec::new();
|
let mut seeds = Vec::new();
|
||||||
|
|
||||||
if self.config.seed_addr.len() > 0 {
|
if self.config.seed_addr.len() > 0 {
|
||||||
seeding_type = servers::Seeding::List;
|
seeding_type = p2p::Seeding::List;
|
||||||
seeds = vec![self.config.seed_addr.to_string()];
|
seeds = vec![self.config.seed_addr.to_string()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,10 +192,10 @@ impl LocalServerContainer {
|
||||||
db_root: format!("{}/.grin", self.working_dir),
|
db_root: format!("{}/.grin", self.working_dir),
|
||||||
p2p_config: p2p::P2PConfig {
|
p2p_config: p2p::P2PConfig {
|
||||||
port: self.config.p2p_server_port,
|
port: self.config.p2p_server_port,
|
||||||
|
seeds: Some(seeds),
|
||||||
|
seeding_type: seeding_type,
|
||||||
..p2p::P2PConfig::default()
|
..p2p::P2PConfig::default()
|
||||||
},
|
},
|
||||||
seeds: Some(seeds),
|
|
||||||
seeding_type: seeding_type,
|
|
||||||
chain_type: core::global::ChainTypes::AutomatedTesting,
|
chain_type: core::global::ChainTypes::AutomatedTesting,
|
||||||
skip_sync_wait: Some(true),
|
skip_sync_wait: Some(true),
|
||||||
stratum_mining_config: None,
|
stratum_mining_config: None,
|
||||||
|
@ -585,10 +585,10 @@ pub fn config(n: u16, test_name_dir: &str, seed_n: u16) -> servers::ServerConfig
|
||||||
db_root: format!("target/tmp/{}/grin-sync-{}", test_name_dir, n),
|
db_root: format!("target/tmp/{}/grin-sync-{}", test_name_dir, n),
|
||||||
p2p_config: p2p::P2PConfig {
|
p2p_config: p2p::P2PConfig {
|
||||||
port: 10000 + n,
|
port: 10000 + n,
|
||||||
|
seeding_type: p2p::Seeding::List,
|
||||||
|
seeds: Some(vec![format!("127.0.0.1:{}", 10000 + seed_n)]),
|
||||||
..p2p::P2PConfig::default()
|
..p2p::P2PConfig::default()
|
||||||
},
|
},
|
||||||
seeding_type: servers::Seeding::List,
|
|
||||||
seeds: Some(vec![format!("127.0.0.1:{}", 10000 + seed_n)]),
|
|
||||||
chain_type: core::global::ChainTypes::AutomatedTesting,
|
chain_type: core::global::ChainTypes::AutomatedTesting,
|
||||||
archive_mode: Some(true),
|
archive_mode: Some(true),
|
||||||
skip_sync_wait: Some(true),
|
skip_sync_wait: Some(true),
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
/// Grin server commands processing
|
/// Grin server commands processing
|
||||||
|
|
||||||
use std::env::current_dir;
|
use std::env::current_dir;
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
@ -21,14 +20,15 @@ use std::sync::Arc;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use ctrlc;
|
|
||||||
use clap::ArgMatches;
|
use clap::ArgMatches;
|
||||||
|
use ctrlc;
|
||||||
use daemonize::Daemonize;
|
use daemonize::Daemonize;
|
||||||
|
|
||||||
use cmd::wallet;
|
use cmd::wallet;
|
||||||
use config::GlobalConfig;
|
use config::GlobalConfig;
|
||||||
use core::global;
|
use core::global;
|
||||||
use grin_wallet::controller;
|
use grin_wallet::controller;
|
||||||
|
use p2p::Seeding;
|
||||||
use servers;
|
use servers;
|
||||||
use tui::ui;
|
use tui::ui;
|
||||||
use util::LOGGER;
|
use util::LOGGER;
|
||||||
|
@ -118,8 +118,8 @@ pub fn server_command(server_args: Option<&ArgMatches>, mut global_config: Globa
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(seeds) = a.values_of("seed") {
|
if let Some(seeds) = a.values_of("seed") {
|
||||||
server_config.seeding_type = servers::Seeding::List;
|
server_config.p2p_config.seeding_type = Seeding::List;
|
||||||
server_config.seeds = Some(seeds.map(|s| s.to_string()).collect());
|
server_config.p2p_config.seeds = Some(seeds.map(|s| s.to_string()).collect());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,4 +192,3 @@ pub fn server_command(server_args: Option<&ArgMatches>, mut global_config: Globa
|
||||||
start_server(server_config);
|
start_server(server_config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue