Light client improvements (#6156)

* no seal checking

* import command and --no-seal-check for light client

* fix eth_call

* tweak registry dapps lookup

* ignore failed requests to non-server peers
This commit is contained in:
Robert Habermeier
2017-07-27 13:50:12 +02:00
committed by Arkadiy Paronyan
parent 5eb8cea6e7
commit 70ef33f6fe
8 changed files with 281 additions and 41 deletions

View File

@@ -54,13 +54,21 @@ struct Peer {
}
impl Peer {
// whether this peer can fulfill the
fn can_fulfill(&self, c: &Capabilities) -> bool {
let caps = &self.capabilities;
// whether this peer can fulfill the necessary capabilities for the given
// request.
fn can_fulfill(&self, request: &Capabilities) -> bool {
let local_caps = &self.capabilities;
let can_serve_since = |req, local| {
match (req, local) {
(Some(request_block), Some(serve_since)) => request_block >= serve_since,
(Some(_), None) => false,
(None, _) => true,
}
};
caps.serve_headers == c.serve_headers &&
caps.serve_chain_since >= c.serve_chain_since &&
caps.serve_state_since >= c.serve_chain_since
local_caps.serve_headers >= request.serve_headers &&
can_serve_since(request.serve_chain_since, local_caps.serve_chain_since) &&
can_serve_since(request.serve_state_since, local_caps.serve_state_since)
}
}
@@ -244,7 +252,7 @@ impl OnDemand {
peers: RwLock::new(HashMap::new()),
in_transit: RwLock::new(HashMap::new()),
cache: cache,
no_immediate_dispatch: true,
no_immediate_dispatch: false,
}
}
@@ -266,7 +274,6 @@ impl OnDemand {
-> Result<Receiver<Vec<Response>>, basic_request::NoSuchOutput>
{
let (sender, receiver) = oneshot::channel();
if requests.is_empty() {
assert!(sender.send(Vec::new()).is_ok(), "receiver still in scope; qed");
return Ok(receiver);
@@ -335,6 +342,7 @@ impl OnDemand {
// dispatch pending requests, and discard those for which the corresponding
// receiver has been dropped.
fn dispatch_pending(&self, ctx: &BasicContext) {
// wrapper future for calling `poll_cancel` on our `Senders` to preserve
// the invariant that it's always within a task.
struct CheckHangup<'a, T: 'a>(&'a mut Sender<T>);
@@ -360,6 +368,8 @@ impl OnDemand {
if self.pending.read().is_empty() { return }
let mut pending = self.pending.write();
debug!(target: "on_demand", "Attempting to dispatch {} pending requests", pending.len());
// iterate over all pending requests, and check them for hang-up.
// then, try and find a peer who can serve it.
let peers = self.peers.read();
@@ -378,16 +388,21 @@ impl OnDemand {
match ctx.request_from(*peer_id, pending.net_requests.clone()) {
Ok(req_id) => {
trace!(target: "on_demand", "Dispatched request {} to peer {}", req_id, peer_id);
self.in_transit.write().insert(req_id, pending);
return None
}
Err(net::Error::NoCredits) => {}
Err(net::Error::NoCredits) | Err(net::Error::NotServer) => {}
Err(e) => debug!(target: "on_demand", "Error dispatching request to peer: {}", e),
}
}
// TODO: maximum number of failures _when we have peers_.
Some(pending)
})
.collect(); // `pending` now contains all requests we couldn't dispatch.
debug!(target: "on_demand", "Was unable to dispatch {} requests.", pending.len());
}
// submit a pending request set. attempts to answer from cache before
@@ -395,6 +410,7 @@ impl OnDemand {
fn submit_pending(&self, ctx: &BasicContext, mut pending: Pending) {
// answer as many requests from cache as we can, and schedule for dispatch
// if incomplete.
pending.answer_from_cache(&*self.cache);
if let Some(mut pending) = pending.try_complete() {
pending.update_net_requests();