-
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
R4R: gen-tx: Support User Given Key Passwords #1856
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,19 +3,25 @@ package app | |
import ( | ||
"encoding/json" | ||
"errors" | ||
"fmt" | ||
|
||
"github.com/spf13/pflag" | ||
"github.com/tendermint/tendermint/crypto" | ||
tmtypes "github.com/tendermint/tendermint/types" | ||
|
||
"github.com/cosmos/cosmos-sdk/client" | ||
"github.com/cosmos/cosmos-sdk/server" | ||
"github.com/cosmos/cosmos-sdk/server/config" | ||
sdk "github.com/cosmos/cosmos-sdk/types" | ||
"github.com/cosmos/cosmos-sdk/wire" | ||
"github.com/cosmos/cosmos-sdk/x/auth" | ||
"github.com/cosmos/cosmos-sdk/x/stake" | ||
|
||
"github.com/spf13/pflag" | ||
|
||
"github.com/tendermint/tendermint/crypto" | ||
tmtypes "github.com/tendermint/tendermint/types" | ||
) | ||
|
||
// DefaultKeyPass contains the default key password for genesis transactions | ||
const DefaultKeyPass = "12345678" | ||
|
||
var ( | ||
// bonded tokens given to genesis validators/accounts | ||
freeFermionVal = int64(100) | ||
|
@@ -81,30 +87,49 @@ type GaiaGenTx struct { | |
PubKey string `json:"pub_key"` | ||
} | ||
|
||
// Generate a gaia genesis transaction with flags | ||
func GaiaAppGenTx(cdc *wire.Codec, pk crypto.PubKey, genTxConfig config.GenTx) ( | ||
appGenTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error) { | ||
// GaiaAppGenTx generates a Gaia genesis transaction. | ||
func GaiaAppGenTx( | ||
cdc *wire.Codec, pk crypto.PubKey, genTxConfig config.GenTx, | ||
) (appGenTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error) { | ||
if genTxConfig.Name == "" { | ||
return nil, nil, tmtypes.GenesisValidator{}, errors.New("Must specify --name (validator moniker)") | ||
} | ||
|
||
var addr sdk.AccAddress | ||
var secret string | ||
addr, secret, err = server.GenerateSaveCoinKey(genTxConfig.CliRoot, genTxConfig.Name, "1234567890", genTxConfig.Overwrite) | ||
buf := client.BufferStdin() | ||
prompt := fmt.Sprintf("Password for account '%s' (default %s):", genTxConfig.Name, DefaultKeyPass) | ||
|
||
keyPass, err := client.GetPassword(prompt, buf) | ||
if err != nil && keyPass != "" { | ||
// An error was returned that either failed to read the password from | ||
// STDIN or the given password is not empty but failed to meet minimum | ||
// length requirements. | ||
return appGenTx, cliPrint, validator, err | ||
} | ||
|
||
if keyPass == "" { | ||
keyPass = DefaultKeyPass | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what's the thinking here around providing the default password here if nothing is provided? Which situations will this come up in? I was thinking we'd just fail if somebody doesn't provide a pass? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm lazy and don't want to enter anything (keeping inline with the current UX)? If we think absolutely requiring a user-provided password is a better UX experience, then I can remove it @rigelrozanski . There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think a better solution would be to have a key type with no password. Using a default password only burns computation time. This will be easier to do if we figure out a good way to refactor the keybase. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mhmmm, I'll need to think on that for a bit. What shall we do for now? Just not supply a default? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't really have a preference rn. I would like just having no passwords as an option later. (I'll try to spend some time today writing a way to do the keybase refactor) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Awesome! |
||
|
||
addr, secret, err := server.GenerateSaveCoinKey( | ||
genTxConfig.CliRoot, | ||
genTxConfig.Name, | ||
keyPass, | ||
genTxConfig.Overwrite, | ||
) | ||
if err != nil { | ||
return | ||
return appGenTx, cliPrint, validator, err | ||
} | ||
|
||
mm := map[string]string{"secret": secret} | ||
var bz []byte | ||
bz, err = cdc.MarshalJSON(mm) | ||
bz, err := cdc.MarshalJSON(mm) | ||
if err != nil { | ||
return | ||
return appGenTx, cliPrint, validator, err | ||
} | ||
|
||
cliPrint = json.RawMessage(bz) | ||
|
||
appGenTx, _, validator, err = GaiaAppGenTxNF(cdc, pk, addr, genTxConfig.Name) | ||
return | ||
|
||
return appGenTx, cliPrint, validator, err | ||
} | ||
|
||
// Generate a gaia genesis transaction without flags | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,7 +25,6 @@ import ( | |
) | ||
|
||
var ( | ||
pass = "1234567890" | ||
gaiadHome = "" | ||
gaiacliHome = "" | ||
) | ||
|
@@ -35,11 +34,12 @@ func init() { | |
} | ||
|
||
func TestGaiaCLISend(t *testing.T) { | ||
tests.ExecuteT(t, fmt.Sprintf("gaiad --home=%s unsafe_reset_all", gaiadHome)) | ||
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s foo", gaiacliHome), pass) | ||
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s bar", gaiacliHome), pass) | ||
tests.ExecuteT(t, fmt.Sprintf("gaiad --home=%s unsafe_reset_all", gaiadHome), "") | ||
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s foo", gaiacliHome), app.DefaultKeyPass) | ||
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s bar", gaiacliHome), app.DefaultKeyPass) | ||
|
||
chainID := executeInit(t, fmt.Sprintf("gaiad init -o --name=foo --home=%s --home-client=%s", gaiadHome, gaiacliHome)) | ||
executeWrite(t, fmt.Sprintf("gaiacli keys add --home=%s bar", gaiacliHome), pass) | ||
executeWrite(t, fmt.Sprintf("gaiacli keys add --home=%s bar", gaiacliHome), app.DefaultKeyPass) | ||
|
||
// get a free port, also setup some common flags | ||
servAddr, port, err := server.FreeTCPAddr() | ||
|
@@ -59,7 +59,7 @@ func TestGaiaCLISend(t *testing.T) { | |
fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %s %v", fooAddr, flags)) | ||
require.Equal(t, int64(50), fooAcc.GetCoins().AmountOf("steak").Int64()) | ||
|
||
executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10steak --to=%s --from=foo", flags, barAddr), pass) | ||
executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10steak --to=%s --from=foo", flags, barAddr), app.DefaultKeyPass) | ||
tests.WaitForNextNBlocksTM(2, port) | ||
|
||
barAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %s %v", barAddr, flags)) | ||
|
@@ -68,7 +68,7 @@ func TestGaiaCLISend(t *testing.T) { | |
require.Equal(t, int64(40), fooAcc.GetCoins().AmountOf("steak").Int64()) | ||
|
||
// test autosequencing | ||
executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10steak --to=%s --from=foo", flags, barAddr), pass) | ||
executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10steak --to=%s --from=foo", flags, barAddr), app.DefaultKeyPass) | ||
tests.WaitForNextNBlocksTM(2, port) | ||
|
||
barAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %s %v", barAddr, flags)) | ||
|
@@ -77,7 +77,7 @@ func TestGaiaCLISend(t *testing.T) { | |
require.Equal(t, int64(30), fooAcc.GetCoins().AmountOf("steak").Int64()) | ||
|
||
// test memo | ||
executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10steak --to=%s --from=foo --memo 'testmemo'", flags, barAddr), pass) | ||
executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10steak --to=%s --from=foo --memo 'testmemo'", flags, barAddr), app.DefaultKeyPass) | ||
tests.WaitForNextNBlocksTM(2, port) | ||
|
||
barAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %s %v", barAddr, flags)) | ||
|
@@ -87,11 +87,11 @@ func TestGaiaCLISend(t *testing.T) { | |
} | ||
|
||
func TestGaiaCLICreateValidator(t *testing.T) { | ||
tests.ExecuteT(t, fmt.Sprintf("gaiad --home=%s unsafe_reset_all", gaiadHome)) | ||
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s foo", gaiacliHome), pass) | ||
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s bar", gaiacliHome), pass) | ||
tests.ExecuteT(t, fmt.Sprintf("gaiad --home=%s unsafe_reset_all", gaiadHome), "") | ||
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s foo", gaiacliHome), app.DefaultKeyPass) | ||
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s bar", gaiacliHome), app.DefaultKeyPass) | ||
chainID := executeInit(t, fmt.Sprintf("gaiad init -o --name=foo --home=%s --home-client=%s", gaiadHome, gaiacliHome)) | ||
executeWrite(t, fmt.Sprintf("gaiacli keys add --home=%s bar", gaiacliHome), pass) | ||
executeWrite(t, fmt.Sprintf("gaiacli keys add --home=%s bar", gaiacliHome), app.DefaultKeyPass) | ||
|
||
// get a free port, also setup some common flags | ||
servAddr, port, err := server.FreeTCPAddr() | ||
|
@@ -109,7 +109,7 @@ func TestGaiaCLICreateValidator(t *testing.T) { | |
barAddr, barPubKey := executeGetAddrPK(t, fmt.Sprintf("gaiacli keys show bar --output=json --home=%s", gaiacliHome)) | ||
barCeshPubKey := sdk.MustBech32ifyValPub(barPubKey) | ||
|
||
executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10steak --to=%s --from=foo", flags, barAddr), pass) | ||
executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10steak --to=%s --from=foo", flags, barAddr), app.DefaultKeyPass) | ||
tests.WaitForNextNBlocksTM(2, port) | ||
|
||
barAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %s %v", barAddr, flags)) | ||
|
@@ -124,7 +124,7 @@ func TestGaiaCLICreateValidator(t *testing.T) { | |
cvStr += fmt.Sprintf(" --amount=%v", "2steak") | ||
cvStr += fmt.Sprintf(" --moniker=%v", "bar-vally") | ||
|
||
executeWrite(t, cvStr, pass) | ||
executeWrite(t, cvStr, app.DefaultKeyPass) | ||
tests.WaitForNextNBlocksTM(2, port) | ||
|
||
barAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %s %v", barAddr, flags)) | ||
|
@@ -140,7 +140,7 @@ func TestGaiaCLICreateValidator(t *testing.T) { | |
unbondStr += fmt.Sprintf(" --address-validator=%s", barAddr) | ||
unbondStr += fmt.Sprintf(" --shares-amount=%v", "1") | ||
|
||
success := executeWrite(t, unbondStr, pass) | ||
success := executeWrite(t, unbondStr, app.DefaultKeyPass) | ||
require.True(t, success) | ||
tests.WaitForNextNBlocksTM(2, port) | ||
|
||
|
@@ -153,11 +153,11 @@ func TestGaiaCLICreateValidator(t *testing.T) { | |
} | ||
|
||
func TestGaiaCLISubmitProposal(t *testing.T) { | ||
tests.ExecuteT(t, fmt.Sprintf("gaiad --home=%s unsafe_reset_all", gaiadHome)) | ||
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s foo", gaiacliHome), pass) | ||
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s bar", gaiacliHome), pass) | ||
tests.ExecuteT(t, fmt.Sprintf("gaiad --home=%s unsafe_reset_all", gaiadHome), "") | ||
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s foo", gaiacliHome), app.DefaultKeyPass) | ||
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s bar", gaiacliHome), app.DefaultKeyPass) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nice the default pass here from the app is good 👍 |
||
chainID := executeInit(t, fmt.Sprintf("gaiad init -o --name=foo --home=%s --home-client=%s", gaiadHome, gaiacliHome)) | ||
executeWrite(t, fmt.Sprintf("gaiacli keys add --home=%s bar", gaiacliHome), pass) | ||
executeWrite(t, fmt.Sprintf("gaiacli keys add --home=%s bar", gaiacliHome), app.DefaultKeyPass) | ||
|
||
// get a free port, also setup some common flags | ||
servAddr, port, err := server.FreeTCPAddr() | ||
|
@@ -176,7 +176,7 @@ func TestGaiaCLISubmitProposal(t *testing.T) { | |
fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %s %v", fooAddr, flags)) | ||
require.Equal(t, int64(50), fooAcc.GetCoins().AmountOf("steak").Int64()) | ||
|
||
proposalsQuery := tests.ExecuteT(t, fmt.Sprintf("gaiacli gov query-proposals %v", flags)) | ||
proposalsQuery := tests.ExecuteT(t, fmt.Sprintf("gaiacli gov query-proposals %v", flags), "") | ||
require.Equal(t, "No matching proposals found", proposalsQuery) | ||
|
||
// submit a test proposal | ||
|
@@ -187,7 +187,7 @@ func TestGaiaCLISubmitProposal(t *testing.T) { | |
spStr += fmt.Sprintf(" --title=%s", "Test") | ||
spStr += fmt.Sprintf(" --description=%s", "test") | ||
|
||
executeWrite(t, spStr, pass) | ||
executeWrite(t, spStr, app.DefaultKeyPass) | ||
tests.WaitForNextNBlocksTM(2, port) | ||
|
||
fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %s %v", fooAddr, flags)) | ||
|
@@ -197,15 +197,15 @@ func TestGaiaCLISubmitProposal(t *testing.T) { | |
require.Equal(t, int64(1), proposal1.GetProposalID()) | ||
require.Equal(t, gov.StatusDepositPeriod, proposal1.GetStatus()) | ||
|
||
proposalsQuery = tests.ExecuteT(t, fmt.Sprintf("gaiacli gov query-proposals %v", flags)) | ||
proposalsQuery = tests.ExecuteT(t, fmt.Sprintf("gaiacli gov query-proposals %v", flags), "") | ||
require.Equal(t, " 1 - Test", proposalsQuery) | ||
|
||
depositStr := fmt.Sprintf("gaiacli gov deposit %v", flags) | ||
depositStr += fmt.Sprintf(" --from=%s", "foo") | ||
depositStr += fmt.Sprintf(" --deposit=%s", "10steak") | ||
depositStr += fmt.Sprintf(" --proposal-id=%s", "1") | ||
|
||
executeWrite(t, depositStr, pass) | ||
executeWrite(t, depositStr, app.DefaultKeyPass) | ||
tests.WaitForNextNBlocksTM(2, port) | ||
|
||
fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %s %v", fooAddr, flags)) | ||
|
@@ -219,7 +219,7 @@ func TestGaiaCLISubmitProposal(t *testing.T) { | |
voteStr += fmt.Sprintf(" --proposal-id=%s", "1") | ||
voteStr += fmt.Sprintf(" --option=%s", "Yes") | ||
|
||
executeWrite(t, voteStr, pass) | ||
executeWrite(t, voteStr, app.DefaultKeyPass) | ||
tests.WaitForNextNBlocksTM(2, port) | ||
|
||
vote := executeGetVote(t, fmt.Sprintf("gaiacli gov query-vote --proposal-id=1 --voter=%s --output=json %v", fooAddr, flags)) | ||
|
@@ -231,10 +231,10 @@ func TestGaiaCLISubmitProposal(t *testing.T) { | |
require.Equal(t, int64(1), votes[0].ProposalID) | ||
require.Equal(t, gov.OptionYes, votes[0].Option) | ||
|
||
proposalsQuery = tests.ExecuteT(t, fmt.Sprintf("gaiacli gov query-proposals --status=DepositPeriod %v", flags)) | ||
proposalsQuery = tests.ExecuteT(t, fmt.Sprintf("gaiacli gov query-proposals --status=DepositPeriod %v", flags), "") | ||
require.Equal(t, "No matching proposals found", proposalsQuery) | ||
|
||
proposalsQuery = tests.ExecuteT(t, fmt.Sprintf("gaiacli gov query-proposals --status=VotingPeriod %v", flags)) | ||
proposalsQuery = tests.ExecuteT(t, fmt.Sprintf("gaiacli gov query-proposals --status=VotingPeriod %v", flags), "") | ||
require.Equal(t, " 1 - Test", proposalsQuery) | ||
|
||
// submit a second test proposal | ||
|
@@ -245,10 +245,10 @@ func TestGaiaCLISubmitProposal(t *testing.T) { | |
spStr += fmt.Sprintf(" --title=%s", "Apples") | ||
spStr += fmt.Sprintf(" --description=%s", "test") | ||
|
||
executeWrite(t, spStr, pass) | ||
executeWrite(t, spStr, app.DefaultKeyPass) | ||
tests.WaitForNextNBlocksTM(2, port) | ||
|
||
proposalsQuery = tests.ExecuteT(t, fmt.Sprintf("gaiacli gov query-proposals --latest=1 %v", flags)) | ||
proposalsQuery = tests.ExecuteT(t, fmt.Sprintf("gaiacli gov query-proposals --latest=1 %v", flags), "") | ||
require.Equal(t, " 2 - Apples", proposalsQuery) | ||
} | ||
|
||
|
@@ -291,7 +291,7 @@ func executeWrite(t *testing.T, cmdStr string, writes ...string) bool { | |
} | ||
|
||
func executeInit(t *testing.T, cmdStr string) (chainID string) { | ||
out := tests.ExecuteT(t, cmdStr) | ||
out := tests.ExecuteT(t, cmdStr, app.DefaultKeyPass) | ||
|
||
var initRes map[string]json.RawMessage | ||
err := json.Unmarshal([]byte(out), &initRes) | ||
|
@@ -304,7 +304,7 @@ func executeInit(t *testing.T, cmdStr string) (chainID string) { | |
} | ||
|
||
func executeGetAddrPK(t *testing.T, cmdStr string) (sdk.AccAddress, crypto.PubKey) { | ||
out := tests.ExecuteT(t, cmdStr) | ||
out := tests.ExecuteT(t, cmdStr, "") | ||
var ko keys.KeyOutput | ||
keys.UnmarshalJSON([]byte(out), &ko) | ||
|
||
|
@@ -315,7 +315,7 @@ func executeGetAddrPK(t *testing.T, cmdStr string) (sdk.AccAddress, crypto.PubKe | |
} | ||
|
||
func executeGetAccount(t *testing.T, cmdStr string) auth.BaseAccount { | ||
out := tests.ExecuteT(t, cmdStr) | ||
out := tests.ExecuteT(t, cmdStr, "") | ||
var initRes map[string]json.RawMessage | ||
err := json.Unmarshal([]byte(out), &initRes) | ||
require.NoError(t, err, "out %v, err %v", out, err) | ||
|
@@ -329,7 +329,7 @@ func executeGetAccount(t *testing.T, cmdStr string) auth.BaseAccount { | |
} | ||
|
||
func executeGetValidator(t *testing.T, cmdStr string) stake.Validator { | ||
out := tests.ExecuteT(t, cmdStr) | ||
out := tests.ExecuteT(t, cmdStr, "") | ||
var validator stake.Validator | ||
cdc := app.MakeCodec() | ||
err := cdc.UnmarshalJSON([]byte(out), &validator) | ||
|
@@ -338,7 +338,7 @@ func executeGetValidator(t *testing.T, cmdStr string) stake.Validator { | |
} | ||
|
||
func executeGetProposal(t *testing.T, cmdStr string) gov.Proposal { | ||
out := tests.ExecuteT(t, cmdStr) | ||
out := tests.ExecuteT(t, cmdStr, "") | ||
var proposal gov.Proposal | ||
cdc := app.MakeCodec() | ||
err := cdc.UnmarshalJSON([]byte(out), &proposal) | ||
|
@@ -347,7 +347,7 @@ func executeGetProposal(t *testing.T, cmdStr string) gov.Proposal { | |
} | ||
|
||
func executeGetVote(t *testing.T, cmdStr string) gov.Vote { | ||
out := tests.ExecuteT(t, cmdStr) | ||
out := tests.ExecuteT(t, cmdStr, "") | ||
var vote gov.Vote | ||
cdc := app.MakeCodec() | ||
err := cdc.UnmarshalJSON([]byte(out), &vote) | ||
|
@@ -356,7 +356,7 @@ func executeGetVote(t *testing.T, cmdStr string) gov.Vote { | |
} | ||
|
||
func executeGetVotes(t *testing.T, cmdStr string) []gov.Vote { | ||
out := tests.ExecuteT(t, cmdStr) | ||
out := tests.ExecuteT(t, cmdStr, "") | ||
var votes []gov.Vote | ||
cdc := app.MakeCodec() | ||
err := cdc.UnmarshalJSON([]byte(out), &votes) | ||
|
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.
typically we try to keep comments as non-verbose as possible, which often means they are not sentences - I think this makes sense - here just a general comment