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

Add Ethereum secp keys to validators #471

Merged
merged 48 commits into from
Oct 13, 2022

Conversation

sug0
Copy link
Contributor

@sug0 sug0 commented Sep 15, 2022

Finalizes the implementation of the 8th item of issue no. #242

This PR adds Ethereum secp keys to genesis validators, and also finalizes the validation code for valset upd vote extensions.

We integrate changes from #371


Missing in this PR: Proof-of-stake VP changes, centered around verifying Ethereum secp keys in storage. This can be addressed in a future PR.

tzemanovic and others added 30 commits September 12, 2022 16:12
@sug0 sug0 marked this pull request as ready for review September 16, 2022 09:41
@sug0
Copy link
Contributor Author

sug0 commented Sep 16, 2022

still missing some VP stuff, will make this a draft PR again

@sug0 sug0 marked this pull request as draft September 16, 2022 09:46
@sug0
Copy link
Contributor Author

sug0 commented Sep 20, 2022

@james-chf feel free to leave a review, if you have time. what's blocking this PR right now are some changes to VPs, which will unify the native and wasm interfaces #318. after that is more or less done, in main, me/tomas/brent can implement the remaining stuff for the ledger secp keys pr #371, which is being tracked here as well. the remaining changes will be around the PoS VP, to verify eth secp keys.

@sug0 sug0 marked this pull request as ready for review September 21, 2022 09:48
@james-chf
Copy link
Contributor

This PR has code from another PR + some new Ethereum-bridge specific logic, this would be easier to review in separate stacked PRs (though not worth splitting out now)

I can't test this locally yet as I need to update my way of generating a devchain to work with the new Tendermint v0.38.x, but I'll do that soon. Then I can test this altogether (maybe after it has merged to eth-bridge-integration), still have a couple more things to look at on this PR

&mut self,
address: &Self::Address,
value: &types::ValidatorEthKey<Self::PublicKey>,
) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I realize the rest of the API is similar to this currently, but it'd be good to return a Result type rather than .unwrap()ping, since self.write can error

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah this is more of a general issue outside of this PR, idk if @tzemanovic wants to pitch in on this

Copy link
Member

Choose a reason for hiding this comment

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

In general, yes agree that it'd be better. We didn't worry about this too much for now in here as this is inside PosBase and these methods are only used by the protocol to init chain. If we return an error from, it would still crash further up the stack - the API of PoS crate could do some bigger refactors in general, but for now it's not a high priority

Comment on lines +420 to +435
fn read_validator_eth_cold_key(
&self,
key: &Self::Address,
) -> Option<types::ValidatorEthKey<Self::PublicKey>> {
let value =
self.ctx.read_pre(&validator_eth_cold_key_key(key)).unwrap();
value.map(|value| decode(value).unwrap())
}

fn read_validator_eth_hot_key(
&self,
key: &Self::Address,
) -> Option<types::ValidatorEthKey<Self::PublicKey>> {
let value = self.ctx.read_pre(&validator_eth_hot_key_key(key)).unwrap();
value.map(|value| decode(value).unwrap())
}
Copy link
Contributor

Choose a reason for hiding this comment

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

When should we expect read_validator_eth_cold_key/read_validator_eth_hot_key to return None instead of Some(...)? It feels like this API could directly return a ValidatorEthKey<Self::PublicKey> (or better, Result<ValidatorEthKey<Self::PublicKey>>), if it's the case that all validators must have Eth keys going forwards

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it can happen if we are a fullnode, for instance

Copy link
Contributor

Choose a reason for hiding this comment

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

Even for a full node, we are reading the validator's key from blockchain state (self.ctx.read_pre) when executing this VP, so these two funcs should work the same for full nodes and validators? I guess returning an Option here follows the pattern of other methods here for the time being

Copy link
Member

Choose a reason for hiding this comment

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

at type level key: &Self::Address can be any address, so this would be None if the given address is not a validator address. If we know we're calling it with validator addresses only, we can expect that those are always Some

Comment on lines +108 to +112
impl
namada_proof_of_stake::types::TryRefTo<
namada_proof_of_stake::types::EthAddress,
> for common::PublicKey
{
Copy link
Contributor

Choose a reason for hiding this comment

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

How come we have this TryRefTo trait (impl TryRefTo<T> for U)? It looks like it's trying to achieve the same thing as impl TryInto<U> for &T which would be more standard, couldn't we use that?

Copy link
Contributor Author

@sug0 sug0 Sep 27, 2022

Choose a reason for hiding this comment

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

me and tomas had a whole coding session where we tried (and successfully!) managed to implement TryFrom, but the code in the proof_of_stake crate looked hideous and unmaintainable with it, because of lifetime issues with references. in short, it's not worth using TryInto.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

pretty sure this is the same reason why we have a RefTo trait lying around

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah interesting, it'd be nice if we could use TryInto but I haven't see what the code looks like with using that, if it means lifetimes everywhere

Copy link
Member

Choose a reason for hiding this comment

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

yeah, we had to specify pretty funky bounds on the PoS traits that use an associated types for the public key to get it to work, so this was actually lot cleaner

Copy link
Member

Choose a reason for hiding this comment

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

still, same as the other thing, the way PoS traits are implemented could use a bigger refactor that would alleviate this

@@ -287,16 +289,28 @@ impl Store {
///
/// Note that this removes the validator data.
pub fn gen_validator_keys(
eth_bridge_keypair: Option<common::SecretKey>,
Copy link
Contributor

Choose a reason for hiding this comment

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

This ultimately needs to be a namada::types::key::secp256k1::SecretKey, we should refactor at some point to accept namada::types::key::secp256k1::SecretKey rather than common::SecretKey. In general, I think we have places where we are using common::{SecretKey, PublicKey} where we should be constraining to the a more specific type (as not all schemes make sense)? We should only use those enum types where the function can or should accept both imo

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah agreed. it forces you to return Option or Return types, which makes APIs more convoluted to use in the end.

Comment on lines +626 to +630
fn get_ethbridge_from_namada_addr(
&self,
validator: &Address,
epoch: Option<Epoch>,
) -> Option<EthAddress> {
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be clearer to return a Result here instead of Option - it looks like we return None in the case where read_validator_eth_hot_key returns None, so it sort of goes back to that. Would we ever expect this to return None, or would that indicate an error?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

same issue as above, it can return None if we are a fullnode.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

like we discussed in our call, the Shell<...> should take an extra parameterNodeTag to distinguish between different node kinds, and only implement methods like prepare_proposal e.g. if we are a NodeTag = Validator. this would also obviate the need to error out from methods like get_ethbridge_from_namada_addr, unless we actually got some storage reading error.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah that sounds like a good approach, have opened #521

Copy link
Contributor

@james-chf james-chf left a comment

Choose a reason for hiding this comment

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

lgtm to merge!

@Fraccaman Fraccaman force-pushed the eth-bridge-integration branch 2 times, most recently from 8d7b66f to c285b74 Compare October 6, 2022 10:49
@sug0
Copy link
Contributor Author

sug0 commented Oct 13, 2022

pls update wasm

@sug0 sug0 merged commit 9abe316 into eth-bridge-integration Oct 13, 2022
@sug0 sug0 deleted the tiago/ethbridge/ledger-secp-keys branch October 13, 2022 08:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants