Back-references for the on-demand service (#5573)

* header back-references for on demand

* initial back-reference implementation for on demand requests

* answer requests from cache

* answer requests from cache, add tests

* strongly typed responses for vectors of homogeneous requests

* fix fallout in RPC without optimizing
This commit is contained in:
Robert Habermeier
2017-05-23 06:39:25 -04:00
committed by Arkadiy Paronyan
parent aa41b48ba0
commit 386cdb830d
9 changed files with 778 additions and 426 deletions

View File

@@ -27,7 +27,7 @@ use light::client::Client;
use light::on_demand::{request, OnDemand};
use light::TransactionQueue;
use futures::{future, stream, Future, Stream};
use futures::{future, Future};
use parity_reactor::Remote;
@@ -73,28 +73,32 @@ impl IoHandler<ClientIoMessage> for QueueCull {
self.remote.spawn_with_timeout(move || {
let maybe_fetching = sync.with_context(move |ctx| {
// fetch the nonce of each sender in the queue.
let nonce_futures = senders.iter()
.map(|&address| request::Account { header: best_header.clone(), address: address })
.map(move |request| {
on_demand.account(ctx, request)
.map(move |maybe_acc| maybe_acc.map_or(start_nonce, |acc| acc.nonce))
})
.zip(senders.iter())
.map(|(fut, &addr)| fut.map(move |nonce| (addr, nonce)));
let nonce_reqs = senders.iter()
.map(|&address| request::Account { header: best_header.clone().into(), address: address })
.collect::<Vec<_>>();
// as they come in, update each sender to the new nonce.
stream::futures_unordered(nonce_futures)
.fold(txq, |txq, (address, nonce)| {
txq.write().cull(address, nonce);
future::ok(txq)
// when they come in, update each sender to the new nonce.
on_demand.request(ctx, nonce_reqs)
.expect("No back-references; therefore all back-references are valid; qed")
.map(move |accs| {
let txq = txq.write();
let _ = accs.into_iter()
.map(|maybe_acc| maybe_acc.map_or(start_nonce, |acc| acc.nonce))
.zip(senders)
.fold(txq, |mut txq, (nonce, addr)| {
txq.cull(addr, nonce);
txq
});
})
.map(|_| ()) // finally, discard the txq handle and log errors.
.map_err(|_| debug!(target: "cull", "OnDemand prematurely closed channel."))
});
match maybe_fetching {
Some(fut) => fut.boxed(),
None => future::ok(()).boxed(),
None => {
debug!(target: "cull", "Unable to acquire network context; qed");
future::ok(()).boxed()
}
}
}, Duration::from_millis(PURGE_TIMEOUT_MS), || {})
}