light: integrate with sync + serve_light CLI
This commit is contained in:
parent
efd66f566d
commit
6f5f1f5e26
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -18,6 +18,7 @@ dependencies = [
|
|||||||
"ethcore-ipc-hypervisor 1.2.0",
|
"ethcore-ipc-hypervisor 1.2.0",
|
||||||
"ethcore-ipc-nano 1.4.0",
|
"ethcore-ipc-nano 1.4.0",
|
||||||
"ethcore-ipc-tests 0.1.0",
|
"ethcore-ipc-tests 0.1.0",
|
||||||
|
"ethcore-light 1.5.0",
|
||||||
"ethcore-logger 1.5.0",
|
"ethcore-logger 1.5.0",
|
||||||
"ethcore-rpc 1.5.0",
|
"ethcore-rpc 1.5.0",
|
||||||
"ethcore-signer 1.5.0",
|
"ethcore-signer 1.5.0",
|
||||||
|
@ -47,6 +47,7 @@ rlp = { path = "util/rlp" }
|
|||||||
ethcore-stratum = { path = "stratum" }
|
ethcore-stratum = { path = "stratum" }
|
||||||
ethcore-dapps = { path = "dapps", optional = true }
|
ethcore-dapps = { path = "dapps", optional = true }
|
||||||
clippy = { version = "0.0.103", optional = true}
|
clippy = { version = "0.0.103", optional = true}
|
||||||
|
ethcore-light = { path = "ethcore/light" }
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies]
|
[target.'cfg(windows)'.dependencies]
|
||||||
winapi = "0.2"
|
winapi = "0.2"
|
||||||
|
@ -20,6 +20,7 @@ extern crate ethcore_ipc_codegen;
|
|||||||
#[cfg(feature = "ipc")]
|
#[cfg(feature = "ipc")]
|
||||||
fn main() {
|
fn main() {
|
||||||
ethcore_ipc_codegen::derive_binary("src/types/mod.rs.in").unwrap();
|
ethcore_ipc_codegen::derive_binary("src/types/mod.rs.in").unwrap();
|
||||||
|
ethcore_ipc_codegen::derive_ipc_cond("src/provider.rs", true).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "ipc"))]
|
#[cfg(not(feature = "ipc"))]
|
||||||
|
@ -33,8 +33,21 @@
|
|||||||
|
|
||||||
pub mod client;
|
pub mod client;
|
||||||
pub mod net;
|
pub mod net;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "ipc"))]
|
||||||
pub mod provider;
|
pub mod provider;
|
||||||
|
|
||||||
|
#[cfg(feature = "ipc")]
|
||||||
|
pub mod provider {
|
||||||
|
#![allow(dead_code, unused_assignments, unused_variables, missing_docs)] // codegen issues
|
||||||
|
include!(concat!(env!("OUT_DIR"), "/provider.rs"));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "ipc")]
|
||||||
|
pub mod remote {
|
||||||
|
pub use provider::LightProviderClient;
|
||||||
|
}
|
||||||
|
|
||||||
mod types;
|
mod types;
|
||||||
|
|
||||||
pub use self::provider::Provider;
|
pub use self::provider::Provider;
|
||||||
|
@ -22,6 +22,9 @@
|
|||||||
//!
|
//!
|
||||||
//! This module provides an interface for configuration of buffer
|
//! This module provides an interface for configuration of buffer
|
||||||
//! flow costs and recharge rates.
|
//! flow costs and recharge rates.
|
||||||
|
//!
|
||||||
|
//! Current default costs are picked completely arbitrarily, not based
|
||||||
|
//! on any empirical timings or mathematical models.
|
||||||
|
|
||||||
use request;
|
use request;
|
||||||
use super::packet;
|
use super::packet;
|
||||||
@ -273,6 +276,16 @@ impl FlowParams {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for FlowParams {
|
||||||
|
fn default() -> Self {
|
||||||
|
FlowParams {
|
||||||
|
limit: 50_000_000.into(),
|
||||||
|
costs: CostTable::default(),
|
||||||
|
recharge: 100_000.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -30,13 +30,14 @@ use util::{Bytes, Mutex, RwLock, U256};
|
|||||||
use time::SteadyTime;
|
use time::SteadyTime;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::sync::Arc;
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
|
|
||||||
use provider::Provider;
|
use provider::Provider;
|
||||||
use request::{self, Request};
|
use request::{self, Request};
|
||||||
|
|
||||||
use self::buffer_flow::{Buffer, FlowParams};
|
use self::buffer_flow::{Buffer, FlowParams};
|
||||||
use self::context::{IoContext, EventContext, Ctx};
|
use self::context::Ctx;
|
||||||
use self::error::{Error, Punishment};
|
use self::error::{Error, Punishment};
|
||||||
|
|
||||||
mod buffer_flow;
|
mod buffer_flow;
|
||||||
@ -47,16 +48,20 @@ mod status;
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
|
||||||
pub use self::status::{Status, Capabilities, Announcement, NetworkId};
|
pub use self::context::{EventContext, IoContext};
|
||||||
|
pub use self::status::{Status, Capabilities, Announcement};
|
||||||
|
|
||||||
const TIMEOUT: TimerToken = 0;
|
const TIMEOUT: TimerToken = 0;
|
||||||
const TIMEOUT_INTERVAL_MS: u64 = 1000;
|
const TIMEOUT_INTERVAL_MS: u64 = 1000;
|
||||||
|
|
||||||
// LPV1
|
// Supported protocol versions.
|
||||||
const PROTOCOL_VERSION: u32 = 1;
|
pub const PROTOCOL_VERSIONS: &'static [u8] = &[1];
|
||||||
|
|
||||||
// TODO [rob] make configurable.
|
// Max protocol version.
|
||||||
const PROTOCOL_ID: [u8; 3] = *b"les";
|
pub const MAX_PROTOCOL_VERSION: u8 = 1;
|
||||||
|
|
||||||
|
// Packet count for LES.
|
||||||
|
pub const PACKET_COUNT: u8 = 15;
|
||||||
|
|
||||||
// packet ID definitions.
|
// packet ID definitions.
|
||||||
mod packet {
|
mod packet {
|
||||||
@ -173,6 +178,8 @@ pub trait Handler: Send + Sync {
|
|||||||
/// Called when a peer responds with header proofs. Each proof is a block header coupled
|
/// Called when a peer responds with header proofs. Each proof is a block header coupled
|
||||||
/// with a series of trie nodes is ascending order by distance from the root.
|
/// with a series of trie nodes is ascending order by distance from the root.
|
||||||
fn on_header_proofs(&self, _ctx: &EventContext, _req_id: ReqId, _proofs: &[(Bytes, Vec<Bytes>)]) { }
|
fn on_header_proofs(&self, _ctx: &EventContext, _req_id: ReqId, _proofs: &[(Bytes, Vec<Bytes>)]) { }
|
||||||
|
/// Called on abort.
|
||||||
|
fn on_abort(&self) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
// a request, the peer who it was made to, and the time it was made.
|
// a request, the peer who it was made to, and the time it was made.
|
||||||
@ -185,7 +192,7 @@ struct Requested {
|
|||||||
/// Protocol parameters.
|
/// Protocol parameters.
|
||||||
pub struct Params {
|
pub struct Params {
|
||||||
/// Network id.
|
/// Network id.
|
||||||
pub network_id: NetworkId,
|
pub network_id: u64,
|
||||||
/// Buffer flow parameters.
|
/// Buffer flow parameters.
|
||||||
pub flow_params: FlowParams,
|
pub flow_params: FlowParams,
|
||||||
/// Initial capabilities.
|
/// Initial capabilities.
|
||||||
@ -203,9 +210,9 @@ pub struct Params {
|
|||||||
// Locks must be acquired in the order declared, and when holding a read lock
|
// Locks must be acquired in the order declared, and when holding a read lock
|
||||||
// on the peers, only one peer may be held at a time.
|
// on the peers, only one peer may be held at a time.
|
||||||
pub struct LightProtocol {
|
pub struct LightProtocol {
|
||||||
provider: Box<Provider>,
|
provider: Arc<Provider>,
|
||||||
genesis_hash: H256,
|
genesis_hash: H256,
|
||||||
network_id: NetworkId,
|
network_id: u64,
|
||||||
pending_peers: RwLock<HashMap<PeerId, PendingPeer>>,
|
pending_peers: RwLock<HashMap<PeerId, PendingPeer>>,
|
||||||
peers: RwLock<HashMap<PeerId, Mutex<Peer>>>,
|
peers: RwLock<HashMap<PeerId, Mutex<Peer>>>,
|
||||||
pending_requests: RwLock<HashMap<usize, Requested>>,
|
pending_requests: RwLock<HashMap<usize, Requested>>,
|
||||||
@ -217,7 +224,7 @@ pub struct LightProtocol {
|
|||||||
|
|
||||||
impl LightProtocol {
|
impl LightProtocol {
|
||||||
/// Create a new instance of the protocol manager.
|
/// Create a new instance of the protocol manager.
|
||||||
pub fn new(provider: Box<Provider>, params: Params) -> Self {
|
pub fn new(provider: Arc<Provider>, params: Params) -> Self {
|
||||||
let genesis_hash = provider.chain_info().genesis_hash;
|
let genesis_hash = provider.chain_info().genesis_hash;
|
||||||
LightProtocol {
|
LightProtocol {
|
||||||
provider: provider,
|
provider: provider,
|
||||||
@ -323,6 +330,23 @@ impl LightProtocol {
|
|||||||
self.handlers.push(handler);
|
self.handlers.push(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Signal to handlers that network activity is being aborted
|
||||||
|
/// and clear peer data.
|
||||||
|
pub fn abort(&self) {
|
||||||
|
for handler in &self.handlers {
|
||||||
|
handler.on_abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
// acquire in order and hold.
|
||||||
|
let mut pending_peers = self.pending_peers.write();
|
||||||
|
let mut peers = self.peers.write();
|
||||||
|
let mut pending_requests = self.pending_requests.write();
|
||||||
|
|
||||||
|
pending_peers.clear();
|
||||||
|
peers.clear();
|
||||||
|
pending_requests.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// Does the common pre-verification of responses before the response itself
|
// Does the common pre-verification of responses before the response itself
|
||||||
// is actually decoded:
|
// is actually decoded:
|
||||||
// - check whether peer exists
|
// - check whether peer exists
|
||||||
@ -460,7 +484,7 @@ impl LightProtocol {
|
|||||||
head_hash: chain_info.best_block_hash,
|
head_hash: chain_info.best_block_hash,
|
||||||
head_num: chain_info.best_block_number,
|
head_num: chain_info.best_block_number,
|
||||||
genesis_hash: chain_info.genesis_hash,
|
genesis_hash: chain_info.genesis_hash,
|
||||||
protocol_version: PROTOCOL_VERSION,
|
protocol_version: MAX_PROTOCOL_VERSION as u32,
|
||||||
network_id: self.network_id,
|
network_id: self.network_id,
|
||||||
last_head: None,
|
last_head: None,
|
||||||
};
|
};
|
||||||
|
@ -82,26 +82,6 @@ impl Key {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Network ID structure.
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
||||||
#[repr(u32)]
|
|
||||||
pub enum NetworkId {
|
|
||||||
/// ID for the mainnet
|
|
||||||
Mainnet = 1,
|
|
||||||
/// ID for the testnet
|
|
||||||
Testnet = 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl NetworkId {
|
|
||||||
fn from_raw(raw: u32) -> Option<Self> {
|
|
||||||
match raw {
|
|
||||||
0 => Some(NetworkId::Testnet),
|
|
||||||
1 => Some(NetworkId::Mainnet),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// helper for decoding key-value pairs in the handshake or an announcement.
|
// helper for decoding key-value pairs in the handshake or an announcement.
|
||||||
struct Parser<'a> {
|
struct Parser<'a> {
|
||||||
pos: usize,
|
pos: usize,
|
||||||
@ -164,7 +144,7 @@ pub struct Status {
|
|||||||
/// Protocol version.
|
/// Protocol version.
|
||||||
pub protocol_version: u32,
|
pub protocol_version: u32,
|
||||||
/// Network id of this peer.
|
/// Network id of this peer.
|
||||||
pub network_id: NetworkId,
|
pub network_id: u64,
|
||||||
/// Total difficulty of the head of the chain.
|
/// Total difficulty of the head of the chain.
|
||||||
pub head_td: U256,
|
pub head_td: U256,
|
||||||
/// Hash of the best block.
|
/// Hash of the best block.
|
||||||
@ -225,8 +205,7 @@ pub fn parse_handshake(rlp: UntrustedRlp) -> Result<(Status, Capabilities, FlowP
|
|||||||
|
|
||||||
let status = Status {
|
let status = Status {
|
||||||
protocol_version: try!(parser.expect(Key::ProtocolVersion)),
|
protocol_version: try!(parser.expect(Key::ProtocolVersion)),
|
||||||
network_id: try!(parser.expect(Key::NetworkId)
|
network_id: try!(parser.expect(Key::NetworkId)),
|
||||||
.and_then(|id: u32| NetworkId::from_raw(id).ok_or(DecoderError::Custom("Invalid network ID")))),
|
|
||||||
head_td: try!(parser.expect(Key::HeadTD)),
|
head_td: try!(parser.expect(Key::HeadTD)),
|
||||||
head_hash: try!(parser.expect(Key::HeadHash)),
|
head_hash: try!(parser.expect(Key::HeadHash)),
|
||||||
head_num: try!(parser.expect(Key::HeadNum)),
|
head_num: try!(parser.expect(Key::HeadNum)),
|
||||||
@ -254,7 +233,7 @@ pub fn parse_handshake(rlp: UntrustedRlp) -> Result<(Status, Capabilities, FlowP
|
|||||||
pub fn write_handshake(status: &Status, capabilities: &Capabilities, flow_params: &FlowParams) -> Vec<u8> {
|
pub fn write_handshake(status: &Status, capabilities: &Capabilities, flow_params: &FlowParams) -> Vec<u8> {
|
||||||
let mut pairs = Vec::new();
|
let mut pairs = Vec::new();
|
||||||
pairs.push(encode_pair(Key::ProtocolVersion, &status.protocol_version));
|
pairs.push(encode_pair(Key::ProtocolVersion, &status.protocol_version));
|
||||||
pairs.push(encode_pair(Key::NetworkId, &(status.network_id as u32)));
|
pairs.push(encode_pair(Key::NetworkId, &(status.network_id as u64)));
|
||||||
pairs.push(encode_pair(Key::HeadTD, &status.head_td));
|
pairs.push(encode_pair(Key::HeadTD, &status.head_td));
|
||||||
pairs.push(encode_pair(Key::HeadHash, &status.head_hash));
|
pairs.push(encode_pair(Key::HeadHash, &status.head_hash));
|
||||||
pairs.push(encode_pair(Key::HeadNum, &status.head_num));
|
pairs.push(encode_pair(Key::HeadNum, &status.head_num));
|
||||||
@ -385,7 +364,7 @@ mod tests {
|
|||||||
fn full_handshake() {
|
fn full_handshake() {
|
||||||
let status = Status {
|
let status = Status {
|
||||||
protocol_version: 1,
|
protocol_version: 1,
|
||||||
network_id: NetworkId::Mainnet,
|
network_id: 1,
|
||||||
head_td: U256::default(),
|
head_td: U256::default(),
|
||||||
head_hash: H256::default(),
|
head_hash: H256::default(),
|
||||||
head_num: 10,
|
head_num: 10,
|
||||||
@ -420,7 +399,7 @@ mod tests {
|
|||||||
fn partial_handshake() {
|
fn partial_handshake() {
|
||||||
let status = Status {
|
let status = Status {
|
||||||
protocol_version: 1,
|
protocol_version: 1,
|
||||||
network_id: NetworkId::Mainnet,
|
network_id: 1,
|
||||||
head_td: U256::default(),
|
head_td: U256::default(),
|
||||||
head_hash: H256::default(),
|
head_hash: H256::default(),
|
||||||
head_num: 10,
|
head_num: 10,
|
||||||
@ -455,7 +434,7 @@ mod tests {
|
|||||||
fn skip_unknown_keys() {
|
fn skip_unknown_keys() {
|
||||||
let status = Status {
|
let status = Status {
|
||||||
protocol_version: 1,
|
protocol_version: 1,
|
||||||
network_id: NetworkId::Mainnet,
|
network_id: 1,
|
||||||
head_td: U256::default(),
|
head_td: U256::default(),
|
||||||
head_hash: H256::default(),
|
head_hash: H256::default(),
|
||||||
head_num: 10,
|
head_num: 10,
|
||||||
|
@ -25,7 +25,7 @@ use network::PeerId;
|
|||||||
|
|
||||||
use net::buffer_flow::FlowParams;
|
use net::buffer_flow::FlowParams;
|
||||||
use net::context::IoContext;
|
use net::context::IoContext;
|
||||||
use net::status::{Capabilities, Status, NetworkId, write_handshake};
|
use net::status::{Capabilities, Status, write_handshake};
|
||||||
use net::{encode_request, LightProtocol, Params, packet};
|
use net::{encode_request, LightProtocol, Params, packet};
|
||||||
use provider::Provider;
|
use provider::Provider;
|
||||||
use request::{self, Request, Headers};
|
use request::{self, Request, Headers};
|
||||||
@ -174,8 +174,8 @@ fn setup(flow_params: FlowParams, capabilities: Capabilities) -> (Arc<TestProvid
|
|||||||
client: TestBlockChainClient::new(),
|
client: TestBlockChainClient::new(),
|
||||||
});
|
});
|
||||||
|
|
||||||
let proto = LightProtocol::new(Box::new(TestProvider(provider.clone())), Params {
|
let proto = LightProtocol::new(Arc::new(TestProvider(provider.clone())), Params {
|
||||||
network_id: NetworkId::Testnet,
|
network_id: 2,
|
||||||
flow_params: flow_params,
|
flow_params: flow_params,
|
||||||
capabilities: capabilities,
|
capabilities: capabilities,
|
||||||
});
|
});
|
||||||
@ -185,8 +185,8 @@ fn setup(flow_params: FlowParams, capabilities: Capabilities) -> (Arc<TestProvid
|
|||||||
|
|
||||||
fn status(chain_info: BlockChainInfo) -> Status {
|
fn status(chain_info: BlockChainInfo) -> Status {
|
||||||
Status {
|
Status {
|
||||||
protocol_version: ::net::PROTOCOL_VERSION,
|
protocol_version: 1,
|
||||||
network_id: NetworkId::Testnet,
|
network_id: 2,
|
||||||
head_td: chain_info.total_difficulty,
|
head_td: chain_info.total_difficulty,
|
||||||
head_hash: chain_info.best_block_hash,
|
head_hash: chain_info.best_block_hash,
|
||||||
head_num: chain_info.best_block_number,
|
head_num: chain_info.best_block_number,
|
||||||
|
@ -33,6 +33,7 @@ use request;
|
|||||||
/// or empty vector where appropriate.
|
/// or empty vector where appropriate.
|
||||||
///
|
///
|
||||||
/// [1]: https://github.com/ethcore/parity/wiki/Light-Ethereum-Subprotocol-(LES)
|
/// [1]: https://github.com/ethcore/parity/wiki/Light-Ethereum-Subprotocol-(LES)
|
||||||
|
#[cfg_attr(feature = "ipc", ipc(client_ident="LightProviderClient"))]
|
||||||
pub trait Provider: Send + Sync {
|
pub trait Provider: Send + Sync {
|
||||||
/// Provide current blockchain info.
|
/// Provide current blockchain info.
|
||||||
fn chain_info(&self) -> BlockChainInfo;
|
fn chain_info(&self) -> BlockChainInfo;
|
||||||
|
@ -32,6 +32,7 @@ warp = true
|
|||||||
allow_ips = "all"
|
allow_ips = "all"
|
||||||
snapshot_peers = 0
|
snapshot_peers = 0
|
||||||
max_pending_peers = 64
|
max_pending_peers = 64
|
||||||
|
serve_light = true
|
||||||
|
|
||||||
reserved_only = false
|
reserved_only = false
|
||||||
reserved_peers = "./path_to_file"
|
reserved_peers = "./path_to_file"
|
||||||
|
@ -135,6 +135,8 @@ usage! {
|
|||||||
flag_reserved_only: bool = false,
|
flag_reserved_only: bool = false,
|
||||||
or |c: &Config| otry!(c.network).reserved_only.clone(),
|
or |c: &Config| otry!(c.network).reserved_only.clone(),
|
||||||
flag_no_ancient_blocks: bool = false, or |_| None,
|
flag_no_ancient_blocks: bool = false, or |_| None,
|
||||||
|
flag_serve_light: bool = false,
|
||||||
|
or |c: &Config| otry!(c.network).serve_light.clone(),
|
||||||
|
|
||||||
// -- API and Console Options
|
// -- API and Console Options
|
||||||
// RPC
|
// RPC
|
||||||
@ -334,6 +336,7 @@ struct Network {
|
|||||||
node_key: Option<String>,
|
node_key: Option<String>,
|
||||||
reserved_peers: Option<String>,
|
reserved_peers: Option<String>,
|
||||||
reserved_only: Option<bool>,
|
reserved_only: Option<bool>,
|
||||||
|
serve_light: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, PartialEq, RustcDecodable)]
|
#[derive(Default, Debug, PartialEq, RustcDecodable)]
|
||||||
@ -543,6 +546,7 @@ mod tests {
|
|||||||
flag_reserved_peers: Some("./path_to_file".into()),
|
flag_reserved_peers: Some("./path_to_file".into()),
|
||||||
flag_reserved_only: false,
|
flag_reserved_only: false,
|
||||||
flag_no_ancient_blocks: false,
|
flag_no_ancient_blocks: false,
|
||||||
|
flag_serve_light: true,
|
||||||
|
|
||||||
// -- API and Console Options
|
// -- API and Console Options
|
||||||
// RPC
|
// RPC
|
||||||
@ -713,6 +717,7 @@ mod tests {
|
|||||||
node_key: None,
|
node_key: None,
|
||||||
reserved_peers: Some("./path/to/reserved_peers".into()),
|
reserved_peers: Some("./path/to/reserved_peers".into()),
|
||||||
reserved_only: Some(true),
|
reserved_only: Some(true),
|
||||||
|
serve_light: None,
|
||||||
}),
|
}),
|
||||||
rpc: Some(Rpc {
|
rpc: Some(Rpc {
|
||||||
disable: Some(true),
|
disable: Some(true),
|
||||||
|
@ -97,6 +97,7 @@ Networking Options:
|
|||||||
--max-pending-peers NUM Allow up to NUM pending connections. (default: {flag_max_pending_peers})
|
--max-pending-peers NUM Allow up to NUM pending connections. (default: {flag_max_pending_peers})
|
||||||
--no-ancient-blocks Disable downloading old blocks after snapshot restoration
|
--no-ancient-blocks Disable downloading old blocks after snapshot restoration
|
||||||
or warp sync. (default: {flag_no_ancient_blocks})
|
or warp sync. (default: {flag_no_ancient_blocks})
|
||||||
|
--serve-light Experimental: Serve light client peers. (default: {flag_serve_light})
|
||||||
|
|
||||||
API and Console Options:
|
API and Console Options:
|
||||||
--no-jsonrpc Disable the JSON-RPC API server. (default: {flag_no_jsonrpc})
|
--no-jsonrpc Disable the JSON-RPC API server. (default: {flag_no_jsonrpc})
|
||||||
|
@ -275,6 +275,7 @@ impl Configuration {
|
|||||||
no_periodic_snapshot: self.args.flag_no_periodic_snapshot,
|
no_periodic_snapshot: self.args.flag_no_periodic_snapshot,
|
||||||
check_seal: !self.args.flag_no_seal_check,
|
check_seal: !self.args.flag_no_seal_check,
|
||||||
download_old_blocks: !self.args.flag_no_ancient_blocks,
|
download_old_blocks: !self.args.flag_no_ancient_blocks,
|
||||||
|
serve_light: self.args.flag_serve_light,
|
||||||
};
|
};
|
||||||
Cmd::Run(run_cmd)
|
Cmd::Run(run_cmd)
|
||||||
};
|
};
|
||||||
@ -921,6 +922,7 @@ mod tests {
|
|||||||
no_periodic_snapshot: false,
|
no_periodic_snapshot: false,
|
||||||
check_seal: true,
|
check_seal: true,
|
||||||
download_old_blocks: true,
|
download_old_blocks: true,
|
||||||
|
serve_light: false,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ extern crate serde;
|
|||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
extern crate rlp;
|
extern crate rlp;
|
||||||
extern crate ethcore_hash_fetch as hash_fetch;
|
extern crate ethcore_hash_fetch as hash_fetch;
|
||||||
|
extern crate ethcore_light as light;
|
||||||
|
|
||||||
extern crate ethcore_ipc_hypervisor as hypervisor;
|
extern crate ethcore_ipc_hypervisor as hypervisor;
|
||||||
extern crate ethcore_rpc;
|
extern crate ethcore_rpc;
|
||||||
|
@ -15,16 +15,22 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
use ethcore::client::BlockChainClient;
|
use ethcore::client::BlockChainClient;
|
||||||
use hypervisor::Hypervisor;
|
use hypervisor::Hypervisor;
|
||||||
use ethsync::{SyncConfig, NetworkConfiguration, NetworkError};
|
use ethsync::{SyncConfig, NetworkConfiguration, NetworkError, Params};
|
||||||
use ethcore::snapshot::SnapshotService;
|
use ethcore::snapshot::SnapshotService;
|
||||||
|
use light::Provider;
|
||||||
|
|
||||||
#[cfg(not(feature="ipc"))]
|
#[cfg(not(feature="ipc"))]
|
||||||
use self::no_ipc_deps::*;
|
use self::no_ipc_deps::*;
|
||||||
|
|
||||||
|
#[cfg(not(feature="ipc"))]
|
||||||
|
use ethcore_logger::Config as LogConfig;
|
||||||
|
|
||||||
#[cfg(feature="ipc")]
|
#[cfg(feature="ipc")]
|
||||||
use self::ipc_deps::*;
|
use self::ipc_deps::*;
|
||||||
use ethcore_logger::Config as LogConfig;
|
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
#[cfg(feature="ipc")]
|
#[cfg(feature="ipc")]
|
||||||
pub mod service_urls {
|
pub mod service_urls {
|
||||||
@ -36,6 +42,8 @@ pub mod service_urls {
|
|||||||
pub const SYNC_NOTIFY: &'static str = "parity-sync-notify.ipc";
|
pub const SYNC_NOTIFY: &'static str = "parity-sync-notify.ipc";
|
||||||
pub const NETWORK_MANAGER: &'static str = "parity-manage-net.ipc";
|
pub const NETWORK_MANAGER: &'static str = "parity-manage-net.ipc";
|
||||||
pub const SYNC_CONTROL: &'static str = "parity-sync-control.ipc";
|
pub const SYNC_CONTROL: &'static str = "parity-sync-control.ipc";
|
||||||
|
pub const LIGHT_PROVIDER: &'static str = "parity-light-provider.ipc";
|
||||||
|
|
||||||
#[cfg(feature="stratum")]
|
#[cfg(feature="stratum")]
|
||||||
pub const STRATUM: &'static str = "parity-stratum.ipc";
|
pub const STRATUM: &'static str = "parity-stratum.ipc";
|
||||||
#[cfg(feature="stratum")]
|
#[cfg(feature="stratum")]
|
||||||
@ -75,6 +83,7 @@ mod ipc_deps {
|
|||||||
pub use nanoipc::{GuardedSocket, NanoSocket, generic_client, fast_client};
|
pub use nanoipc::{GuardedSocket, NanoSocket, generic_client, fast_client};
|
||||||
pub use ipc::IpcSocket;
|
pub use ipc::IpcSocket;
|
||||||
pub use ipc::binary::serialize;
|
pub use ipc::binary::serialize;
|
||||||
|
pub use light::remote::LightProviderClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature="ipc")]
|
#[cfg(feature="ipc")]
|
||||||
@ -124,6 +133,7 @@ pub fn sync
|
|||||||
net_cfg: NetworkConfiguration,
|
net_cfg: NetworkConfiguration,
|
||||||
_client: Arc<BlockChainClient>,
|
_client: Arc<BlockChainClient>,
|
||||||
_snapshot_service: Arc<SnapshotService>,
|
_snapshot_service: Arc<SnapshotService>,
|
||||||
|
_provider: Arc<Provider>,
|
||||||
log_settings: &LogConfig,
|
log_settings: &LogConfig,
|
||||||
)
|
)
|
||||||
-> Result<SyncModules, NetworkError>
|
-> Result<SyncModules, NetworkError>
|
||||||
@ -141,6 +151,8 @@ pub fn sync
|
|||||||
&service_urls::with_base(&hypervisor.io_path, service_urls::SYNC_NOTIFY)).unwrap();
|
&service_urls::with_base(&hypervisor.io_path, service_urls::SYNC_NOTIFY)).unwrap();
|
||||||
let manage_client = generic_client::<NetworkManagerClient<_>>(
|
let manage_client = generic_client::<NetworkManagerClient<_>>(
|
||||||
&service_urls::with_base(&hypervisor.io_path, service_urls::NETWORK_MANAGER)).unwrap();
|
&service_urls::with_base(&hypervisor.io_path, service_urls::NETWORK_MANAGER)).unwrap();
|
||||||
|
let provider_client = generic_client::<LightProviderClient<_>>(
|
||||||
|
&service_urls::with_base(&hypervisor.io_path, service_urls::LIGHT_PROVIDER)).unwrap();
|
||||||
|
|
||||||
*hypervisor_ref = Some(hypervisor);
|
*hypervisor_ref = Some(hypervisor);
|
||||||
Ok((sync_client, manage_client, notify_client))
|
Ok((sync_client, manage_client, notify_client))
|
||||||
@ -154,10 +166,18 @@ pub fn sync
|
|||||||
net_cfg: NetworkConfiguration,
|
net_cfg: NetworkConfiguration,
|
||||||
client: Arc<BlockChainClient>,
|
client: Arc<BlockChainClient>,
|
||||||
snapshot_service: Arc<SnapshotService>,
|
snapshot_service: Arc<SnapshotService>,
|
||||||
|
provider: Arc<Provider>,
|
||||||
_log_settings: &LogConfig,
|
_log_settings: &LogConfig,
|
||||||
)
|
)
|
||||||
-> Result<SyncModules, NetworkError>
|
-> Result<SyncModules, NetworkError>
|
||||||
{
|
{
|
||||||
let eth_sync = try!(EthSync::new(sync_cfg, client, snapshot_service, net_cfg));
|
let eth_sync = try!(EthSync::new(Params {
|
||||||
|
config: sync_cfg,
|
||||||
|
chain: client,
|
||||||
|
provider: provider,
|
||||||
|
snapshot_service: snapshot_service,
|
||||||
|
network_config: net_cfg,
|
||||||
|
}));
|
||||||
|
|
||||||
Ok((eth_sync.clone() as Arc<SyncProvider>, eth_sync.clone() as Arc<ManageNetwork>, eth_sync.clone() as Arc<ChainNotify>))
|
Ok((eth_sync.clone() as Arc<SyncProvider>, eth_sync.clone() as Arc<ManageNetwork>, eth_sync.clone() as Arc<ChainNotify>))
|
||||||
}
|
}
|
||||||
|
@ -92,6 +92,7 @@ pub struct RunCmd {
|
|||||||
pub no_periodic_snapshot: bool,
|
pub no_periodic_snapshot: bool,
|
||||||
pub check_seal: bool,
|
pub check_seal: bool,
|
||||||
pub download_old_blocks: bool,
|
pub download_old_blocks: bool,
|
||||||
|
pub serve_light: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open_ui(dapps_conf: &dapps::Configuration, signer_conf: &signer::Configuration) -> Result<(), String> {
|
pub fn open_ui(dapps_conf: &dapps::Configuration, signer_conf: &signer::Configuration) -> Result<(), String> {
|
||||||
@ -185,6 +186,11 @@ pub fn execute(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<(), String> {
|
|||||||
);
|
);
|
||||||
info!("Operating mode: {}", Colour::White.bold().paint(format!("{}", mode)));
|
info!("Operating mode: {}", Colour::White.bold().paint(format!("{}", mode)));
|
||||||
|
|
||||||
|
if cmd.serve_light {
|
||||||
|
info!("Configured to serve light client peers. Please note this feature is {}.",
|
||||||
|
Colour::White.bold().paint("experimental".to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
// display warning about using experimental journaldb alorithm
|
// display warning about using experimental journaldb alorithm
|
||||||
if !algorithm.is_stable() {
|
if !algorithm.is_stable() {
|
||||||
warn!("Your chosen strategy is {}! You can re-run with --pruning to change.", Colour::Red.bold().paint("unstable"));
|
warn!("Your chosen strategy is {}! You can re-run with --pruning to change.", Colour::Red.bold().paint("unstable"));
|
||||||
@ -204,6 +210,7 @@ pub fn execute(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<(), String> {
|
|||||||
sync_config.fork_block = spec.fork_block();
|
sync_config.fork_block = spec.fork_block();
|
||||||
sync_config.warp_sync = cmd.warp_sync;
|
sync_config.warp_sync = cmd.warp_sync;
|
||||||
sync_config.download_old_blocks = cmd.download_old_blocks;
|
sync_config.download_old_blocks = cmd.download_old_blocks;
|
||||||
|
sync_config.serve_light = cmd.serve_light;
|
||||||
|
|
||||||
// prepare account provider
|
// prepare account provider
|
||||||
let account_provider = Arc::new(try!(prepare_account_provider(&cmd.dirs, cmd.acc_conf)));
|
let account_provider = Arc::new(try!(prepare_account_provider(&cmd.dirs, cmd.acc_conf)));
|
||||||
@ -268,7 +275,13 @@ pub fn execute(cmd: RunCmd, logger: Arc<RotatingLogger>) -> Result<(), String> {
|
|||||||
|
|
||||||
// create sync object
|
// create sync object
|
||||||
let (sync_provider, manage_network, chain_notify) = try!(modules::sync(
|
let (sync_provider, manage_network, chain_notify) = try!(modules::sync(
|
||||||
&mut hypervisor, sync_config, net_conf.into(), client.clone(), snapshot_service.clone(), &cmd.logger_config,
|
&mut hypervisor,
|
||||||
|
sync_config,
|
||||||
|
net_conf.into(),
|
||||||
|
client.clone(),
|
||||||
|
snapshot_service.clone(),
|
||||||
|
client.clone(),
|
||||||
|
&cmd.logger_config,
|
||||||
).map_err(|e| format!("Sync error: {}", e)));
|
).map_err(|e| format!("Sync error: {}", e)));
|
||||||
|
|
||||||
service.add_notify(chain_notify.clone());
|
service.add_notify(chain_notify.clone());
|
||||||
|
@ -22,6 +22,7 @@ use hypervisor::{SYNC_MODULE_ID, HYPERVISOR_IPC_URL, ControlService};
|
|||||||
use ethcore::client::ChainNotify;
|
use ethcore::client::ChainNotify;
|
||||||
use ethcore::client::remote::RemoteClient;
|
use ethcore::client::remote::RemoteClient;
|
||||||
use ethcore::snapshot::remote::RemoteSnapshotService;
|
use ethcore::snapshot::remote::RemoteSnapshotService;
|
||||||
|
use light::remote::LightProviderClient;
|
||||||
use ethsync::{SyncProvider, EthSync, ManageNetwork, ServiceConfiguration};
|
use ethsync::{SyncProvider, EthSync, ManageNetwork, ServiceConfiguration};
|
||||||
use modules::service_urls;
|
use modules::service_urls;
|
||||||
use boot;
|
use boot;
|
||||||
@ -48,8 +49,15 @@ pub fn main() {
|
|||||||
|
|
||||||
let remote_client = dependency!(RemoteClient, &service_urls::with_base(&service_config.io_path, service_urls::CLIENT));
|
let remote_client = dependency!(RemoteClient, &service_urls::with_base(&service_config.io_path, service_urls::CLIENT));
|
||||||
let remote_snapshot = dependency!(RemoteSnapshotService, &service_urls::with_base(&service_config.io_path, service_urls::SNAPSHOT));
|
let remote_snapshot = dependency!(RemoteSnapshotService, &service_urls::with_base(&service_config.io_path, service_urls::SNAPSHOT));
|
||||||
|
let remote_provider = dependency!(LightProviderClient, &service_urls::with_base(&service_config.io_path, service_urls::LIGHT_PROVIDER));
|
||||||
|
|
||||||
let sync = EthSync::new(service_config.sync, remote_client.service().clone(), remote_snapshot.service().clone(), service_config.net).unwrap();
|
let sync = EthSync::new(Params {
|
||||||
|
config: service_config.sync,
|
||||||
|
chain: remote_client.service().clone(),
|
||||||
|
snapshot_service: remote_snapshot.service().clone(),
|
||||||
|
provider: remote_provider.service().clone(),
|
||||||
|
network_config: service_config.net
|
||||||
|
}).unwrap();
|
||||||
|
|
||||||
let _ = boot::main_thread();
|
let _ = boot::main_thread();
|
||||||
let service_stop = Arc::new(AtomicBool::new(false));
|
let service_stop = Arc::new(AtomicBool::new(false));
|
||||||
|
@ -16,6 +16,10 @@
|
|||||||
|
|
||||||
extern crate ethcore_ipc_codegen;
|
extern crate ethcore_ipc_codegen;
|
||||||
|
|
||||||
|
#[cfg(feature = "ipc")]
|
||||||
fn main() {
|
fn main() {
|
||||||
ethcore_ipc_codegen::derive_ipc_cond("src/api.rs", cfg!(feature="ipc")).unwrap();
|
ethcore_ipc_codegen::derive_ipc_cond("src/api.rs", true).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "ipc"))]
|
||||||
|
fn main() {}
|
||||||
|
116
sync/src/api.rs
116
sync/src/api.rs
@ -33,6 +33,7 @@ use ipc::{BinaryConvertable, BinaryConvertError, IpcConfig};
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use chain::{ETH_PACKET_COUNT, SNAPSHOT_SYNC_PACKET_COUNT};
|
use chain::{ETH_PACKET_COUNT, SNAPSHOT_SYNC_PACKET_COUNT};
|
||||||
|
use light::net::{LightProtocol, Params as LightParams, Capabilities, Handler as LightHandler, EventContext};
|
||||||
|
|
||||||
pub const WARP_SYNC_PROTOCOL_ID: ProtocolId = *b"par";
|
pub const WARP_SYNC_PROTOCOL_ID: ProtocolId = *b"par";
|
||||||
|
|
||||||
@ -47,10 +48,14 @@ pub struct SyncConfig {
|
|||||||
pub network_id: u64,
|
pub network_id: u64,
|
||||||
/// Main "eth" subprotocol name.
|
/// Main "eth" subprotocol name.
|
||||||
pub subprotocol_name: [u8; 3],
|
pub subprotocol_name: [u8; 3],
|
||||||
|
/// Light "les" subprotocol name.
|
||||||
|
pub light_subprotocol_name: [u8; 3],
|
||||||
/// Fork block to check
|
/// Fork block to check
|
||||||
pub fork_block: Option<(BlockNumber, H256)>,
|
pub fork_block: Option<(BlockNumber, H256)>,
|
||||||
/// Enable snapshot sync
|
/// Enable snapshot sync
|
||||||
pub warp_sync: bool,
|
pub warp_sync: bool,
|
||||||
|
/// Enable light client server.
|
||||||
|
pub serve_light: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for SyncConfig {
|
impl Default for SyncConfig {
|
||||||
@ -60,8 +65,10 @@ impl Default for SyncConfig {
|
|||||||
download_old_blocks: true,
|
download_old_blocks: true,
|
||||||
network_id: 1,
|
network_id: 1,
|
||||||
subprotocol_name: *b"eth",
|
subprotocol_name: *b"eth",
|
||||||
|
light_subprotocol_name: *b"les",
|
||||||
fork_block: None,
|
fork_block: None,
|
||||||
warp_sync: false,
|
warp_sync: false,
|
||||||
|
serve_light: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,30 +123,74 @@ pub struct PeerInfo {
|
|||||||
pub eth_difficulty: Option<U256>,
|
pub eth_difficulty: Option<U256>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// EthSync initialization parameters.
|
||||||
|
#[cfg_attr(feature = "ipc", derive(Binary))]
|
||||||
|
pub struct Params {
|
||||||
|
/// Configuration.
|
||||||
|
pub config: SyncConfig,
|
||||||
|
/// Blockchain client.
|
||||||
|
pub chain: Arc<BlockChainClient>,
|
||||||
|
/// Snapshot service.
|
||||||
|
pub snapshot_service: Arc<SnapshotService>,
|
||||||
|
/// Light data provider.
|
||||||
|
pub provider: Arc<::light::Provider>,
|
||||||
|
/// Network layer configuration.
|
||||||
|
pub network_config: NetworkConfiguration,
|
||||||
|
}
|
||||||
|
|
||||||
/// Ethereum network protocol handler
|
/// Ethereum network protocol handler
|
||||||
pub struct EthSync {
|
pub struct EthSync {
|
||||||
/// Network service
|
/// Network service
|
||||||
network: NetworkService,
|
network: NetworkService,
|
||||||
/// Protocol handler
|
/// Main (eth/par) protocol handler
|
||||||
handler: Arc<SyncProtocolHandler>,
|
sync_handler: Arc<SyncProtocolHandler>,
|
||||||
|
/// Light (les) protocol handler
|
||||||
|
light_proto: Option<Arc<LightProtocol>>,
|
||||||
/// The main subprotocol name
|
/// The main subprotocol name
|
||||||
subprotocol_name: [u8; 3],
|
subprotocol_name: [u8; 3],
|
||||||
|
/// Light subprotocol name.
|
||||||
|
light_subprotocol_name: [u8; 3],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EthSync {
|
impl EthSync {
|
||||||
/// Creates and register protocol with the network service
|
/// Creates and register protocol with the network service
|
||||||
pub fn new(config: SyncConfig, chain: Arc<BlockChainClient>, snapshot_service: Arc<SnapshotService>, network_config: NetworkConfiguration) -> Result<Arc<EthSync>, NetworkError> {
|
pub fn new(params: Params) -> Result<Arc<EthSync>, NetworkError> {
|
||||||
let chain_sync = ChainSync::new(config, &*chain);
|
let pruning_info = params.chain.pruning_info();
|
||||||
let service = try!(NetworkService::new(try!(network_config.clone().into_basic())));
|
let light_proto = match params.config.serve_light {
|
||||||
let sync = Arc::new(EthSync{
|
false => None,
|
||||||
|
true => Some({
|
||||||
|
let light_params = LightParams {
|
||||||
|
network_id: params.config.network_id,
|
||||||
|
flow_params: Default::default(),
|
||||||
|
capabilities: Capabilities {
|
||||||
|
serve_headers: true,
|
||||||
|
serve_chain_since: Some(pruning_info.earliest_chain),
|
||||||
|
serve_state_since: Some(pruning_info.earliest_state),
|
||||||
|
tx_relay: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut light_proto = LightProtocol::new(params.provider, light_params);
|
||||||
|
light_proto.add_handler(Box::new(TxRelay(params.chain.clone())));
|
||||||
|
|
||||||
|
Arc::new(light_proto)
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
let chain_sync = ChainSync::new(params.config, &*params.chain);
|
||||||
|
let service = try!(NetworkService::new(try!(params.network_config.clone().into_basic())));
|
||||||
|
|
||||||
|
let sync = Arc::new(EthSync {
|
||||||
network: service,
|
network: service,
|
||||||
handler: Arc::new(SyncProtocolHandler {
|
sync_handler: Arc::new(SyncProtocolHandler {
|
||||||
sync: RwLock::new(chain_sync),
|
sync: RwLock::new(chain_sync),
|
||||||
chain: chain,
|
chain: params.chain,
|
||||||
snapshot_service: snapshot_service,
|
snapshot_service: params.snapshot_service,
|
||||||
overlay: RwLock::new(HashMap::new()),
|
overlay: RwLock::new(HashMap::new()),
|
||||||
}),
|
}),
|
||||||
subprotocol_name: config.subprotocol_name,
|
light_proto: light_proto,
|
||||||
|
subprotocol_name: params.config.subprotocol_name,
|
||||||
|
light_subprotocol_name: params.config.light_subprotocol_name,
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(sync)
|
Ok(sync)
|
||||||
@ -150,14 +201,15 @@ impl EthSync {
|
|||||||
impl SyncProvider for EthSync {
|
impl SyncProvider for EthSync {
|
||||||
/// Get sync status
|
/// Get sync status
|
||||||
fn status(&self) -> SyncStatus {
|
fn status(&self) -> SyncStatus {
|
||||||
self.handler.sync.write().status()
|
self.sync_handler.sync.write().status()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get sync peers
|
/// Get sync peers
|
||||||
fn peers(&self) -> Vec<PeerInfo> {
|
fn peers(&self) -> Vec<PeerInfo> {
|
||||||
|
// TODO: [rob] LES peers/peer info
|
||||||
self.network.with_context_eval(self.subprotocol_name, |context| {
|
self.network.with_context_eval(self.subprotocol_name, |context| {
|
||||||
let sync_io = NetSyncIo::new(context, &*self.handler.chain, &*self.handler.snapshot_service, &self.handler.overlay);
|
let sync_io = NetSyncIo::new(context, &*self.sync_handler.chain, &*self.sync_handler.snapshot_service, &self.sync_handler.overlay);
|
||||||
self.handler.sync.write().peers(&sync_io)
|
self.sync_handler.sync.write().peers(&sync_io)
|
||||||
}).unwrap_or(Vec::new())
|
}).unwrap_or(Vec::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,7 +218,7 @@ impl SyncProvider for EthSync {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn transactions_stats(&self) -> BTreeMap<H256, TransactionStats> {
|
fn transactions_stats(&self) -> BTreeMap<H256, TransactionStats> {
|
||||||
let sync = self.handler.sync.read();
|
let sync = self.sync_handler.sync.read();
|
||||||
sync.transactions_stats()
|
sync.transactions_stats()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(hash, stats)| (*hash, stats.into()))
|
.map(|(hash, stats)| (*hash, stats.into()))
|
||||||
@ -228,8 +280,8 @@ impl ChainNotify for EthSync {
|
|||||||
_duration: u64)
|
_duration: u64)
|
||||||
{
|
{
|
||||||
self.network.with_context(self.subprotocol_name, |context| {
|
self.network.with_context(self.subprotocol_name, |context| {
|
||||||
let mut sync_io = NetSyncIo::new(context, &*self.handler.chain, &*self.handler.snapshot_service, &self.handler.overlay);
|
let mut sync_io = NetSyncIo::new(context, &*self.sync_handler.chain, &*self.sync_handler.snapshot_service, &self.sync_handler.overlay);
|
||||||
self.handler.sync.write().chain_new_blocks(
|
self.sync_handler.sync.write().chain_new_blocks(
|
||||||
&mut sync_io,
|
&mut sync_io,
|
||||||
&imported,
|
&imported,
|
||||||
&invalid,
|
&invalid,
|
||||||
@ -245,19 +297,36 @@ impl ChainNotify for EthSync {
|
|||||||
Err(err) => warn!("Error starting network: {}", err),
|
Err(err) => warn!("Error starting network: {}", err),
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
self.network.register_protocol(self.handler.clone(), self.subprotocol_name, ETH_PACKET_COUNT, &[62u8, 63u8])
|
self.network.register_protocol(self.sync_handler.clone(), self.subprotocol_name, ETH_PACKET_COUNT, &[62u8, 63u8])
|
||||||
.unwrap_or_else(|e| warn!("Error registering ethereum protocol: {:?}", e));
|
.unwrap_or_else(|e| warn!("Error registering ethereum protocol: {:?}", e));
|
||||||
// register the warp sync subprotocol
|
// register the warp sync subprotocol
|
||||||
self.network.register_protocol(self.handler.clone(), WARP_SYNC_PROTOCOL_ID, SNAPSHOT_SYNC_PACKET_COUNT, &[1u8])
|
self.network.register_protocol(self.sync_handler.clone(), WARP_SYNC_PROTOCOL_ID, SNAPSHOT_SYNC_PACKET_COUNT, &[1u8])
|
||||||
.unwrap_or_else(|e| warn!("Error registering snapshot sync protocol: {:?}", e));
|
.unwrap_or_else(|e| warn!("Error registering snapshot sync protocol: {:?}", e));
|
||||||
|
|
||||||
|
// register the light protocol.
|
||||||
|
if let Some(light_proto) = self.light_proto.as_ref().map(|x| x.clone()) {
|
||||||
|
self.network.register_protocol(light_proto, self.light_subprotocol_name, ::light::net::PACKET_COUNT, ::light::net::PROTOCOL_VERSIONS)
|
||||||
|
.unwrap_or_else(|e| warn!("Error registering light client protocol: {:?}", e));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop(&self) {
|
fn stop(&self) {
|
||||||
self.handler.snapshot_service.abort_restore();
|
self.sync_handler.snapshot_service.abort_restore();
|
||||||
self.network.stop().unwrap_or_else(|e| warn!("Error stopping network: {:?}", e));
|
self.network.stop().unwrap_or_else(|e| warn!("Error stopping network: {:?}", e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// LES event handler.
|
||||||
|
/// Simply queues transactions from light client peers.
|
||||||
|
struct TxRelay(Arc<BlockChainClient>);
|
||||||
|
|
||||||
|
impl LightHandler for TxRelay {
|
||||||
|
fn on_transactions(&self, ctx: &EventContext, relay: &[::ethcore::transaction::SignedTransaction]) {
|
||||||
|
trace!(target: "les", "Relaying {} transactions from peer {}", relay.len(), ctx.peer());
|
||||||
|
self.0.queue_transactions(relay.iter().map(|tx| ::rlp::encode(tx).to_vec()).collect())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl IpcConfig for ManageNetwork { }
|
impl IpcConfig for ManageNetwork { }
|
||||||
impl IpcConfig for SyncProvider { }
|
impl IpcConfig for SyncProvider { }
|
||||||
|
|
||||||
@ -304,9 +373,14 @@ impl ManageNetwork for EthSync {
|
|||||||
|
|
||||||
fn stop_network(&self) {
|
fn stop_network(&self) {
|
||||||
self.network.with_context(self.subprotocol_name, |context| {
|
self.network.with_context(self.subprotocol_name, |context| {
|
||||||
let mut sync_io = NetSyncIo::new(context, &*self.handler.chain, &*self.handler.snapshot_service, &self.handler.overlay);
|
let mut sync_io = NetSyncIo::new(context, &*self.sync_handler.chain, &*self.sync_handler.snapshot_service, &self.sync_handler.overlay);
|
||||||
self.handler.sync.write().abort(&mut sync_io);
|
self.sync_handler.sync.write().abort(&mut sync_io);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if let Some(light_proto) = self.light_proto.as_ref() {
|
||||||
|
light_proto.abort();
|
||||||
|
}
|
||||||
|
|
||||||
self.stop();
|
self.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ mod api {
|
|||||||
#[cfg(not(feature = "ipc"))]
|
#[cfg(not(feature = "ipc"))]
|
||||||
mod api;
|
mod api;
|
||||||
|
|
||||||
pub use api::{EthSync, SyncProvider, ManageNetwork, SyncConfig,
|
pub use api::{EthSync, Params, SyncProvider, ManageNetwork, SyncConfig,
|
||||||
ServiceConfiguration, NetworkConfiguration, PeerInfo, AllowIP, TransactionStats};
|
ServiceConfiguration, NetworkConfiguration, PeerInfo, AllowIP, TransactionStats};
|
||||||
pub use chain::{SyncStatus, SyncState};
|
pub use chain::{SyncStatus, SyncState};
|
||||||
pub use network::{is_valid_node_url, NonReservedPeerMode, NetworkError};
|
pub use network::{is_valid_node_url, NonReservedPeerMode, NetworkError};
|
||||||
|
Loading…
Reference in New Issue
Block a user