Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Light client: further trait impls, improvements, and tests #84

Merged
merged 32 commits into from
Dec 16, 2019

Conversation

liamsi
Copy link
Member

@liamsi liamsi commented Dec 10, 2019

Supersedes #63: clean-up the commit history and rebased the changes of #63 on master.

From #63's description:

ref #36

Update: Since this PR was opened (mostly to show the impact of #59), it grew to contain several further PRs added in by @yihuang (big thanks). These added 2 missing impls, resolved a few encoding edge cases and simple (json-based) tests.

Particularly:

Additionally this PR introduces a TrustLevel trait via bd26e74 and adds a verify method that is closer to the (current) spec / go-code in 017c1ba (with a few tests from JSON).

byteslices.push(self.app_hash.as_ref().map_or(vec![], encode_hash));
byteslices.push(self.last_results_hash.as_ref().map_or(vec![], encode_hash));
byteslices.push(self.evidence_hash.as_ref().map_or(vec![], encode_hash));
byteslices.push(bytes_enc(self.proposer_address.as_bytes()));

This comment was marked as resolved.

@liamsi
Copy link
Member Author

liamsi commented Dec 12, 2019

TODOs:

liamsi and others added 19 commits December 12, 2019 02:25
Further reduce boilerplate code by leveraging generics
 - SignedVote can now be constructed without going through CanoncialVote
   (which is an amino-type)
 - modify impl to match new constructor and remove amino dep
 - make explicit where which types are amino_types (in vote.rs)
lite::ValidatorSet:: & Set

- tests for  lite::ValidatorSetLookup lite::ValidatorSet impl
- delete `fn hash(self) -> merkle::Hash` from Set and only keep the impl
  of lite::ValidatorSet
and correctly compute header hash when block id is empty.

Represent empty Hash with Option
accept iff +1/3 of the voting power signed
…code (lite2) and

tests:

 - rename former verify method to verify_header_and_commit (might be obsolete)
 - make the expired method public to be able to use and test it from the outside
 - add some helpers to be able to deal with deserialization hickups
 - add a bunch of tests using @Shivani912's generator code (with minor modifications)
and some minor changes due to rebasing on master
tendermint/src/lite/verifier.rs Outdated Show resolved Hide resolved
tendermint/src/lite/verifier.rs Outdated Show resolved Hide resolved
run_test_cases(cases);
}

fn run_test_cases(cases: TestCases) {
Copy link
Member Author

Choose a reason for hiding this comment

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

- add a `voting_power_in` method to Commit trait
(corresponds to votingpower_in(V1, V1) auxiliary function of spec
- use above method to simplify `verify_commit_full` and `verify_commit_trusting`
- move validator(id) lookup method to ValidatorSet trait
- delete `ValidatorSetLookup` trait
- take references everywhere (instead of cloning)
- add a len() method the ValidatorSet trait
- add in an is_empty method to ValidatorSet; otherwise: `trait `ValidatorSet` has a `len` method but no (possibly inherited) `is_empty` method`
}
signed_power += val.power();
}
let signed_power = commit.voting_power_in(vals)?;
Copy link
Member Author

@liamsi liamsi Dec 12, 2019

Choose a reason for hiding this comment

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

@ancazamfir @ebuchman Does this work for you? I think it's closer to what is in the spec and should also be less confusing. It's used here and below in verify_commit_trusting (we do lookups in both cases now).

referencing related comments: #36 (comment)

see votingpower_in(V1,V2) function in spec: https://github.com/tendermint/spec/blob/4f7c55507cb99c35c7774c583f182859283f3017/spec/consensus/light-client.md#functions-1

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, it looks better imo.

 - they are not used in the abstract verifier logic; hence they
 do not need to be part of the trait anymore
/// and thus use an ternary enum here instead of the binary Option.
// TODO figure out if we want/can do an iter() method here that returns a
// VoteIterator instead of returning a vec
fn into_vec(&self) -> Vec<Option<Self::Vote>>;
Copy link
Member Author

Choose a reason for hiding this comment

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

