From fcb6cc1e767efa813f8d2f8c77682ee62a3edeec Mon Sep 17 00:00:00 2001 From: cheme Date: Tue, 14 Aug 2018 09:58:29 +0200 Subject: [PATCH] Light client logs should include 'from_block' when querying logs (#9331) * Fix PubSub for logs when using light client : prior to this fix the pubsub process did send a query for each new block header (and for each subs : there is something to optimize here) by setting from and to of the filter at this block number; but there was a bug in the code that fetch logs : it was non inclusive for its start bound, meaning that with start bound = end bound we never query any block (and attached logs). * Option iter instead of once. Use of bloom existing function to check if a bloom contains another. * Makes from block header checking explicit --- rpc/src/v1/helpers/light_fetch.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/rpc/src/v1/helpers/light_fetch.rs b/rpc/src/v1/helpers/light_fetch.rs index 1da2fdf1a..c63591caf 100644 --- a/rpc/src/v1/helpers/light_fetch.rs +++ b/rpc/src/v1/helpers/light_fetch.rs @@ -321,9 +321,15 @@ impl LightFetch { BlockId::Number(x) => Some(x), }; - match (block_number(filter.to_block), block_number(filter.from_block)) { - (Some(to), Some(from)) if to < from => return Either::A(future::ok(Vec::new())), - (Some(_), Some(_)) => {}, + let (from_block_number, from_block_header) = match self.client.block_header(filter.from_block) { + Some(from) => (from.number(), from), + None => return Either::A(future::err(errors::unknown_block())), + }; + + match block_number(filter.to_block) { + Some(to) if to < from_block_number || from_block_number > best_number + => return Either::A(future::ok(Vec::new())), + Some(_) => (), _ => return Either::A(future::err(errors::unknown_block())), } @@ -332,11 +338,11 @@ impl LightFetch { // match them with their numbers for easy sorting later. let bit_combos = filter.bloom_possibilities(); let receipts_futures: Vec<_> = self.client.ancestry_iter(filter.to_block) - .take_while(|ref hdr| BlockId::Number(hdr.number()) != filter.from_block) - .take_while(|ref hdr| BlockId::Hash(hdr.hash()) != filter.from_block) + .take_while(|ref hdr| hdr.number() != from_block_number) + .chain(Some(from_block_header)) .filter(|ref hdr| { let hdr_bloom = hdr.log_bloom(); - bit_combos.iter().find(|&bloom| hdr_bloom & *bloom == *bloom).is_some() + bit_combos.iter().any(|bloom| hdr_bloom.contains_bloom(bloom)) }) .map(|hdr| (hdr.number(), request::BlockReceipts(hdr.into()))) .map(|(num, req)| self.on_demand.request(ctx, req).expect(NO_INVALID_BACK_REFS).map(move |x| (num, x)))