Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Commit

Permalink
exclusive access to each peer at a time
Browse files Browse the repository at this point in the history
  • Loading branch information
rphmeier committed Nov 18, 2016
1 parent 4fd9670 commit 48df2e1
Showing 1 changed file with 38 additions and 21 deletions.
59 changes: 38 additions & 21 deletions ethcore/src/light/net/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ struct PendingPeer {

// data about each 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
current_asking: HashSet<usize>, // pending request ids.
status: Status,
Expand All @@ -112,21 +112,25 @@ impl Peer {
// check the maximum cost of a request, returning an error if there's
// not enough buffer left.
// returns the calculated maximum cost.
fn deduct_max(&self, flow_params: &FlowParams, kind: request::Kind, max: usize) -> Result<U256, Error> {
let mut local_buffer = self.local_buffer.lock();
flow_params.recharge(&mut local_buffer);
fn deduct_max(&mut self, flow_params: &FlowParams, kind: request::Kind, max: usize) -> Result<U256, Error> {
flow_params.recharge(&mut self.local_buffer);

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)
}

// refund buffer for a request. returns new buffer amount.
fn refund(&self, flow_params: &FlowParams, amount: U256) -> U256 {
let mut local_buffer = self.local_buffer.lock();
flow_params.refund(&mut local_buffer, amount);
fn refund(&mut self, flow_params: &FlowParams, amount: U256) -> U256 {
flow_params.refund(&mut self.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);
}
}

Expand Down Expand Up @@ -171,7 +175,7 @@ pub struct LightProtocol {
genesis_hash: H256,
network_id: NetworkId,
pending_peers: RwLock<HashMap<PeerId, PendingPeer>>,
peers: RwLock<HashMap<PeerId, Peer>>,
peers: RwLock<HashMap<PeerId, Mutex<Peer>>>,
pending_requests: RwLock<HashMap<usize, Requested>>,
capabilities: RwLock<Capabilities>,
flow_params: FlowParams, // assumed static and same for every peer.
Expand Down Expand Up @@ -199,8 +203,9 @@ impl LightProtocol {
/// Check the maximum amount of requests of a specific type
/// which a peer would be able to serve.
pub fn max_requests(&self, peer: PeerId, kind: request::Kind) -> Option<usize> {
self.peers.write().get_mut(&peer).map(|peer| {
peer.remote_flow.recharge(&mut peer.remote_buffer);
self.peers.read().get(&peer).map(|peer| {
let mut peer = peer.lock();
peer.recharge_remote();
peer.remote_flow.max_amount(&peer.remote_buffer, kind)
})
}
Expand All @@ -212,9 +217,11 @@ impl LightProtocol {
/// On success, returns a request id which can later be coordinated
/// with an event.
pub fn request_from(&self, io: &NetworkContext, peer_id: &PeerId, request: Request) -> Result<ReqId, Error> {
let mut peers = self.peers.write();
let peer = try!(peers.get_mut(peer_id).ok_or_else(|| Error::UnknownPeer));
peer.remote_flow.recharge(&mut peer.remote_buffer);
let peers = self.peers.read();
let peer = try!(peers.get(peer_id).ok_or_else(|| Error::UnknownPeer));
let mut peer = peer.lock();

peer.recharge_remote();

let max = peer.remote_flow.compute_cost(request.kind(), request.amount());
try!(peer.remote_buffer.deduct_cost(max));
Expand Down Expand Up @@ -251,7 +258,8 @@ impl LightProtocol {
self.capabilities.write().update_from(&announcement);

// 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)
.or_insert_with(|| {
match self.provider.reorg_depth(&announcement.head_hash, &peer_info.sent_head) {
Expand Down Expand Up @@ -354,15 +362,15 @@ impl LightProtocol {
return Err(Error::WrongNetwork);
}

self.peers.write().insert(*peer, Peer {
local_buffer: Mutex::new(self.flow_params.create_buffer()),
self.peers.write().insert(*peer, Mutex::new(Peer {
local_buffer: self.flow_params.create_buffer(),
remote_buffer: flow_params.create_buffer(),
current_asking: HashSet::new(),
status: status.clone(),
capabilities: capabilities.clone(),
remote_flow: flow_params,
sent_head: pending.sent_head,
});
}));

for handler in &self.handlers {
handler.on_connect(*peer, &status, &capabilities)
Expand All @@ -379,13 +387,15 @@ impl LightProtocol {
}

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,
None => return Ok(()),
};

let mut peer_info = peer_info.lock();

// update status.
{
// TODO: punish peer if they've moved backwards.
Expand Down Expand Up @@ -420,6 +430,8 @@ impl LightProtocol {
}
};

let mut peer = peer.lock();

let req_id: u64 = try!(data.val_at(0));

let block = {
Expand Down Expand Up @@ -471,6 +483,7 @@ impl LightProtocol {
return Ok(())
}
};
let mut peer = peer.lock();

let req_id: u64 = try!(data.val_at(0));

Expand Down Expand Up @@ -516,6 +529,7 @@ impl LightProtocol {
return Ok(())
}
};
let mut peer = peer.lock();

let req_id: u64 = try!(data.val_at(0));

Expand Down Expand Up @@ -561,6 +575,7 @@ impl LightProtocol {
return Ok(())
}
};
let mut peer = peer.lock();

let req_id: u64 = try!(data.val_at(0));

Expand Down Expand Up @@ -617,6 +632,7 @@ impl LightProtocol {
return Ok(())
}
};
let mut peer = peer.lock();

let req_id: u64 = try!(data.val_at(0));

Expand Down Expand Up @@ -671,6 +687,7 @@ impl LightProtocol {
return Ok(())
}
};
let mut peer = peer.lock();

let req_id: u64 = try!(data.val_at(0));

Expand Down

0 comments on commit 48df2e1

Please sign in to comment.