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

R4R: Allow --from to be a name or an address #2073

Merged
merged 16 commits into from
Sep 25, 2018

Conversation

mslipper
Copy link
Contributor

@mslipper mslipper commented Aug 17, 2018

Closes #1735.

  • Linked to github-issue with discussion and accepted design OR link to spec that describes this work.
  • Updated all relevant documentation (docs/)
  • Updated all relevant code comments
  • Wrote tests
  • Added entries in PENDING.md that include links to the relevant issue or PR that most accurately describes the change.
  • Updated cmd/gaia and examples/

For Admin Use:

  • Added appropriate labels to PR (ex. wip, ready-for-review, docs)
  • Reviewers Assigned
  • Squashed all commits, uses message "Merge pull request #XYZ: [title]" (coding standards)

Copy link
Contributor

@alexanderbez alexanderbez left a comment

Choose a reason for hiding this comment

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

@mslipper great start, but it seems some logic may be incorrect? Also left some minors remarks. Also, please make sure CI passes too 👍

PENDING.md Outdated
@@ -61,6 +61,7 @@ FEATURES
* [core] added BaseApp.Seal - ability to seal baseapp parameters once they've been set
* [scripts] added log output monitoring to DataDog using Ansible scripts
* [gov] added TallyResult type that gets added stored in Proposal after tallying is finished
* [cli] --from can now be either an address or a key name
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you reference the PR here please @mslipper ?

