exclusive access to each peer at a time
This commit is contained in:
parent
4fd9670b33
commit
48df2e12fa
@ -99,7 +99,7 @@ struct PendingPeer {
|
|||||||
|
|
||||||
// data about each peer.
|
// data about each peer.
|
||||||
struct Peer {
|
struct Peer {
|
||||||
local_buffer: Mutex<Buffer>, // their buffer relative to us
|
local_buffer: Buffer, // their buffer relative to us
|
||||||
remote_buffer: Buffer, // our buffer relative to them
|
remote_buffer: Buffer, // our buffer relative to them
|
||||||
current_asking: HashSet<usize>, // pending request ids.
|
current_asking: HashSet<usize>, // pending request ids.
|
||||||
status: Status,
|
status: Status,
|
||||||
@ -112,21 +112,25 @@ impl Peer {
|
|||||||
// check the maximum cost of a request, returning an error if there's
|
// check the maximum cost of a request, returning an error if there's
|
||||||
// not enough buffer left.
|
// not enough buffer left.
|
||||||
// returns the calculated maximum cost.
|
// returns the calculated maximum cost.
|
||||||
fn deduct_max(&self, flow_params: &FlowParams, kind: request::Kind, max: usize) -> Result<U256, Error> {
|
fn deduct_max(&mut self, flow_params: &FlowParams, kind: request::Kind, max: usize) -> Result<U256, Error> {
|
||||||
let mut local_buffer = self.local_buffer.lock();
|
flow_params.recharge(&mut self.local_buffer);
|
||||||
flow_params.recharge(&mut local_buffer);
|
|
||||||
|
|
||||||
let max_cost = flow_params.compute_cost(kind, max);
|
let max_cost = flow_params.compute_cost(kind, max);
|
||||||
try!(local_buffer.deduct_cost(max_cost));
|
try!(self.local_buffer.deduct_cost(max_cost));
|
||||||
Ok(max_cost)
|
Ok(max_cost)
|
||||||
}
|
}
|
||||||
|
|
||||||
// refund buffer for a request. returns new buffer amount.
|
// refund buffer for a request. returns new buffer amount.
|
||||||
fn refund(&self, flow_params: &FlowParams, amount: U256) -> U256 {
|
fn refund(&mut self, flow_params: &FlowParams, amount: U256) -> U256 {
|
||||||
let mut local_buffer = self.local_buffer.lock();
|
flow_params.refund(&mut self.local_buffer, amount);
|
||||||
flow_params.refund(&mut local_buffer, amount);
|
|
||||||
|
|
||||||
local_buffer.current()
|
self.local_buffer.current()
|
||||||
|
}
|
||||||
|
|
||||||
|
// recharge remote buffer with remote flow params.
|
||||||
|
fn recharge_remote(&mut self) {
|
||||||
|
let flow = &mut self.remote_flow;
|
||||||
|
flow.recharge(&mut self.remote_buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,7 +175,7 @@ pub struct LightProtocol {
|
|||||||
genesis_hash: H256,
|
genesis_hash: H256,
|
||||||
network_id: NetworkId,
|
network_id: NetworkId,
|
||||||
pending_peers: RwLock<HashMap<PeerId, PendingPeer>>,
|
pending_peers: RwLock<HashMap<PeerId, PendingPeer>>,
|
||||||
peers: RwLock<HashMap<PeerId, Peer>>,
|
peers: RwLock<HashMap<PeerId, Mutex<Peer>>>,
|
||||||
pending_requests: RwLock<HashMap<usize, Requested>>,
|
pending_requests: RwLock<HashMap<usize, Requested>>,
|
||||||
capabilities: RwLock<Capabilities>,
|
capabilities: RwLock<Capabilities>,
|
||||||
flow_params: FlowParams, // assumed static and same for every peer.
|
flow_params: FlowParams, // assumed static and same for every peer.
|
||||||
@ -199,8 +203,9 @@ impl LightProtocol {
|
|||||||
/// Check the maximum amount of requests of a specific type
|
/// Check the maximum amount of requests of a specific type
|
||||||
/// which a peer would be able to serve.
|
/// which a peer would be able to serve.
|
||||||
pub fn max_requests(&self, peer: PeerId, kind: request::Kind) -> Option<usize> {
|
pub fn max_requests(&self, peer: PeerId, kind: request::Kind) -> Option<usize> {
|
||||||
self.peers.write().get_mut(&peer).map(|peer| {
|
self.peers.read().get(&peer).map(|peer| {
|
||||||
peer.remote_flow.recharge(&mut peer.remote_buffer);
|
let mut peer = peer.lock();
|
||||||
|
peer.recharge_remote();
|
||||||
peer.remote_flow.max_amount(&peer.remote_buffer, kind)
|
peer.remote_flow.max_amount(&peer.remote_buffer, kind)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -212,9 +217,11 @@ impl LightProtocol {
|
|||||||
/// On success, returns a request id which can later be coordinated
|
/// On success, returns a request id which can later be coordinated
|
||||||
/// with an event.
|
/// with an event.
|
||||||
pub fn request_from(&self, io: &NetworkContext, peer_id: &PeerId, request: Request) -> Result<ReqId, Error> {
|
pub fn request_from(&self, io: &NetworkContext, peer_id: &PeerId, request: Request) -> Result<ReqId, Error> {
|
||||||
let mut peers = self.peers.write();
|
let peers = self.peers.read();
|
||||||
let peer = try!(peers.get_mut(peer_id).ok_or_else(|| Error::UnknownPeer));
|
let peer = try!(peers.get(peer_id).ok_or_else(|| Error::UnknownPeer));
|
||||||
peer.remote_flow.recharge(&mut peer.remote_buffer);
|
let mut peer = peer.lock();
|
||||||
|
|
||||||
|
peer.recharge_remote();
|
||||||
|
|
||||||
let max = peer.remote_flow.compute_cost(request.kind(), request.amount());
|
let max = peer.remote_flow.compute_cost(request.kind(), request.amount());
|
||||||
try!(peer.remote_buffer.deduct_cost(max));
|
try!(peer.remote_buffer.deduct_cost(max));
|
||||||
@ -251,7 +258,8 @@ impl LightProtocol {
|
|||||||
self.capabilities.write().update_from(&announcement);
|
self.capabilities.write().update_from(&announcement);
|
||||||
|
|
||||||
// calculate reorg info and send packets
|
// calculate reorg info and send packets
|
||||||
for (peer_id, peer_info) in self.peers.write().iter_mut() {
|
for (peer_id, peer_info) in self.peers.read().iter() {
|
||||||
|
let mut peer_info = peer_info.lock();
|
||||||
let reorg_depth = reorgs_map.entry(peer_info.sent_head)
|
let reorg_depth = reorgs_map.entry(peer_info.sent_head)
|
||||||
.or_insert_with(|| {
|
.or_insert_with(|| {
|
||||||
match self.provider.reorg_depth(&announcement.head_hash, &peer_info.sent_head) {
|
match self.provider.reorg_depth(&announcement.head_hash, &peer_info.sent_head) {
|
||||||
@ -354,15 +362,15 @@ impl LightProtocol {
|
|||||||
return Err(Error::WrongNetwork);
|
return Err(Error::WrongNetwork);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.peers.write().insert(*peer, Peer {
|
self.peers.write().insert(*peer, Mutex::new(Peer {
|
||||||
local_buffer: Mutex::new(self.flow_params.create_buffer()),
|
local_buffer: self.flow_params.create_buffer(),
|
||||||
remote_buffer: flow_params.create_buffer(),
|
remote_buffer: flow_params.create_buffer(),
|
||||||
current_asking: HashSet::new(),
|
current_asking: HashSet::new(),
|
||||||
status: status.clone(),
|
status: status.clone(),
|
||||||
capabilities: capabilities.clone(),
|
capabilities: capabilities.clone(),
|
||||||
remote_flow: flow_params,
|
remote_flow: flow_params,
|
||||||
sent_head: pending.sent_head,
|
sent_head: pending.sent_head,
|
||||||
});
|
}));
|
||||||
|
|
||||||
for handler in &self.handlers {
|
for handler in &self.handlers {
|
||||||
handler.on_connect(*peer, &status, &capabilities)
|
handler.on_connect(*peer, &status, &capabilities)
|
||||||
@ -379,13 +387,15 @@ impl LightProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let announcement = try!(status::parse_announcement(data));
|
let announcement = try!(status::parse_announcement(data));
|
||||||
let mut peers = self.peers.write();
|
let peers = self.peers.read();
|
||||||
|
|
||||||
let peer_info = match peers.get_mut(peer) {
|
let peer_info = match peers.get(peer) {
|
||||||
Some(info) => info,
|
Some(info) => info,
|
||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut peer_info = peer_info.lock();
|
||||||
|
|
||||||
// update status.
|
// update status.
|
||||||
{
|
{
|
||||||
// TODO: punish peer if they've moved backwards.
|
// TODO: punish peer if they've moved backwards.
|
||||||
@ -420,6 +430,8 @@ impl LightProtocol {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut peer = peer.lock();
|
||||||
|
|
||||||
let req_id: u64 = try!(data.val_at(0));
|
let req_id: u64 = try!(data.val_at(0));
|
||||||
|
|
||||||
let block = {
|
let block = {
|
||||||
@ -471,6 +483,7 @@ impl LightProtocol {
|
|||||||
return Ok(())
|
return Ok(())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
let mut peer = peer.lock();
|
||||||
|
|
||||||
let req_id: u64 = try!(data.val_at(0));
|
let req_id: u64 = try!(data.val_at(0));
|
||||||
|
|
||||||
@ -516,6 +529,7 @@ impl LightProtocol {
|
|||||||
return Ok(())
|
return Ok(())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
let mut peer = peer.lock();
|
||||||
|
|
||||||
let req_id: u64 = try!(data.val_at(0));
|
let req_id: u64 = try!(data.val_at(0));
|
||||||
|
|
||||||
@ -561,6 +575,7 @@ impl LightProtocol {
|
|||||||
return Ok(())
|
return Ok(())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
let mut peer = peer.lock();
|
||||||
|
|
||||||
let req_id: u64 = try!(data.val_at(0));
|
let req_id: u64 = try!(data.val_at(0));
|
||||||
|
|
||||||
@ -617,6 +632,7 @@ impl LightProtocol {
|
|||||||
return Ok(())
|
return Ok(())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
let mut peer = peer.lock();
|
||||||
|
|
||||||
let req_id: u64 = try!(data.val_at(0));
|
let req_id: u64 = try!(data.val_at(0));
|
||||||
|
|
||||||
@ -671,6 +687,7 @@ impl LightProtocol {
|
|||||||
return Ok(())
|
return Ok(())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
let mut peer = peer.lock();
|
||||||
|
|
||||||
let req_id: u64 = try!(data.val_at(0));
|
let req_id: u64 = try!(data.val_at(0));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user