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

Missing blocks in filter_changes RPC #9947

Merged
merged 4 commits into from
Nov 21, 2018

Conversation

mattrutherford
Copy link
Contributor

Fixes: #9858

Implement validity check of reported hashes (in case of re-org)
to determine the last block reported that is still valid. This will return hashes for
block numbers that have previously been reported if the hash is different.

Add const to set history length for validity check. Currently set to 32 blocks.

Implement fix for missing blocks due to suspected bug when
block_hash(id) returned None, latest_block was still set at id.

Also implement validity check of reported hashes (in case of re-org)
and re-set last_block to the last block reported that is still valid.

Add const to set history size for validity check.
@parity-cla-bot
Copy link

It looks like @mattrutherford signed our Contributor License Agreement. 👍

Many thanks,

Parity Technologies CLA Bot

@mattrutherford mattrutherford added the A0-pleasereview 🤓 Pull request needs code review. label Nov 20, 2018
// in the case of a re-org we get same block number if hash is different - BlockId::Number(2)
tester.client.blocks.write().remove(&hash2).unwrap();
tester.client.numbers.write().remove(&2).unwrap();
tester.client.numbers.write().insert(1, hash2);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems that this line is actually changing hash of block1, why isn't that block part of the response?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, that would be the case if the hash was different, but actually in import_block() in test_client.rs, that value gets overwritten again by the old hash! So I just need to take that line out because it effectively does nothing.

@tomusdrw tomusdrw added the M6-rpcapi 📣 RPC API. label Nov 21, 2018
@tomusdrw tomusdrw added A8-looksgood 🦄 Pull request is reviewed well. and removed A0-pleasereview 🤓 Pull request needs code review. labels Nov 21, 2018
Copy link
Contributor

@andresilva andresilva left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current implementation LGTM, but I think we could also implement this by just storing (last_reported_number, last_reported_hash). We can calculate the tree_route between the current best block and the last reported block. If there's no re-org then last_reported_hash is an ancestor of best_block_hash, so tree_route(last, best).ancestor == last (and index should be 0). If there was a re-org then tree route will get us the common ancestor between the forks and we need to push to the client the route from common ancestor until best block. There's also the case where tree_route might return None if one of the provided hashes doesn't exist in the db, I'm not sure what to do in this case (just send everything from last_reported_block_number until best_block_number? Or from last_reported_block_number - 32?).

@mattrutherford
Copy link
Contributor Author

mattrutherford commented Nov 21, 2018

OK, thanks for the comments @andresilva . I like the elegant solution you mentioned, but depends in practice on how often a re-org would exceed 1 block; and if so whether duplicating returned hashes would be less less nice from an end-user perspective? Personally I think on balance I would prefer to keep as it is, but I am open to re-working it, if it's deemed the additional overhead is undesirable?

@andresilva
Copy link
Contributor

@mattrutherford I think assuming re-orgs are smaller than 32 blocks both methods would return the same results, the common ancestor found by tree_route would also be the same block we find when searching in recent_reported_hashes. The case where tree_route returns None shouldn't happen because both blocks should exist on the database (since we've seen it before) and we don't prune blocks on re-orgs. Either way I'm OK with the current solution, we can log this as an improvement.

@mattrutherford
Copy link
Contributor Author

OK, noted, thanks. I notice that tree_root also includes forked blocks so we'd need to remove those if we care about duplication of the returned hashes.

@mattrutherford mattrutherford merged commit 03600dc into master Nov 21, 2018
@andresilva
Copy link
Contributor

Ah, I see what you mean, indeed if there was a re-org tree_route would also report the retracted route. In this case we would just ignore the retracted part of the route, this method would be more useful if we could notify about previously reported blocks that were retracted (we do this for logs) but the API doesn't allow this right now and we can't break compatibility.

@mattrutherford
Copy link
Contributor Author

mattrutherford commented Nov 21, 2018

I guess we could also rename tree_root, add the extra param and functionality and then make a new fn tree_root(&self, from: H256, to: H256) that basically just calls the modified fn.

@ordian ordian deleted the mr-9858-pollfilter-block-changes branch November 22, 2018 08:54
@ordian ordian added this to the 2.3 milestone Nov 22, 2018
@ankitchiplunkar
Copy link

Thanks a lot guys, this is great!
When can I test the improved functionality?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A8-looksgood 🦄 Pull request is reviewed well. M6-rpcapi 📣 RPC API.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants