-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
Interchangable PrivKey implementations in keybase #5278
Conversation
Thanks @austinabell! Unfortunately, odds are we won't have any time in the near future to review this in-depth. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @austinabell! Minor comments only.
client/keys/add.go
Outdated
return err | ||
} | ||
|
||
return RunAddCmd(cmd, args, kb) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this looks odd. Shouldn't a public function call a private one instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I agree, the rationale was that I did not want to require an application to duplicate all of the command logic just to add options to the keybase. Ideally I would have liked to restructure the flow of this command, to split the logic into generating the key bytes from the command parameters and saving the key, so that instead of options passed to the keybase, the key type that is saved could just be defined in the command. I didn't want to make breaking changes though, so I will try to think of a better way of doing this without making breaking changes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see and appreciate the rationale, though I'm not convinced about the implementation. I like see a suboptimal design flow better than a potentially broken one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I'm sorry, I missed this comment. I'll explain what I meant by a different flow by some vague pseudocode and hopefully this will be sufficient to get the point across:
currently the code vaguely does:
addcommand() {
info ... = kb.CreateAccount(...)
}
...) CreateAccount(..) {
...
derivedBz = ComputeDerivedKey(seed,...)
writeKey(...derivedBz)
}
Where it would be more ideal to pass the bytes back to the addcommand to be able to derive whatever implementation there instead of having to add keybase options to do this deep in the function calls. It doesn't make much sense to me why the key is derived and written all in one flow anyway. This would have removed the need for this PR altogether because I could have just overriden the add command and been done with it. Example in pseudo:
addcommand() {
derivedBz = ComputeDerivedKey(...)
writeKey(...derivedBz)
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is very nice indeed, thanks!
Changes in the Keybase on ongoing, so I think this could be merged after #5180 is merged first.
I'll review this in-depth ASAP anyway, thanks!
Awesome, yeah I had noticed that which is why I was trying to delay making a PR but I opened anyway now since it would be beneficial for Ethermint to migrate back to the Cosmos keybase. Now that I know you guys are open to this I will see how I can make the changes work with your changes and clean up the PR after this has been merged in :) |
After that PR is merged and you guys get a chance to rereview, let me know if you want me to unseal and not change the codecs to be public, something like: ChainSafe@f5e01d4 I don't think there is another option other than just allowing new types to be registered or overwriting the module codecs unless there are other changes. One idea I did have is to possibly attach the additional account and key types to the module manager and just regenerate the codec with the types that the module manages. For example: the genutil module codec requires any new key types to be registered where the auth module codec requires new key types and account types to be registered in it's codec. So what my proposition is to add a function to regenerate the module codecs with the new registered types, and use types added to the module manager to update the necessary codecs and reseal them if necessary. The reason this would be useful is for a developer it is unknown which modules require which types to be registered, and is not clear how to update (if even possible). for example, with these changes in Ethermint, the module codecs have to be updated individually:
and possibly more will be needed once other modules are tested. Another option would be to have a crypto codec that can be modified and resealed that is referenced by all modules, instead of referencing the tendermint amino codec (where this cannot be updated as a dependency). |
48600d8
to
d378296
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Pending a Changelog entry and minor godoc changes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good progress so far! Few things need to be addressed. Would you @austinabell mind to open a PR in cosmos/gaia to test these gaia
aganst these changes please?
There are no changes required for Gaia? I'm confused about what you mean specifically Edit: do you just mean a PR with just replacing the Cosmos-sdk dependency with this commit? |
@austinabell dixit:
Exactly. We need to run gaia integration test suites against this. |
crypto/keys/types.go
Outdated
@@ -4,6 +4,7 @@ import ( | |||
"fmt" | |||
|
|||
"github.com/tendermint/tendermint/crypto" | |||
tmcrypto "github.com/tendermint/tendermint/crypto" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is already imported, see the preceding line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is not yet resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Few suggestions
…to austin/kbsigning
Just last bit: can you please drop an example somewhere as per #5278 (comment)? |
Okay I was somewhat confused by this, because I assumed all logic for this is tested in the test I added, and these tests are testing usually printable data, the edit: also sorry I missed your comment before, I responded: #5278 (comment) |
@austinabell I meant something like the following to illustrate the usage of the function by example: diff --git a/crypto/keys/keybase_test.go b/crypto/keys/keybase_test.go
index 2d4752fe3..7fd744c3b 100644
--- a/crypto/keys/keybase_test.go
+++ b/crypto/keys/keybase_test.go
@@ -7,6 +7,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+ "github.com/tendermint/tendermint/crypto/secp256k1"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519"
@@ -401,7 +402,8 @@ func TestSeedPhrase(t *testing.T) {
func ExampleNew() {
// Select the encryption and storage for your cryptostore
- cstore := NewInMemory()
+ customKeyGenFunc := func(bz [32]byte) crypto.PrivKey { return secp256k1.PrivKeySecp256k1(bz) }
+ cstore := NewInMemory(WithKeygenFunc(customKeyGenFunc))
sec := Secp256k1
However, it's not a blocker |
Assumed that would be confusing, since it makes it look like it is a required parameter in the example, but will commit this change |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nihil obstat from me - pending CI
Thanks!
Codecov Report
@@ Coverage Diff @@
## master #5278 +/- ##
==========================================
+ Coverage 54.53% 54.55% +0.02%
==========================================
Files 311 311
Lines 18740 18756 +16
==========================================
+ Hits 10219 10233 +14
- Misses 7741 7744 +3
+ Partials 780 779 -1
|
Allow for the keybase to be configured to override the implementation of the key that is saved to the keybase. Closes: cosmos#4941
closes: #4941
This PR allows for the keybase to be configured to override the implementation of the key that is saved to the keybase. I made this PR to be non-breaking changes and as unintrusive as possible, but can structure it differently or suggest different ways of going about this if you are open to these kinds of changes.
Summary of what this changes:
The other part of this is the key signing, which the only change is overriding the codec in Tendermint used for decoding a private key from bytes, change I made was this. After the key is decoded it simply uses the Sign function of the tendermint PrivKey interface
Let me know if you guys are open to these changes and I can clean up the PR and do necessary documentation. I will try to think of a better way to modify the codecs being referenced without exposing them publicly.
Here is an example of the keys commands being used with the overriden add command to use the keybase options. Here is the key type that is being saved, and it is usable because it satisfies the tendermint PrivKey interface. Here is the PR in ethermint that uses these changes but the main utility of these changes is to be able to override the addressing and signing of the existing secp256k1 curve, but does not solve the issue of allowing multiple curves.
docs/
)Unreleased
section inCHANGELOG.md
Files changed
in the github PR explorerFor Admin Use: