-
Notifications
You must be signed in to change notification settings - Fork 12
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
custom key types #1254
custom key types #1254
Conversation
This needs a lot more polish in some particularly rough spots, and there are now conflicts with |
cmd/kwil-cli/cmds/account/balance.go
Outdated
typeStr = args[1] | ||
keyType := crypto.KeyTypeSecp256k1 | ||
if len(args) > 1 { | ||
// keyType, err = authExt.ParseKeyType(args[1]) // ok to use extns in here? |
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 think you came to this conclusion / it is now a non-issue, but probably not ok to use exts here since it is kwil-cli
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'm not actually sure why anymore though. Should we strive to keep a vanilla kwil-cli
build workable for all kwild chains no matter what extensions are used on the nodes? i.e. use strings and other POD types in the client and simply let node interpret based on its own extension-based capabilities?
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.
That's been the approach so far. I see two good options:
- We keep a vanilla
kwil-cli
that works with any extended node - We allow
kwil-cli
to access extensions, and we bundlekwil-cli
,kwil-admin
, andkwild
.
So far, it seems like keeping a vanilla kwil-cli
is fine though. There are two places where it gets awkward and extensions don't work:
- If someone wants to use a custom key type, they cannot (IMO seems like nbd)
- If somebody wants to use a precompile within their tests (idOS ran into this, I have another solution I am kicking around though)
Will have to just incrementally review b/c I cannot partake in discussion and review at the same time (Github doesn't allow you) |
fd78975
to
6437169
Compare
Minimal PoC:
|
b643ba9
to
c74e8b8
Compare
Apologies, I got caught up in an insane amount of bugs and required fixes for what seemed like it would've been the last .1% of a PR. Getting to this now, will get a review tonight |
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.
Aside from a few comments lgtm
core/crypto/keytype.go
Outdated
) | ||
|
||
// KeyType is the type of key, which may be public or private depending on context. | ||
type KeyType string // uint32 |
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.
seems like the // uint32
comment is not relevant anymore
cmd/kwil-cli/cmds/account/balance.go
Outdated
typeStr = crypto.KeyTypeSecp256k1.String() | ||
} else { | ||
typeStr = args[1] | ||
keyType := crypto.KeyTypeSecp256k1 |
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.
Might be worth handling in another PR, and I know we've already discussed this, but we need to be able to recognize 0x
addresses for balance
, transfer
, account
, etc.
Also, do you think key type should be a flag? Not super strongly held, just feel like it maybe makes more sense because it is optional. (I know it was added in a previous PR, just thought I'd bring it up before people get their hands on it b/c it was not in v0.9)
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.
Indeed. Done.
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.
Also, do you think key type should be a flag? Not super strongly held, just feel like it maybe makes more sense because it is optional. (I know it was added in a previous PR, just thought I'd bring it up before people get their hands on it b/c it was not in v0.9)
Ah, on this for some reason an optional arg felt better. I do think that required inputs should be args not flags, but the reverse for optional inputs being flags isn't typically my rule. It could create difficulty though if we end up adding a second required arg, so I'll change it to a flag to future proof.
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.
Also special-cased the output of the account balance
command:
0xDC18F4993e93b50486e3e54e27d91D57cEE1dA07 (Ethereum secp256k1)
Balance: 0
Nonce: 0
Otherwise it is the hex compact id with keytype as usual.
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 lord I forgot that we have a nil accountID set from the get account RPC response if the account isn't found. Adjusted... b06239c
// correspond to crypto.KeyTypeSecp256k1. This information is important to | ||
// determine the key type of a transaction Sender from the AuthType in the | ||
// signature. | ||
KeyType() crypto.KeyType |
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 noticed that this Authenticator
interface in core/crypto/auth
is only ever referenced in core within tests. Do you think we should move this to the main module?
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 observation. I think it could. Will check to see if there's a coupling between Signer and Authenticator that might prevent this.
} | ||
|
||
return authn.Verify(tx.Sender, msg, tx.Signature.Data) | ||
} |
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.
Doesn't really matter, but you have a function in the authExt
package that wraps these:
func verifyTransaction(tx *types.Transaction) error {
msg, err := tx.SerializeMsg()
if err != nil {
return err
}
return authExt.VerifySignature(tx.Sender, msg, tx.Signature)
}
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 was over-optimizing here probably. Wanted to skip the SerializeMsg
if there was no authenticator found. Will just use the helper.
b06239c
to
40c210b
Compare
There is now a type core/crypto.KeyDefinition that is registered with core/crypto.RegisterKeyType. An arbitrary external key type can be supported with basic capabilities defined, including unmarshal/generate/type. The main purpose is to recognize key types in various config, DBs, and network comms, and provide the ability to unmarshal and create these keys. type KeyDefinition interface { Type() KeyType // name of key type e.g. "secp256k1" EncodeFlag() uint32 // prefix for compact unique binary encoding UnmarshalPrivateKey(b []byte) (PrivateKey, error) UnmarshalPublicKey(b []byte) (PublicKey, error) Generate() PrivateKey } The package level core/crypto.UnmarshalPrivateKey (and one for public) dispatch to the registered implementation based on KeyType. Note that the interfaces PrivateKey and PublicKey include the crypto.Key interface, which has its own marshal method (Bytes()). KeyType is a string now to make it self describing since we can't really have methods like Valid and String anymore now that the key type registry is not in core. Regarding the weird new EncodeFlag, this is for node internal use to make compact serializations. See core/crypto.WireEncodeKey etc. It seemed silly to encode a string key type in non-user-facing places like storage, network transmission, hashing, etc. So this does create a second value that must be unique to register, but I don't think it's a problem. permit eth address in account balance,transfer commands eth addr in account balance output
There is now a type
core/crypto.KeyDefinition
that is registered with core/crypto.RegisterKeyType`. An arbitrary external key type can be supported with basic capabilities defined, including unmarshal/generate/type. The main purpose is to recognize key types in various config, DBs, and network comms, and provide the ability to unmarshal and create these keys.The package level
core/crypto.UnmarshalPrivateKey
(and one for public) dispatch to the registered implementation based onKeyType
. Note that the interfacesPrivateKey
andPublicKey
include thecrypto.Key
interface, which has its own marshal method (Bytes()
).KeyType
is a string now to make it self describing since we can't really have methods likeValid
andString
anymore now that the key type registry is not incore
.Regarding the weird new
EncodeFlag
, this is for node internal use to make compact serializations. Seecore/crypto.WireEncodeKey
etc. Its seemed silly to encode a string key type in non-user-facing places like storage, network transmission, hashing, etc. So this does create a second value that must be unique to register, but I don't think it's a problem.