@@ -84,7 +87,7 @@ func (ctx CLIContext) WithAccountStore(accountStore string) CLIContext {
// WithFromAddressName returns a copy of the context with an updated from
// address.
func (ctx CLIContext) WithFromAddressName(addrName string) CLIContext {
Copy link
Contributor

Choose a reason for hiding this comment

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

WithFrom*

return ctx.fromAddress, nil
}

func (ctx CLIContext) GetFromName() (string, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Missing godoc

client/context/query.go Show resolved Hide resolved
return ctx.fromName, nil
}

func (ctx CLIContext) populateFromFields() error {
Copy link
Contributor

Choose a reason for hiding this comment

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

Are you sure this logic is correct? I have not been able to get this to work (gaiacli send --from <addr1> --to <addr2> ...)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep - note that you'll have to create a new key for the correct data to appear in the database.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

To be clear: the way I've written it, an additional key (as in key-value store) is written to LevelDB to look up keys (as in private keys) by address. If that KV-store key doesn't exist, you won't be able to pass a public key in --from.

Copy link
Contributor

Choose a reason for hiding this comment

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

@mslipper I created a fresh local testnet, added all of my node's keys to a single node's key DB and still could not get this to work. I've tried with both recovered keys and with newly created keys.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Were you able to get it working @alexanderbez ? If you could post the command you're using and the error you get I can debug.

@alexanderbez alexanderbez changed the title Allow --from to be a name or an address WIP: Allow --from to be a name or an address Aug 17, 2018
@jackzampolin jackzampolin changed the title WIP: Allow --from to be a name or an address R4R: Allow --from to be a name or an address Aug 21, 2018
@@ -84,7 +87,7 @@ func (ctx CLIContext) WithAccountStore(accountStore string) CLIContext {
// WithFromAddressName returns a copy of the context with an updated from
// address.
func (ctx CLIContext) WithFromAddressName(addrName string) CLIContext {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we'd want to search for "FromAddressName" and replace them w/ "From" as well, like this method name.


var info cskeys.Info

if strings.HasPrefix(ctx.From, sdk.Bech32PrefixAccAddr) {
Copy link
Contributor

Choose a reason for hiding this comment

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

There's a conflict if the user enters a name that happens to be a Bech32 address, or one that starts with the Bech32PrefixAccAddr. A few thoughts:

  • Checking for the Bech32PrefixAccAddr prefix is not enough, we should also check for the "1" that follows, as per the bech32 spec.
  • Maybe we should just try parsing the address via sdk.AccAddressFromBech32 and assume it's an address if there's no error. (there's a checksum in bech32 so this should be enough).
  • And, maybe we should instead check on the add/new side and ensure that you can't enter a valid Bech32 address as a name.

@jackzampolin
Copy link
Member

Looks like a couple of changes here @mslipper

@mslipper
Copy link
Contributor Author

Yep I'm checking them out @jackzampolin.

@mslipper mslipper force-pushed the issue-1735 branch 2 times, most recently from 246ab1a to 564d259 Compare August 23, 2018 08:29
@alexanderbez
Copy link
Contributor

@mslipper mind rebasing using the latest develop to fix the broken test_sim_gaia_fast? Also, the test_cli is failing and I still cannot get this functionality to work for me locally?

@@ -14,6 +14,7 @@ import (
cmn "github.com/tendermint/tendermint/libs/common"
rpcclient "github.com/tendermint/tendermint/rpc/client"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
cskeys "github.com/cosmos/cosmos-sdk/crypto/keys"
Copy link
Contributor

Choose a reason for hiding this comment

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

formatting is off (use gofmt)

Copy link
Contributor

Choose a reason for hiding this comment

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

Formatting is still off here @mslipper

func (ctx CLIContext) WithFromAddressName(addrName string) CLIContext {
ctx.FromAddressName = addrName
// WithFrom returns a copy of the context with an updated from address.
func (ctx CLIContext) WithFrom(addrName string) CLIContext {
Copy link
Contributor

Choose a reason for hiding this comment

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

addrName -> from

// address.
func (ctx CLIContext) WithFromAddressName(addrName string) CLIContext {
ctx.FromAddressName = addrName
// WithFrom returns a copy of the context with an updated from address.
Copy link
Contributor

Choose a reason for hiding this comment

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

address or name

@@ -179,6 +180,12 @@ func (kb dbKeybase) List() ([]Info, error) {
iter := kb.db.Iterator(nil, nil)
defer iter.Close()
for ; iter.Valid(); iter.Next() {
key := string(iter.Key())

if strings.HasSuffix(key, ".address") {
Copy link
Contributor

Choose a reason for hiding this comment

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

this needs a comment IMHO

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd say if one needs to write code like ^^^, then something is wrong. Just a earlier warning to core devs.

Copy link
Contributor

Choose a reason for hiding this comment

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

++

@codecov
Copy link

codecov bot commented Aug 30, 2018

Codecov Report

Merging #2073 into develop will decrease coverage by 0.05%.
The diff coverage is 0%.

@@             Coverage Diff             @@
##           develop    #2073      +/-   ##
===========================================
- Coverage    64.97%   64.92%   -0.06%     
===========================================
  Files          135      135              
  Lines         8418     8425       +7     
===========================================
  Hits          5470     5470              
- Misses        2587     2594       +7     
  Partials       361      361

Copy link
Contributor

@alexanderbez alexanderbez left a comment

Choose a reason for hiding this comment

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

@mslipper I think we're almost there! Left a bit more feedback :-)

Also, integration_tests is failing. Wanna take a look at that?

@@ -14,6 +14,7 @@ import (
cmn "github.com/tendermint/tendermint/libs/common"
rpcclient "github.com/tendermint/tendermint/rpc/client"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
cskeys "github.com/cosmos/cosmos-sdk/crypto/keys"
Copy link
Contributor

Choose a reason for hiding this comment

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

Formatting is still off here @mslipper

return ctx.fromAddress, nil
}

// GetFromname returns the key name for the current context.
Copy link
Contributor

Choose a reason for hiding this comment

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

GetFromName*

}

return sdk.AccAddress(info.GetPubKey().Address()), nil
ctx.fromAddress = (sdk.AccAddress)(info.GetPubKey().Address())
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this equivalent to: sdk.AccAddress(info.GetPubKey().Address().Bytes())?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Correct. Both Address() and Bytes() return effectively a byte slice.

return cliCtx.EnsureBroadcastTx(txBytes)
}

func lookupTxCtx(txCtx authctx.TxContext, cliCtx context.CLIContext, from []byte) (*authctx.TxContext, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Where did this come from? I don't think we should be returning pointers to contexts. Is this from the original simulation PR @alessio ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Nvm, I don't see this on develop. I don't think lookupTxCtx is appropriate here. See prepareTxContext here. I think it should be analogous to that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Was trying to reduce the cyclomatic complexity of the function above - I can revert.

Copy link
Contributor

Choose a reason for hiding this comment

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

ohhh no, we should definitely reduce cyclomatic complexity! We just should:

  1. Not return a pointer
  2. Avoid a merge conflict cause @alessio's PR has something similar

That's all :-)

func (kb dbKeybase) GetByAddress(address types.AccAddress) (Info, error) {
ik := kb.db.Get(addrKey((tmcrypto.Address)(address)))
if len(ik) == 0 {
return nil, fmt.Errorf("Key with address %s not found", address.String())
Copy link
Contributor

Choose a reason for hiding this comment

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

Lets lowercase Key 👍

@@ -179,6 +180,13 @@ func (kb dbKeybase) List() ([]Info, error) {
iter := kb.db.Iterator(nil, nil)
defer iter.Close()
for ; iter.Valid(); iter.Next() {
key := string(iter.Key())

// need to exclude any keys in storage that have an address suffix
Copy link
Contributor

Choose a reason for hiding this comment

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

I think a more defensive mechanism would be to: if strings.HasSuffix(key, infoSuffix) { // read and parse...}

}

func addrKey(address tmcrypto.Address) []byte {
return []byte(fmt.Sprintf("%s.address", address.String()))
Copy link
Contributor

Choose a reason for hiding this comment

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

Since we have more than one key type now, I think we should have these two suffixes as constants.

@mslipper
Copy link
Contributor Author

mslipper commented Sep 7, 2018

Hmm.. I'm on the int. test failures.

@mslipper
Copy link
Contributor Author

mslipper commented Sep 9, 2018

@alexanderbez finally figured this one out... the populateFromFields method needed to be a pointer receiver since it mutated state.

Copy link
Contributor

@alexanderbez alexanderbez left a comment

Choose a reason for hiding this comment

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

@mslipper tested the changes and they work (I only tested sends)!

However, I left a bit of final feedback. Also, I think this needs a rebase/merge with develop. Thanks!

PENDING.md Show resolved Hide resolved
func (kb dbKeybase) GetByAddress(address types.AccAddress) (Info, error) {
ik := kb.db.Get(addrKey(address))
if len(ik) == 0 {
return nil, fmt.Errorf("key with address %s not found", address.String())
Copy link
Contributor

Choose a reason for hiding this comment

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

No need to actually use String() here as Go will automatically do this for you (if the type implements Stringer) 👍

}

// NOTE: mutates state so must be pointer receiver
func (ctx *CLIContext) populateFromFields() error {
Copy link
Contributor

Choose a reason for hiding this comment

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

We'll need to think of another way implementing this functionality. The goal and point of contexts is that they are never modified, hence the ctx = ctx.With* logic. In our case here, maybe we'll need to to ctx = populateFromFields(ctx) somewhere upstream?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, I'll figure out a solution without the pointer receiver.

Copy link
Contributor

@alexanderbez alexanderbez left a comment

Choose a reason for hiding this comment

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

Just a few minor comments @mslipper and I think we're ready for merge 👍


keybase, err := keys.GetKeyBase()
if err != nil {
fmt.Println("No keybase found.")
Copy link
Contributor

Choose a reason for hiding this comment

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

no keybase found*

@@ -106,6 +116,36 @@ func createCertifier() tmlite.Certifier {
return certifier
}

// NOTE: mutates state so must be pointer receiver
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we can remove this note 👍

@@ -106,6 +116,36 @@ func createCertifier() tmlite.Certifier {
return certifier
}

// NOTE: mutates state so must be pointer receiver
func fromFields(from string) (types.AccAddress, string) {
Copy link
Contributor

Choose a reason for hiding this comment

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

func getFromFields(name string) (fromAddr types.AccAddress, fromName string) { *?

@rigelrozanski
Copy link
Contributor

Cool - let's merge this after bez comments addressed

@alexanderbez
Copy link
Contributor

@mslipper by any chance would you have the time to address the minor remarks left before we merge? Would be great if we could get this in before the next release 🎉

Copy link
Contributor

@alexanderbez alexanderbez left a comment

Choose a reason for hiding this comment

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

utACK -- can be merged @rigelrozanski

@rigelrozanski rigelrozanski merged commit 24413a3 into cosmos:develop Sep 25, 2018
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.

8 participants