fixed connection establishing
This commit is contained in:
parent
7664ff5acd
commit
80b9e931f5
@ -289,8 +289,7 @@ impl ClusterCore {
|
|||||||
|
|
||||||
/// Accept connection future.
|
/// Accept connection future.
|
||||||
fn accept_connection_future(handle: &Handle, data: Arc<ClusterData>, stream: TcpStream, node_address: SocketAddr) -> BoxedEmptyFuture {
|
fn accept_connection_future(handle: &Handle, data: Arc<ClusterData>, stream: TcpStream, node_address: SocketAddr) -> BoxedEmptyFuture {
|
||||||
let disconnected_nodes = data.connections.disconnected_nodes().keys().cloned().collect();
|
net_accept_connection(node_address, stream, handle, data.self_key_pair.clone())
|
||||||
net_accept_connection(node_address, stream, handle, data.self_key_pair.clone(), disconnected_nodes)
|
|
||||||
.then(move |result| ClusterCore::process_connection_result(data, true, result))
|
.then(move |result| ClusterCore::process_connection_result(data, true, result))
|
||||||
.then(|_| finished(()))
|
.then(|_| finished(()))
|
||||||
.boxed()
|
.boxed()
|
||||||
@ -381,14 +380,16 @@ impl ClusterCore {
|
|||||||
finished(Ok(())).boxed()
|
finished(Ok(())).boxed()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Ok(DeadlineStatus::Meet(Err(_))) => {
|
Ok(DeadlineStatus::Meet(Err(err))) => {
|
||||||
|
warn!(target: "secretstore_net", "{}: protocol error {} when establishind connection", data.self_key_pair.public(), err);
|
||||||
finished(Ok(())).boxed()
|
finished(Ok(())).boxed()
|
||||||
},
|
},
|
||||||
Ok(DeadlineStatus::Timeout) => {
|
Ok(DeadlineStatus::Timeout) => {
|
||||||
|
warn!(target: "secretstore_net", "{}: timeout when establishind connection", data.self_key_pair.public());
|
||||||
finished(Ok(())).boxed()
|
finished(Ok(())).boxed()
|
||||||
},
|
},
|
||||||
Err(_) => {
|
Err(err) => {
|
||||||
// network error
|
warn!(target: "secretstore_net", "{}: network error {} when establishind connection", data.self_key_pair.public(), err);
|
||||||
finished(Ok(())).boxed()
|
finished(Ok(())).boxed()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -699,6 +700,12 @@ impl ClusterConnections {
|
|||||||
|
|
||||||
pub fn insert(&self, connection: Arc<Connection>) -> bool {
|
pub fn insert(&self, connection: Arc<Connection>) -> bool {
|
||||||
let mut data = self.data.write();
|
let mut data = self.data.write();
|
||||||
|
if !data.nodes.contains_key(connection.node_id()) {
|
||||||
|
// incoming connections are checked here
|
||||||
|
trace!(target: "secretstore_net", "{}: ignoring unknown connection from {} at {}", self.self_node_id, connection.node_id(), connection.node_address());
|
||||||
|
debug_assert!(connection.is_inbound());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if data.connections.contains_key(connection.node_id()) {
|
if data.connections.contains_key(connection.node_id()) {
|
||||||
// we have already connected to the same node
|
// we have already connected to the same node
|
||||||
// the agreement is that node with lower id must establish connection to node with higher id
|
// the agreement is that node with lower id must establish connection to node with higher id
|
||||||
@ -746,14 +753,37 @@ impl ClusterConnections {
|
|||||||
let mut new_nodes = self.key_server_set.get();
|
let mut new_nodes = self.key_server_set.get();
|
||||||
new_nodes.remove(&self.self_node_id);
|
new_nodes.remove(&self.self_node_id);
|
||||||
|
|
||||||
|
let mut num_added_nodes = 0;
|
||||||
|
let mut num_removed_nodes = 0;
|
||||||
|
let mut num_changed_nodes = 0;
|
||||||
|
|
||||||
for obsolete_node in data.nodes.keys().cloned().collect::<Vec<_>>() {
|
for obsolete_node in data.nodes.keys().cloned().collect::<Vec<_>>() {
|
||||||
if !new_nodes.contains_key(&obsolete_node) {
|
if !new_nodes.contains_key(&obsolete_node) {
|
||||||
|
if let Entry::Occupied(entry) = data.connections.entry(obsolete_node) {
|
||||||
|
trace!(target: "secretstore_net", "{}: removing connection to {} at {}", self.self_node_id, entry.get().node_id(), entry.get().node_address());
|
||||||
|
entry.remove();
|
||||||
|
}
|
||||||
|
|
||||||
data.nodes.remove(&obsolete_node);
|
data.nodes.remove(&obsolete_node);
|
||||||
data.connections.remove(&obsolete_node);
|
num_removed_nodes += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (new_node_public, new_node_addr) in new_nodes {
|
for (new_node_public, new_node_addr) in new_nodes {
|
||||||
data.nodes.insert(new_node_public, new_node_addr);
|
match data.nodes.insert(new_node_public, new_node_addr) {
|
||||||
|
None => num_added_nodes += 1,
|
||||||
|
Some(old_node_addr) => if new_node_addr != old_node_addr {
|
||||||
|
if let Entry::Occupied(entry) = data.connections.entry(new_node_public) {
|
||||||
|
trace!(target: "secretstore_net", "{}: removing connection to {} at {}", self.self_node_id, entry.get().node_id(), entry.get().node_address());
|
||||||
|
entry.remove();
|
||||||
|
}
|
||||||
|
num_changed_nodes += 1;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if num_added_nodes != 0 || num_removed_nodes != 0 || num_changed_nodes != 0 {
|
||||||
|
trace!(target: "secretstore_net", "{}: updated nodes set: removed {}, added {}, changed {}", self.self_node_id, num_removed_nodes, num_added_nodes, num_changed_nodes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ pub fn handshake_with_plain_confirmation<A>(a: A, self_confirmation_plain: Resul
|
|||||||
state: state,
|
state: state,
|
||||||
self_key_pair: self_key_pair,
|
self_key_pair: self_key_pair,
|
||||||
self_confirmation_plain: self_confirmation_plain.unwrap_or(Default::default()),
|
self_confirmation_plain: self_confirmation_plain.unwrap_or(Default::default()),
|
||||||
trusted_nodes: trusted_nodes,
|
trusted_nodes: Some(trusted_nodes),
|
||||||
other_node_id: None,
|
other_node_id: None,
|
||||||
other_confirmation_plain: None,
|
other_confirmation_plain: None,
|
||||||
shared_key: None,
|
shared_key: None,
|
||||||
@ -53,7 +53,7 @@ pub fn handshake_with_plain_confirmation<A>(a: A, self_confirmation_plain: Resul
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Wait for handshake procedure to be started by another node from the cluster.
|
/// Wait for handshake procedure to be started by another node from the cluster.
|
||||||
pub fn accept_handshake<A>(a: A, self_key_pair: KeyPair, trusted_nodes: BTreeSet<NodeId>) -> Handshake<A> where A: AsyncWrite + AsyncRead {
|
pub fn accept_handshake<A>(a: A, self_key_pair: KeyPair) -> Handshake<A> where A: AsyncWrite + AsyncRead {
|
||||||
let self_confirmation_plain = Random.generate().map(|kp| *kp.secret().clone()).map_err(Into::into);
|
let self_confirmation_plain = Random.generate().map(|kp| *kp.secret().clone()).map_err(Into::into);
|
||||||
let (error, state) = match self_confirmation_plain.clone() {
|
let (error, state) = match self_confirmation_plain.clone() {
|
||||||
Ok(_) => (None, HandshakeState::ReceivePublicKey(read_message(a))),
|
Ok(_) => (None, HandshakeState::ReceivePublicKey(read_message(a))),
|
||||||
@ -66,7 +66,7 @@ pub fn accept_handshake<A>(a: A, self_key_pair: KeyPair, trusted_nodes: BTreeSet
|
|||||||
state: state,
|
state: state,
|
||||||
self_key_pair: self_key_pair,
|
self_key_pair: self_key_pair,
|
||||||
self_confirmation_plain: self_confirmation_plain.unwrap_or(Default::default()),
|
self_confirmation_plain: self_confirmation_plain.unwrap_or(Default::default()),
|
||||||
trusted_nodes: trusted_nodes,
|
trusted_nodes: None,
|
||||||
other_node_id: None,
|
other_node_id: None,
|
||||||
other_confirmation_plain: None,
|
other_confirmation_plain: None,
|
||||||
shared_key: None,
|
shared_key: None,
|
||||||
@ -89,7 +89,7 @@ pub struct Handshake<A> {
|
|||||||
state: HandshakeState<A>,
|
state: HandshakeState<A>,
|
||||||
self_key_pair: KeyPair,
|
self_key_pair: KeyPair,
|
||||||
self_confirmation_plain: H256,
|
self_confirmation_plain: H256,
|
||||||
trusted_nodes: BTreeSet<NodeId>,
|
trusted_nodes: Option<BTreeSet<NodeId>>,
|
||||||
other_node_id: Option<NodeId>,
|
other_node_id: Option<NodeId>,
|
||||||
other_confirmation_plain: Option<H256>,
|
other_confirmation_plain: Option<H256>,
|
||||||
shared_key: Option<KeyPair>,
|
shared_key: Option<KeyPair>,
|
||||||
@ -172,7 +172,8 @@ impl<A> Future for Handshake<A> where A: AsyncRead + AsyncWrite {
|
|||||||
Err(err) => return Ok((stream, Err(err.into())).into()),
|
Err(err) => return Ok((stream, Err(err.into())).into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
if !self.trusted_nodes.contains(&*message.node_id) {
|
if !self.trusted_nodes.as_ref().map(|tn| tn.contains(&*message.node_id)).unwrap_or(true) {
|
||||||
|
println!("=== HANDSHAKE - INVALID NODE: self.trusted_nodes = {:?}, message.node_id = {:?}", self.trusted_nodes, message.node_id);
|
||||||
return Ok((stream, Err(Error::InvalidNodeId)).into());
|
return Ok((stream, Err(Error::InvalidNodeId)).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,7 +301,7 @@ mod tests {
|
|||||||
let trusted_nodes: BTreeSet<_> = vec![io.peer_public().clone()].into_iter().collect();
|
let trusted_nodes: BTreeSet<_> = vec![io.peer_public().clone()].into_iter().collect();
|
||||||
let shared_key = compute_shared_key(self_key_pair.secret(), trusted_nodes.iter().nth(0).unwrap()).unwrap();
|
let shared_key = compute_shared_key(self_key_pair.secret(), trusted_nodes.iter().nth(0).unwrap()).unwrap();
|
||||||
|
|
||||||
let mut handshake = accept_handshake(io, self_key_pair, trusted_nodes);
|
let mut handshake = accept_handshake(io, self_key_pair);
|
||||||
handshake.set_self_confirmation_plain(self_confirmation_plain);
|
handshake.set_self_confirmation_plain(self_confirmation_plain);
|
||||||
|
|
||||||
let handshake_result = handshake.wait().unwrap();
|
let handshake_result = handshake.wait().unwrap();
|
||||||
|
@ -17,19 +17,18 @@
|
|||||||
use std::io;
|
use std::io;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::collections::BTreeSet;
|
|
||||||
use futures::{Future, Poll};
|
use futures::{Future, Poll};
|
||||||
use tokio_core::reactor::Handle;
|
use tokio_core::reactor::Handle;
|
||||||
use tokio_core::net::TcpStream;
|
use tokio_core::net::TcpStream;
|
||||||
use ethkey::KeyPair;
|
use ethkey::KeyPair;
|
||||||
use key_server_cluster::{Error, NodeId};
|
use key_server_cluster::Error;
|
||||||
use key_server_cluster::io::{accept_handshake, Handshake, Deadline, deadline};
|
use key_server_cluster::io::{accept_handshake, Handshake, Deadline, deadline};
|
||||||
use key_server_cluster::net::Connection;
|
use key_server_cluster::net::Connection;
|
||||||
|
|
||||||
/// Create future for accepting incoming connection.
|
/// Create future for accepting incoming connection.
|
||||||
pub fn accept_connection(address: SocketAddr, stream: TcpStream, handle: &Handle, self_key_pair: KeyPair, trusted_nodes: BTreeSet<NodeId>) -> Deadline<AcceptConnection> {
|
pub fn accept_connection(address: SocketAddr, stream: TcpStream, handle: &Handle, self_key_pair: KeyPair) -> Deadline<AcceptConnection> {
|
||||||
let accept = AcceptConnection {
|
let accept = AcceptConnection {
|
||||||
handshake: accept_handshake(stream, self_key_pair, trusted_nodes),
|
handshake: accept_handshake(stream, self_key_pair),
|
||||||
address: address,
|
address: address,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -28,8 +28,8 @@ use types::all::Public;
|
|||||||
const KEY_SERVER_SET_CONTRACT_REGISTRY_NAME: &'static str = "secretstore_server_set";
|
const KEY_SERVER_SET_CONTRACT_REGISTRY_NAME: &'static str = "secretstore_server_set";
|
||||||
|
|
||||||
// TODO: ethabi should be able to generate this.
|
// TODO: ethabi should be able to generate this.
|
||||||
const ADDED_EVENT_NAME: &'static [u8] = &*b"KeyServerAdded()";
|
const ADDED_EVENT_NAME: &'static [u8] = &*b"KeyServerAdded(address)";
|
||||||
const REMOVED_EVENT_NAME: &'static [u8] = &*b"KeyServerRemoved()";
|
const REMOVED_EVENT_NAME: &'static [u8] = &*b"KeyServerRemoved(address)";
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref ADDED_EVENT_NAME_HASH: H256 = ADDED_EVENT_NAME.sha3();
|
static ref ADDED_EVENT_NAME_HASH: H256 = ADDED_EVENT_NAME.sha3();
|
||||||
@ -83,7 +83,6 @@ impl KeyServerSet for OnChainKeyServerSet {
|
|||||||
|
|
||||||
impl ChainNotify for OnChainKeyServerSet {
|
impl ChainNotify for OnChainKeyServerSet {
|
||||||
fn new_blocks(&self, _imported: Vec<H256>, _invalid: Vec<H256>, enacted: Vec<H256>, retracted: Vec<H256>, _sealed: Vec<H256>, _proposed: Vec<Bytes>, _duration: u64) {
|
fn new_blocks(&self, _imported: Vec<H256>, _invalid: Vec<H256>, enacted: Vec<H256>, retracted: Vec<H256>, _sealed: Vec<H256>, _proposed: Vec<Bytes>, _duration: u64) {
|
||||||
println!("=== new_blocks: imported {}, invalid: {}, enactd: {}, retracted: {}, sealed: {}, proposed: {}", _imported.len(), _invalid.len(), enacted.len(), retracted.len(), _sealed.len(), _proposed.len());
|
|
||||||
self.contract.lock().update(enacted, retracted)
|
self.contract.lock().update(enacted, retracted)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,26 +96,33 @@ impl CachedContract {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, enacted: Vec<H256>, _retracted: Vec<H256>) {
|
pub fn update(&mut self, enacted: Vec<H256>, retracted: Vec<H256>) {
|
||||||
if let Some(client) = self.client.upgrade() {
|
if let Some(client) = self.client.upgrade() {
|
||||||
let new_contract_addr = client.registry_address(KEY_SERVER_SET_CONTRACT_REGISTRY_NAME.to_owned());
|
let new_contract_addr = client.registry_address(KEY_SERVER_SET_CONTRACT_REGISTRY_NAME.to_owned());
|
||||||
println!("=== Registry address = {:?}", new_contract_addr);
|
|
||||||
// new contract installed
|
// new contract installed
|
||||||
if self.contract_addr.as_ref() != new_contract_addr.as_ref() {
|
if self.contract_addr.as_ref() != new_contract_addr.as_ref() {
|
||||||
self.read_from_registry(&*client, new_contract_addr);
|
self.read_from_registry(&*client, new_contract_addr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for events
|
// check for contract events
|
||||||
for enacted_hash in enacted {
|
let is_set_changed = self.contract_addr.is_some() && enacted.iter()
|
||||||
let filter = Filter {
|
.chain(retracted.iter())
|
||||||
from_block: BlockId::Hash(enacted_hash.clone()),
|
.any(|block_hash| !client.logs(Filter {
|
||||||
to_block: BlockId::Hash(enacted_hash.clone()),
|
from_block: BlockId::Hash(block_hash.clone()),
|
||||||
|
to_block: BlockId::Hash(block_hash.clone()),
|
||||||
address: self.contract_addr.clone().map(|a| vec![a]),
|
address: self.contract_addr.clone().map(|a| vec![a]),
|
||||||
topics: vec![Some(vec![*ADDED_EVENT_NAME_HASH]), Some(vec![*REMOVED_EVENT_NAME_HASH])],
|
topics: vec![
|
||||||
limit: None,
|
Some(vec![*ADDED_EVENT_NAME_HASH, *REMOVED_EVENT_NAME_HASH]),
|
||||||
};
|
None,
|
||||||
println!("=== Number of filtered log entries: {}", client.logs(filter).len());
|
None,
|
||||||
|
None,
|
||||||
|
],
|
||||||
|
limit: Some(1),
|
||||||
|
}).is_empty());
|
||||||
|
if is_set_changed {
|
||||||
|
self.read_from_registry(&*client, new_contract_addr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -126,7 +132,6 @@ println!("=== Registry address = {:?}", new_contract_addr);
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn read_from_registry(&mut self, client: &Client, new_contract_address: Option<Address>) {
|
fn read_from_registry(&mut self, client: &Client, new_contract_address: Option<Address>) {
|
||||||
println!("=== Installing contract from address: {:?}", new_contract_address);
|
|
||||||
self.key_servers = new_contract_address.map(|contract_addr| {
|
self.key_servers = new_contract_address.map(|contract_addr| {
|
||||||
trace!(target: "secretstore", "Configuring for key server set contract from {}", contract_addr);
|
trace!(target: "secretstore", "Configuring for key server set contract from {}", contract_addr);
|
||||||
|
|
||||||
@ -146,10 +151,8 @@ println!("=== Installing contract from address: {:?}", new_contract_address);
|
|||||||
|a, d| future::done(client.call_contract(BlockId::Latest, a, d)), key_server).wait()
|
|a, d| future::done(client.call_contract(BlockId::Latest, a, d)), key_server).wait()
|
||||||
.and_then(|a| a.parse().map_err(|e| format!("Invalid ip address: {}", e)));
|
.and_then(|a| a.parse().map_err(|e| format!("Invalid ip address: {}", e)));
|
||||||
if let (Ok(key_server_public), Ok(key_server_ip)) = (key_server_public, key_server_ip) {
|
if let (Ok(key_server_public), Ok(key_server_ip)) = (key_server_public, key_server_ip) {
|
||||||
println!("=== PARSED {:?} {:?}", key_server_public, key_server_ip);
|
|
||||||
key_servers.insert(key_server_public, key_server_ip);
|
key_servers.insert(key_server_public, key_server_ip);
|
||||||
}
|
}
|
||||||
else { println!("=== ERROR parsing"); }
|
|
||||||
}
|
}
|
||||||
key_servers
|
key_servers
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user