The into_vec or any possibility to iterate over the underlying votes is not used in the abstract verifier code. The parts of the code that needed this is now moved into voting_power_in (see below). I think this makes the code more readable and closer to the spec.

@liamsi
Copy link
Member Author

liamsi commented Dec 12, 2019

I'd appreciate another pass of reviews here. I started working on putting this all together but it would be nice to merge this soon and continue with the remaining parts of the light client (on-top of these changes):

  • initial config for light client
  • requesting from multiple peers (networking)
  • storing state (memory, DB)
  • detecting misbehaviour, gossiping misbehaviour
  • bisection
  • creating command line tool (light client daemon)

"evidence_hash": "",
"proposer_address": "01F527D77D3FFCC4FCFF2DDC2952EEA5414F2A33"
},
"commit": null
Copy link
Member Author

@liamsi liamsi Dec 13, 2019

Choose a reason for hiding this comment

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

Currently, this (null commit) won't even parse correctly. (In the SignedHeader struct a commit isn't optional).

"input": [
{
"signed_header": {
"header": null,
Copy link
Member Author

Choose a reason for hiding this comment

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

Currently, this (null header) won't even parse correctly. (In the SignedHeader struct a header isn't optional).

Copy link
Member

Choose a reason for hiding this comment

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

@Shivani912 why do we even have a null header? Is there ever a case where the rpc would return this?

improve the readability of the abstract traits / verification logic
… instead) and

add method `CheckSupport` (see spec)
Copy link
Contributor

@ancazamfir ancazamfir left a comment

Choose a reason for hiding this comment

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

Looks good! A couple of comments on the verifier.rs. Slowly catching up on the others.

tendermint/src/lite/verifier.rs Show resolved Hide resolved
}
signed_power += val.power();
}
let signed_power = commit.voting_power_in(vals)?;
Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, it looks better imo.

 - delete `verify` add in a `verify` method that verifies a signed header
 - use check_support in the tests instead
 - add module documentation (see: cargo doc --open --no-deps)
 - make comment a todo to make it easier grepable
 - add in some feedback for shivani
ebuchman
ebuchman previously approved these changes Dec 16, 2019
Copy link
Member

@ebuchman ebuchman left a comment

Choose a reason for hiding this comment

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

Awesome work, thanks! Few minor points but I think we can probably merge and follow up in more PRs

tendermint/src/lite/types.rs Outdated Show resolved Hide resolved
tendermint/src/rpc/endpoint/commit.rs Outdated Show resolved Hide resolved
tendermint/src/rpc/endpoint/commit.rs Outdated Show resolved Hide resolved
tendermint/src/validator.rs Outdated Show resolved Hide resolved
// Then for tests this structure could be used for the skipping case too:
// The light client get's two such LiteBlocks (one with height h and one with height h-x)
// This gives more flexibility on how to compose the tests and can be used
// to mock both rpc endpoints too?
Copy link
Member

Choose a reason for hiding this comment

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

This is a good idea cc @Shivani912.

Don't we need to include the NextValidatorSet as well ? Even in bisection, we're verifying the commit against the current Validators, but setting the NextValidators as the trusted ones when checking support for a subsequent commit.

tendermint/src/lite/verifier.rs Show resolved Hide resolved
tendermint/src/lite/types.rs Show resolved Hide resolved
tendermint/src/lite/verifier.rs Show resolved Hide resolved
tendermint/src/lite/verifier.rs Outdated Show resolved Hide resolved
tendermint/src/lite/verifier.rs Show resolved Hide resolved
@liamsi liamsi mentioned this pull request Dec 16, 2019
17 tasks
@liamsi liamsi requested a review from ebuchman December 16, 2019 15:26
Copy link
Member

@ebuchman ebuchman left a comment

Choose a reason for hiding this comment

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

Awesome work thanks @liamsi and @yihuang !

@ebuchman ebuchman merged commit 0a621f6 into master Dec 16, 2019
@ebuchman ebuchman deleted the fix_lite_impl_merkle_merged branch December 16, 2019 17:55
@tarcieri tarcieri mentioned this pull request Dec 17, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants