Merge PR #3517: Increasing test coverage in keys/client package

This commit is contained in:
Juan Leni 2019-02-08 21:45:23 +01:00 committed by Jack Zampolin
parent cff985ffc5
commit b5fdb83830
49 changed files with 1137 additions and 312 deletions

View File

@ -204,7 +204,7 @@ jobs:
export VERSION="$(git describe --tags --long | sed 's/v\(.*\)/\1/')"
for pkg in $(go list ./... | grep -v github.com/cosmos/cosmos-sdk/cmd/gaia/cli_test | grep -v '/simulation' | circleci tests split --split-by=timings); do
id=$(echo "$pkg" | sed 's|[/.]|_|g')
GOCACHE=off go test -timeout 8m -race -coverprofile=/tmp/workspace/profiles/$id.out -covermode=atomic "$pkg" | tee "/tmp/logs/$id-$RANDOM.log"
GOCACHE=off go test -timeout 8m -race -coverprofile=/tmp/workspace/profiles/$id.out -covermode=atomic -tags='ledger test_ledger_mock' "$pkg" | tee "/tmp/logs/$id-$RANDOM.log"
done
- persist_to_workspace:
root: /tmp/workspace

View File

@ -145,10 +145,13 @@ test_cli:
@go test -p 4 `go list github.com/cosmos/cosmos-sdk/cmd/gaia/cli_test` -tags=cli_test
test_ledger:
@go test `go list github.com/cosmos/cosmos-sdk/crypto` -tags='cgo ledger test_real_ledger'
# First test with mock
@go test `go list github.com/cosmos/cosmos-sdk/crypto` -tags='cgo ledger test_ledger_mock'
# Now test with a real device
@go test -v `go list github.com/cosmos/cosmos-sdk/crypto` -tags='cgo ledger'
test_unit:
@VERSION=$(VERSION) go test $(PACKAGES_NOSIMULATION)
@VERSION=$(VERSION) go test $(PACKAGES_NOSIMULATION) -tags='test_ledger_mock'
test_race:
@VERSION=$(VERSION) go test -race $(PACKAGES_NOSIMULATION)

View File

@ -77,6 +77,7 @@ IMPROVEMENTS
* [\#3497](https://github.com/cosmos/cosmos-sdk/issues/3497) `gaiad gentx` supports `--ip` and `--node-id` flags to override defaults.
* [\#3518](https://github.com/cosmos/cosmos-sdk/issues/3518) Fix flow in
`keys add` to show the mnemonic by default.
* [\#3517](https://github.com/cosmos/cosmos-sdk/pull/3517) Increased test coverage
* Gaia
* [\#3418](https://github.com/cosmos/cosmos-sdk/issues/3418) Add vesting account

View File

@ -770,7 +770,7 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte, tx sdk.Tx) (result sdk
)
if ctx.BlockGasMeter().GasConsumed() < startingGas {
panic(sdk.ErrorGasOverflow{"tx gas summation"})
panic(sdk.ErrorGasOverflow{Descriptor: "tx gas summation"})
}
}
}()

View File

@ -15,10 +15,26 @@ import (
// MinPassLength is the minimum acceptable password length
const MinPassLength = 8
var currentStdin *bufio.Reader
func init() {
currentStdin = bufio.NewReader(os.Stdin)
}
// BufferStdin is used to allow reading prompts for stdin
// multiple times, when we read from non-tty
func BufferStdin() *bufio.Reader {
return bufio.NewReader(os.Stdin)
return currentStdin
}
// OverrideStdin allows to temporarily override stdin
func OverrideStdin(newStdin *bufio.Reader) (cleanUp func()) {
prevStdin := currentStdin
currentStdin = newStdin
cleanUp = func() {
currentStdin = prevStdin
}
return cleanUp
}
// GetPassword will prompt for a password one-time (to sign a tx)

View File

@ -90,7 +90,7 @@ input
output
- armor encrypted private key (saved to file)
*/
func runAddCmd(cmd *cobra.Command, args []string) error {
func runAddCmd(_ *cobra.Command, args []string) error {
var kb keys.Keybase
var err error
var encryptPassword string
@ -265,7 +265,7 @@ func printCreate(info keys.Info, showMnemonic bool, mnemonic string) error {
output := viper.Get(cli.OutputFlag)
switch output {
case "text":
case OutputFormatText:
fmt.Fprintln(os.Stderr)
printKeyInfo(info, Bech32KeyOutput)
@ -276,7 +276,7 @@ func printCreate(info keys.Info, showMnemonic bool, mnemonic string) error {
fmt.Fprintln(os.Stderr, "")
fmt.Fprintln(os.Stderr, mnemonic)
}
case "json":
case OutputFormatJSON:
out, err := Bech32KeyOutput(info)
if err != nil {
return err

104
client/keys/add_test.go Normal file
View File

@ -0,0 +1,104 @@
package keys
import (
"bufio"
"net/http"
"strings"
"testing"
"github.com/pkg/errors"
"github.com/stretchr/testify/require"
"github.com/spf13/viper"
"github.com/tendermint/tendermint/libs/cli"
"github.com/cosmos/cosmos-sdk/tests"
"github.com/cosmos/cosmos-sdk/client"
"github.com/stretchr/testify/assert"
)
func Test_runAddCmdBasic(t *testing.T) {
cmd := addKeyCommand()
assert.NotNil(t, cmd)
// Missing input (enter password)
err := runAddCmd(cmd, []string{"keyname"})
assert.EqualError(t, err, "EOF")
// Prepare a keybase
kbHome, kbCleanUp, err := tests.GetTempDir("Test_runDeleteCmd")
assert.NoError(t, err)
assert.NotNil(t, kbHome)
defer kbCleanUp()
viper.Set(cli.HomeFlag, kbHome)
/// Test Text
viper.Set(cli.OutputFlag, OutputFormatText)
// Now enter password
cleanUp1 := client.OverrideStdin(bufio.NewReader(strings.NewReader("test1234\ntest1234\n")))
defer cleanUp1()
err = runAddCmd(cmd, []string{"keyname1"})
assert.NoError(t, err)
/// Test Text - Replace? >> FAIL
viper.Set(cli.OutputFlag, OutputFormatText)
// Now enter password
cleanUp2 := client.OverrideStdin(bufio.NewReader(strings.NewReader("test1234\ntest1234\n")))
defer cleanUp2()
err = runAddCmd(cmd, []string{"keyname1"})
assert.Error(t, err)
/// Test Text - Replace? Answer >> PASS
viper.Set(cli.OutputFlag, OutputFormatText)
// Now enter password
cleanUp3 := client.OverrideStdin(bufio.NewReader(strings.NewReader("y\ntest1234\ntest1234\n")))
defer cleanUp3()
err = runAddCmd(cmd, []string{"keyname1"})
assert.NoError(t, err)
// Check JSON
viper.Set(cli.OutputFlag, OutputFormatJSON)
// Now enter password
cleanUp4 := client.OverrideStdin(bufio.NewReader(strings.NewReader("test1234\ntest1234\n")))
defer cleanUp4()
err = runAddCmd(cmd, []string{"keyname2"})
assert.NoError(t, err)
}
type MockResponseWriter struct {
dataHeaderStatus int
dataBody []byte
}
func (MockResponseWriter) Header() http.Header {
panic("Unexpected call!")
}
func (w *MockResponseWriter) Write(data []byte) (int, error) {
w.dataBody = append(w.dataBody, data...)
return len(data), nil
}
func (w *MockResponseWriter) WriteHeader(statusCode int) {
w.dataHeaderStatus = statusCode
}
func TestCheckAndWriteErrorResponse(t *testing.T) {
mockRW := MockResponseWriter{}
mockRW.WriteHeader(100)
assert.Equal(t, 100, mockRW.dataHeaderStatus)
detected := CheckAndWriteErrorResponse(&mockRW, http.StatusBadRequest, errors.New("some ERROR"))
require.True(t, detected)
require.Equal(t, http.StatusBadRequest, mockRW.dataHeaderStatus)
require.Equal(t, "some ERROR", string(mockRW.dataBody[:]))
mockRW = MockResponseWriter{}
detected = CheckAndWriteErrorResponse(&mockRW, http.StatusBadRequest, nil)
require.False(t, detected)
require.Equal(t, 0, mockRW.dataHeaderStatus)
require.Equal(t, "", string(mockRW.dataBody[:]))
}

100
client/keys/codec_test.go Normal file
View File

@ -0,0 +1,100 @@
package keys
import (
"fmt"
"reflect"
"testing"
"github.com/stretchr/testify/require"
)
type testCases struct {
Keys []KeyOutput
Answers []KeyOutput
JSON [][]byte
}
func getTestCases() testCases {
return testCases{
[]KeyOutput{
{"A", "B", "C", "D", "E"},
{"A", "B", "C", "D", ""},
{"", "B", "C", "D", ""},
{"", "", "", "", ""},
},
make([]KeyOutput, 4),
[][]byte{
[]byte(`{"name":"A","type":"B","address":"C","pub_key":"D","mnemonic":"E"}`),
[]byte(`{"name":"A","type":"B","address":"C","pub_key":"D"}`),
[]byte(`{"name":"","type":"B","address":"C","pub_key":"D"}`),
[]byte(`{"name":"","type":"","address":"","pub_key":""}`),
},
}
}
func TestMarshalJSON(t *testing.T) {
type args struct {
o KeyOutput
}
data := getTestCases()
tests := []struct {
name string
args args
want []byte
wantErr bool
}{
{"basic", args{data.Keys[0]}, []byte(data.JSON[0]), false},
{"mnemonic is optional", args{data.Keys[1]}, []byte(data.JSON[1]), false},
// REVIEW: Are the next results expected??
{"empty name", args{data.Keys[2]}, []byte(data.JSON[2]), false},
{"empty object", args{data.Keys[3]}, []byte(data.JSON[3]), false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := MarshalJSON(tt.args.o)
if (err != nil) != tt.wantErr {
t.Errorf("MarshalJSON() error = %v, wantErr %v", err, tt.wantErr)
return
}
fmt.Printf("%s\n", got)
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("MarshalJSON() = %v, want %v", got, tt.want)
}
})
}
}
func TestUnmarshalJSON(t *testing.T) {
type args struct {
bz []byte
ptr interface{}
}
data := getTestCases()
tests := []struct {
name string
args args
wantErr bool
}{
{"basic", args{data.JSON[0], &data.Answers[0]}, false},
{"mnemonic is optional", args{data.JSON[1], &data.Answers[1]}, false},
// REVIEW: Are the next results expected??
{"empty name", args{data.JSON[2], &data.Answers[2]}, false},
{"empty object", args{data.JSON[3], &data.Answers[3]}, false},
}
for idx, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := UnmarshalJSON(tt.args.bz, tt.args.ptr); (err != nil) != tt.wantErr {
t.Errorf("UnmarshalJSON() error = %v, wantErr %v", err, tt.wantErr)
}
// Confirm deserialized objects are the same
require.Equal(t, data.Keys[idx], data.Answers[idx])
})
}
}

View File

@ -91,6 +91,17 @@ func runDeleteCmd(cmd *cobra.Command, args []string) error {
return nil
}
func confirmDeletion(buf *bufio.Reader) error {
answer, err := client.GetConfirmation("Key reference will be deleted. Continue?", buf)
if err != nil {
return err
}
if !answer {
return errors.New("aborted")
}
return nil
}
////////////////////////
// REST
@ -110,42 +121,31 @@ func DeleteKeyRequestHandler(w http.ResponseWriter, r *http.Request) {
err := decoder.Decode(&m)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
}
kb, err = NewKeyBaseFromHomeFlag()
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
}
err = kb.Delete(name, m.Password, false)
if keyerror.IsErrKeyNotFound(err) {
w.WriteHeader(http.StatusNotFound)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
} else if keyerror.IsErrWrongPassword(err) {
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
} else if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
}
w.WriteHeader(http.StatusOK)
}
func confirmDeletion(buf *bufio.Reader) error {
answer, err := client.GetConfirmation("Key reference will be deleted. Continue?", buf)
if err != nil {
return err
}
if !answer {
return errors.New("aborted")
}
return nil
}

103
client/keys/delete_test.go Normal file
View File

@ -0,0 +1,103 @@
package keys
import (
"bufio"
"strings"
"testing"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/tests"
"github.com/spf13/viper"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/libs/cli"
)
func Test_runDeleteCmd(t *testing.T) {
deleteKeyCommand := deleteKeyCommand()
yesF, _ := deleteKeyCommand.Flags().GetBool(flagYes)
forceF, _ := deleteKeyCommand.Flags().GetBool(flagForce)
assert.False(t, yesF)
assert.False(t, forceF)
fakeKeyName1 := "runDeleteCmd_Key1"
fakeKeyName2 := "runDeleteCmd_Key2"
// Now add a temporary keybase
kbHome, cleanUp, err := tests.GetTempDir("Test_runDeleteCmd")
assert.NoError(t, err)
defer cleanUp()
viper.Set(cli.HomeFlag, kbHome)
// Now
kb, err := NewKeyBaseFromHomeFlag()
assert.NoError(t, err)
_, err = kb.CreateAccount(fakeKeyName1, tests.TestMnemonic, "", "", 0, 0)
assert.NoError(t, err)
_, err = kb.CreateAccount(fakeKeyName2, tests.TestMnemonic, "", "", 0, 1)
assert.NoError(t, err)
err = runDeleteCmd(deleteKeyCommand, []string{"blah"})
require.Error(t, err)
require.Equal(t, "Key blah not found", err.Error())
// User confirmation missing
err = runDeleteCmd(deleteKeyCommand, []string{fakeKeyName1})
require.Error(t, err)
require.Equal(t, "EOF", err.Error())
{
_, err = kb.Get(fakeKeyName1)
require.NoError(t, err)
// Now there is a confirmation
cleanUp := client.OverrideStdin(bufio.NewReader(strings.NewReader("y\n")))
defer cleanUp()
err = runDeleteCmd(deleteKeyCommand, []string{fakeKeyName1})
require.NoError(t, err)
_, err = kb.Get(fakeKeyName1)
require.Error(t, err) // Key1 is gone
}
viper.Set(flagYes, true)
_, err = kb.Get(fakeKeyName2)
require.NoError(t, err)
err = runDeleteCmd(deleteKeyCommand, []string{fakeKeyName2})
require.NoError(t, err)
_, err = kb.Get(fakeKeyName2)
require.Error(t, err) // Key2 is gone
// TODO: Write another case for !keys.Local
}
func Test_confirmDeletion(t *testing.T) {
type args struct {
buf *bufio.Reader
}
answerYes := bufio.NewReader(strings.NewReader("y\n"))
answerYes2 := bufio.NewReader(strings.NewReader("Y\n"))
answerNo := bufio.NewReader(strings.NewReader("n\n"))
answerInvalid := bufio.NewReader(strings.NewReader("245\n"))
tests := []struct {
name string
args args
wantErr bool
}{
{"Y", args{answerYes}, false},
{"y", args{answerYes2}, false},
{"N", args{answerNo}, true},
{"BAD", args{answerInvalid}, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := confirmDeletion(tt.args.buf); (err != nil) != tt.wantErr {
t.Errorf("confirmDeletion() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

View File

View File

@ -6,15 +6,14 @@ import (
"github.com/spf13/cobra"
)
// CMD
// listKeysCmd represents the list command
var listKeysCmd = &cobra.Command{
Use: "list",
Short: "List all keys",
Long: `Return a list of all public keys stored by this key manager
func listKeysCmd() *cobra.Command {
return &cobra.Command{
Use: "list",
Short: "List all keys",
Long: `Return a list of all public keys stored by this key manager
along with their associated name and address.`,
RunE: runListCmd,
RunE: runListCmd,
}
}
func runListCmd(cmd *cobra.Command, args []string) error {
@ -39,13 +38,13 @@ func QueryKeysRequestHandler(indent bool) http.HandlerFunc {
kb, err := NewKeyBaseFromHomeFlag()
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
}
infos, err := kb.List()
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
}
// an empty list will be JSONized as null, but we want to keep the empty list
@ -56,7 +55,7 @@ func QueryKeysRequestHandler(indent bool) http.HandlerFunc {
keysOutput, err := Bech32KeysOutput(infos)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
}
PostProcessResponse(w, cdc, keysOutput, indent)

57
client/keys/list_test.go Normal file
View File

@ -0,0 +1,57 @@
package keys
import (
"testing"
"github.com/cosmos/cosmos-sdk/tests"
"github.com/stretchr/testify/assert"
"github.com/spf13/viper"
"github.com/tendermint/tendermint/libs/cli"
"github.com/spf13/cobra"
)
func Test_runListCmd(t *testing.T) {
type args struct {
cmd *cobra.Command
args []string
}
cmdBasic := listKeysCmd()
// Prepare some keybases
kbHome1, cleanUp1, err := tests.GetTempDir("Test_runListCmd")
defer cleanUp1()
assert.NoError(t, err)
// Do nothing, leave home1 empty
kbHome2, cleanUp2, err := tests.GetTempDir("Test_runListCmd")
defer cleanUp2()
viper.Set(cli.HomeFlag, kbHome2)
assert.NoError(t, err)
kb, err := NewKeyBaseFromHomeFlag()
assert.NoError(t, err)
_, err = kb.CreateAccount("something", tests.TestMnemonic, "", "", 0, 0)
assert.NoError(t, err)
testData := []struct {
name string
kbDir string
args args
wantErr bool
}{
{"invalid keybase", "/dev/null", args{cmdBasic, []string{}}, true},
{"keybase: empty", kbHome1, args{cmdBasic, []string{}}, false},
{"keybase: w/key", kbHome2, args{cmdBasic, []string{}}, false},
}
for _, tt := range testData {
t.Run(tt.name, func(t *testing.T) {
viper.Set(cli.HomeFlag, tt.kbDir)
if err := runListCmd(tt.args.cmd, tt.args.args); (err != nil) != tt.wantErr {
t.Errorf("runListCmd() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

View File

@ -43,9 +43,7 @@ func runMnemonicCmd(cmd *cobra.Command, args []string) error {
if len(inputEntropy) < 43 {
return fmt.Errorf("256-bits is 43 characters in Base-64, and 100 in Base-6. You entered %v, and probably want more", len(inputEntropy))
}
conf, err := client.GetConfirmation(
fmt.Sprintf("> Input length: %d", len(inputEntropy)),
buf)
conf, err := client.GetConfirmation(fmt.Sprintf("> Input length: %d", len(inputEntropy)), buf)
if err != nil {
return err
}

View File

@ -0,0 +1,59 @@
package keys
import (
"bufio"
"strings"
"testing"
"github.com/cosmos/cosmos-sdk/client"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func Test_RunMnemonicCmdNormal(t *testing.T) {
cmdBasic := mnemonicKeyCommand()
err := runMnemonicCmd(cmdBasic, []string{})
require.NoError(t, err)
}
func Test_RunMnemonicCmdUser(t *testing.T) {
cmdUser := mnemonicKeyCommand()
err := cmdUser.Flags().Set(flagUserEntropy, "1")
assert.NoError(t, err)
err = runMnemonicCmd(cmdUser, []string{})
require.Error(t, err)
require.Equal(t, "EOF", err.Error())
// Try again
cleanUp := client.OverrideStdin(bufio.NewReader(strings.NewReader("Hi!\n")))
defer cleanUp()
err = runMnemonicCmd(cmdUser, []string{})
require.Error(t, err)
require.Equal(t,
"256-bits is 43 characters in Base-64, and 100 in Base-6. You entered 3, and probably want more",
err.Error())
// Now provide "good" entropy :)
fakeEntropy := strings.Repeat(":)", 40) + "\ny\n" // entropy + accept count
cleanUp2 := client.OverrideStdin(bufio.NewReader(strings.NewReader(fakeEntropy)))
defer cleanUp2()
err = runMnemonicCmd(cmdUser, []string{})
require.NoError(t, err)
// Now provide "good" entropy but no answer
fakeEntropy = strings.Repeat(":)", 40) + "\n" // entropy + accept count
cleanUp3 := client.OverrideStdin(bufio.NewReader(strings.NewReader(fakeEntropy)))
defer cleanUp3()
err = runMnemonicCmd(cmdUser, []string{})
require.Error(t, err)
// Now provide "good" entropy but say no
fakeEntropy = strings.Repeat(":)", 40) + "\nn\n" // entropy + accept count
cleanUp4 := client.OverrideStdin(bufio.NewReader(strings.NewReader(fakeEntropy)))
defer cleanUp4()
err = runMnemonicCmd(cmdUser, []string{})
require.NoError(t, err)
}

View File

@ -22,7 +22,7 @@ func Commands() *cobra.Command {
cmd.AddCommand(
mnemonicKeyCommand(),
addKeyCommand(),
listKeysCmd,
listKeysCmd(),
showKeysCmd(),
client.LineBreak,
deleteKeyCommand(),

22
client/keys/root_test.go Normal file
View File

@ -0,0 +1,22 @@
package keys
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/gorilla/mux"
)
func TestCommands(t *testing.T) {
rootCommands := Commands()
assert.NotNil(t, rootCommands)
// Commands are registered
assert.Equal(t, 7, len(rootCommands.Commands()))
}
func TestRegisterRoutes(t *testing.T) {
fakeRouter := mux.Router{}
RegisterRoutes(&fakeRouter, false)
}

View File

@ -93,7 +93,12 @@ func runShowCmd(cmd *cobra.Command, args []string) (err error) {
isShowAddr := viper.GetBool(FlagAddress)
isShowPubKey := viper.GetBool(FlagPublicKey)
isOutputSet := cmd.Flag(cli.OutputFlag).Changed
isOutputSet := false
tmp := cmd.Flag(cli.OutputFlag)
if tmp != nil {
isOutputSet = tmp.Changed
}
if isShowAddr && isShowPubKey {
return errors.New("cannot use both --address and --pubkey at once")
@ -161,25 +166,25 @@ func GetKeyRequestHandler(indent bool) http.HandlerFunc {
bechKeyOut, err := getBechKeyOut(bechPrefix)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
}
info, err := GetKeyInfo(name)
if keyerror.IsErrKeyNotFound(err) {
w.WriteHeader(http.StatusNotFound)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
} else if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
}
keyOutput, err := bechKeyOut(info)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
}

146
client/keys/show_test.go Normal file
View File

@ -0,0 +1,146 @@
package keys
import (
"testing"
"github.com/cosmos/cosmos-sdk/tests"
"github.com/spf13/viper"
"github.com/tendermint/tendermint/libs/cli"
"github.com/tendermint/tendermint/crypto/secp256k1"
"github.com/stretchr/testify/assert"
"github.com/cosmos/cosmos-sdk/crypto/keys"
)
func Test_multiSigKey_Properties(t *testing.T) {
tmpKey1 := secp256k1.GenPrivKeySecp256k1([]byte("mySecret"))
tmp := multiSigKey{
name: "myMultisig",
key: tmpKey1.PubKey(),
}
assert.Equal(t, "myMultisig", tmp.GetName())
assert.Equal(t, keys.TypeLocal, tmp.GetType())
assert.Equal(t, "015ABFFB09DB738A45745A91E8C401423ECE4016", tmp.GetPubKey().Address().String())
assert.Equal(t, "cosmos1q9dtl7cfmdec53t5t2g733qpgglvusqk6xdntl", tmp.GetAddress().String())
}
func Test_showKeysCmd(t *testing.T) {
cmd := showKeysCmd()
assert.NotNil(t, cmd)
assert.Equal(t, "false", cmd.Flag(FlagAddress).DefValue)
assert.Equal(t, "false", cmd.Flag(FlagPublicKey).DefValue)
}
func Test_runShowCmd(t *testing.T) {
cmd := showKeysCmd()
err := runShowCmd(cmd, []string{"invalid"})
assert.EqualError(t, err, "Key invalid not found")
err = runShowCmd(cmd, []string{"invalid1", "invalid2"})
assert.EqualError(t, err, "Key invalid1 not found")
// Prepare a key base
// Now add a temporary keybase
kbHome, cleanUp, err := tests.GetTempDir("Test_runShowCmd")
assert.NoError(t, err)
defer cleanUp()
viper.Set(cli.HomeFlag, kbHome)
fakeKeyName1 := "runShowCmd_Key1"
fakeKeyName2 := "runShowCmd_Key2"
kb, err := NewKeyBaseFromHomeFlag()
assert.NoError(t, err)
_, err = kb.CreateAccount(fakeKeyName1, tests.TestMnemonic, "", "", 0, 0)
assert.NoError(t, err)
_, err = kb.CreateAccount(fakeKeyName2, tests.TestMnemonic, "", "", 0, 1)
assert.NoError(t, err)
// Now try single key
err = runShowCmd(cmd, []string{fakeKeyName1})
assert.EqualError(t, err, "invalid Bech32 prefix encoding provided: ")
// Now try single key - set bech to acc
viper.Set(FlagBechPrefix, "acc")
err = runShowCmd(cmd, []string{fakeKeyName1})
assert.NoError(t, err)
// Now try multisig key - set bech to acc
viper.Set(FlagBechPrefix, "acc")
err = runShowCmd(cmd, []string{fakeKeyName1, fakeKeyName2})
assert.EqualError(t, err, "threshold must be a positive integer")
// Now try multisig key - set bech to acc + threshold=2
viper.Set(FlagBechPrefix, "acc")
viper.Set(flagMultiSigThreshold, 2)
err = runShowCmd(cmd, []string{fakeKeyName1, fakeKeyName2})
assert.NoError(t, err)
// TODO: Capture stdout and compare
}
func Test_validateMultisigThreshold(t *testing.T) {
type args struct {
k int
nKeys int
}
tests := []struct {
name string
args args
wantErr bool
}{
{"zeros", args{0, 0}, true},
{"1-0", args{1, 0}, true},
{"1-1", args{1, 1}, false},
{"1-2", args{1, 1}, false},
{"1-2", args{2, 1}, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := validateMultisigThreshold(tt.args.k, tt.args.nKeys); (err != nil) != tt.wantErr {
t.Errorf("validateMultisigThreshold() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}
func Test_getBechKeyOut(t *testing.T) {
type args struct {
bechPrefix string
}
tests := []struct {
name string
args args
want bechKeyOutFn
wantErr bool
}{
{"empty", args{""}, nil, true},
{"wrong", args{"???"}, nil, true},
{"acc", args{"acc"}, Bech32KeyOutput, false},
{"val", args{"val"}, Bech32ValKeyOutput, false},
{"cons", args{"cons"}, Bech32ConsKeyOutput, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := getBechKeyOut(tt.args.bechPrefix)
if (err != nil) != tt.wantErr {
t.Errorf("getBechKeyOut() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !tt.wantErr {
assert.NotNil(t, got)
}
// TODO: Still not possible to compare functions
// Maybe in next release: https://github.com/stretchr/testify/issues/182
//if &got != &tt.want {
// t.Errorf("getBechKeyOut() = %v, want %v", got, tt.want)
//}
})
}
}

View File

@ -8,7 +8,7 @@ import (
"github.com/gorilla/mux"
"github.com/cosmos/cosmos-sdk/client"
keys "github.com/cosmos/cosmos-sdk/crypto/keys"
"github.com/cosmos/cosmos-sdk/crypto/keys"
"github.com/spf13/cobra"
@ -73,14 +73,14 @@ func UpdateKeyRequestHandler(w http.ResponseWriter, r *http.Request) {
err := decoder.Decode(&m)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
}
kb, err = NewKeyBaseFromHomeFlag()
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
}
@ -89,15 +89,15 @@ func UpdateKeyRequestHandler(w http.ResponseWriter, r *http.Request) {
err = kb.Update(name, m.OldPassword, getNewpass)
if keyerror.IsErrKeyNotFound(err) {
w.WriteHeader(http.StatusNotFound)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
} else if keyerror.IsErrWrongPassword(err) {
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
} else if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
}

View File

@ -0,0 +1,64 @@
package keys
import (
"bufio"
"strings"
"testing"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/tests"
"github.com/spf13/viper"
"github.com/tendermint/tendermint/libs/cli"
"github.com/stretchr/testify/assert"
)
func Test_updateKeyCommand(t *testing.T) {
cmd := updateKeyCommand()
assert.NotNil(t, cmd)
// No flags or defaults to validate
}
func Test_runUpdateCmd(t *testing.T) {
fakeKeyName1 := "runUpdateCmd_Key1"
fakeKeyName2 := "runUpdateCmd_Key2"
cmd := updateKeyCommand()
// fails because it requests a password
err := runUpdateCmd(cmd, []string{fakeKeyName1})
assert.EqualError(t, err, "EOF")
cleanUp := client.OverrideStdin(bufio.NewReader(strings.NewReader("pass1234\n")))
defer cleanUp()
// try again
err = runUpdateCmd(cmd, []string{fakeKeyName1})
assert.EqualError(t, err, "Key runUpdateCmd_Key1 not found")
// Prepare a key base
// Now add a temporary keybase
kbHome, cleanUp1, err := tests.GetTempDir("Test_runShowCmd")
assert.NoError(t, err)
defer cleanUp1()
viper.Set(cli.HomeFlag, kbHome)
kb, err := NewKeyBaseFromHomeFlag()
assert.NoError(t, err)
_, err = kb.CreateAccount(fakeKeyName1, tests.TestMnemonic, "", "", 0, 0)
assert.NoError(t, err)
_, err = kb.CreateAccount(fakeKeyName2, tests.TestMnemonic, "", "", 0, 1)
assert.NoError(t, err)
// Try again now that we have keys
cleanUp2 := client.OverrideStdin(bufio.NewReader(strings.NewReader("pass1234\nNew1234\nNew1234")))
defer cleanUp2()
// Incorrect key type
err = runUpdateCmd(cmd, []string{fakeKeyName1})
assert.EqualError(t, err, "locally stored key required. Received: keys.offlineInfo")
// TODO: Check for other type types?
}

View File

@ -15,7 +15,11 @@ import (
)
// KeyDBName is the directory under root where we store the keys
const KeyDBName = "keys"
const (
KeyDBName = "keys"
OutputFormatText = "text"
OutputFormatJSON = "json"
)
type bechKeyOutFn func(keyInfo keys.Info) (KeyOutput, error)
@ -157,7 +161,7 @@ func printKeyInfo(keyInfo keys.Info, bechKeyOut bechKeyOutFn) {
}
switch viper.Get(cli.OutputFlag) {
case "text":
case OutputFormatText:
fmt.Printf("NAME:\tTYPE:\tADDRESS:\t\t\t\t\t\tPUBKEY:\n")
printKeyOutput(ko)
case "json":
@ -176,12 +180,12 @@ func printInfos(infos []keys.Info) {
panic(err)
}
switch viper.Get(cli.OutputFlag) {
case "text":
case OutputFormatText:
fmt.Printf("NAME:\tTYPE:\tADDRESS:\t\t\t\t\t\tPUBKEY:\n")
for _, ko := range kos {
printKeyOutput(ko)
}
case "json":
case OutputFormatJSON:
out, err := MarshalJSON(kos)
if err != nil {
panic(err)
@ -225,12 +229,12 @@ func PostProcessResponse(w http.ResponseWriter, cdc *codec.Codec, response inter
}
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
_, _ = w.Write([]byte(err.Error()))
return
}
case []byte:
output = response.([]byte)
}
w.Header().Set("Content-Type", "application/json")
w.Write(output)
_, _ = w.Write(output)
}

View File

@ -175,7 +175,7 @@ func TestVersion(t *testing.T) {
reg, err := regexp.Compile(`\d+\.\d+\.\d+.*`)
require.Nil(t, err)
match := reg.MatchString(body)
require.True(t, match, body, fmt.Sprintf("%s", body))
require.True(t, match, body, body)
// node info
res, body = Request(t, port, "GET", "/node_version", nil)

View File

@ -301,8 +301,8 @@ func fauxMerkleModeOpt(bapp *baseapp.BaseApp) {
// /usr/local/go/bin/go test -benchmem -run=^$ github.com/cosmos/cosmos-sdk/cmd/gaia/app -bench ^BenchmarkFullGaiaSimulation$ -SimulationCommit=true -cpuprofile cpu.out
func BenchmarkFullGaiaSimulation(b *testing.B) {
// Setup Gaia application
var logger log.Logger
logger = log.NewNopLogger()
logger := log.NewNopLogger()
var db dbm.DB
dir, _ := ioutil.TempDir("", "goleveldb-gaia-sim")
db, _ = dbm.NewGoLevelDB("Simulation", dir)

View File

@ -8,20 +8,16 @@ import (
"testing"
"time"
"github.com/tendermint/tendermint/libs/cli"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
"github.com/cosmos/cosmos-sdk/server"
"github.com/cosmos/cosmos-sdk/server/mock"
"github.com/spf13/viper"
"github.com/stretchr/testify/require"
abciServer "github.com/tendermint/tendermint/abci/server"
tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
"github.com/tendermint/tendermint/libs/cli"
"github.com/tendermint/tendermint/libs/log"
"github.com/cosmos/cosmos-sdk/server"
"github.com/cosmos/cosmos-sdk/server/mock"
"github.com/spf13/viper"
)
func TestInitCmd(t *testing.T) {

View File

@ -4,6 +4,7 @@ import (
"bufio"
"fmt"
"os"
"reflect"
"strings"
"errors"
@ -147,13 +148,13 @@ func (kb dbKeybase) CreateLedger(name string, algo SigningAlgo, account uint32,
}
pub := priv.PubKey()
return kb.writeLedgerKey(pub, *hdPath, name), nil
return kb.writeLedgerKey(name, pub, *hdPath), nil
}
// CreateOffline creates a new reference to an offline keypair
// It returns the created key info
func (kb dbKeybase) CreateOffline(name string, pub tmcrypto.PubKey) (Info, error) {
return kb.writeOfflineKey(pub, name), nil
return kb.writeOfflineKey(name, pub), nil
}
func (kb *dbKeybase) persistDerivedKey(seed []byte, passwd, name, fullHdPath string) (info Info, err error) {
@ -167,10 +168,10 @@ func (kb *dbKeybase) persistDerivedKey(seed []byte, passwd, name, fullHdPath str
// if we have a password, use it to encrypt the private key and store it
// else store the public key only
if passwd != "" {
info = kb.writeLocalKey(secp256k1.PrivKeySecp256k1(derivedPriv), name, passwd)
info = kb.writeLocalKey(name, secp256k1.PrivKeySecp256k1(derivedPriv), passwd)
} else {
pubk := secp256k1.PrivKeySecp256k1(derivedPriv).PubKey()
info = kb.writeOfflineKey(pubk, name)
info = kb.writeOfflineKey(name, pubk)
}
return
}
@ -342,7 +343,7 @@ func (kb dbKeybase) ImportPubKey(name string, armor string) (err error) {
if err != nil {
return
}
kb.writeOfflineKey(pubKey, name)
kb.writeOfflineKey(name, pubKey)
return
}
@ -390,10 +391,10 @@ func (kb dbKeybase) Update(name, oldpass string, getNewpass func() (string, erro
if err != nil {
return err
}
kb.writeLocalKey(key, name, newpass)
kb.writeLocalKey(name, key, newpass)
return nil
default:
return fmt.Errorf("locally stored key required")
return fmt.Errorf("locally stored key required. Received: %v", reflect.TypeOf(info).String())
}
}
@ -402,29 +403,29 @@ func (kb dbKeybase) CloseDB() {
kb.db.Close()
}
func (kb dbKeybase) writeLocalKey(priv tmcrypto.PrivKey, name, passphrase string) Info {
func (kb dbKeybase) writeLocalKey(name string, priv tmcrypto.PrivKey, passphrase string) Info {
// encrypt private key using passphrase
privArmor := mintkey.EncryptArmorPrivKey(priv, passphrase)
// make Info
pub := priv.PubKey()
info := newLocalInfo(name, pub, privArmor)
kb.writeInfo(info, name)
kb.writeInfo(name, info)
return info
}
func (kb dbKeybase) writeLedgerKey(pub tmcrypto.PubKey, path hd.BIP44Params, name string) Info {
func (kb dbKeybase) writeLedgerKey(name string, pub tmcrypto.PubKey, path hd.BIP44Params) Info {
info := newLedgerInfo(name, pub, path)
kb.writeInfo(info, name)
kb.writeInfo(name, info)
return info
}
func (kb dbKeybase) writeOfflineKey(pub tmcrypto.PubKey, name string) Info {
func (kb dbKeybase) writeOfflineKey(name string, pub tmcrypto.PubKey) Info {
info := newOfflineInfo(name, pub)
kb.writeInfo(info, name)
kb.writeInfo(name, info)
return info
}
func (kb dbKeybase) writeInfo(info Info, name string) {
func (kb dbKeybase) writeInfo(name string, info Info) {
// write the info by key
key := infoKey(name)
kb.db.SetSync(key, writeInfo(info))

View File

@ -2,6 +2,7 @@ package keys
import (
"fmt"
"io/ioutil"
"testing"
"github.com/stretchr/testify/assert"
@ -9,26 +10,84 @@ import (
"github.com/cosmos/cosmos-sdk/crypto/keys/hd"
"github.com/cosmos/cosmos-sdk/crypto/keys/mintkey"
"github.com/cosmos/cosmos-sdk/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519"
dbm "github.com/tendermint/tendermint/libs/db"
"github.com/cosmos/cosmos-sdk/types"
)
func init() {
mintkey.BcryptSecurityParameter = 1
}
func TestKeybaseOpenClose(t *testing.T) {
dir, err := ioutil.TempDir("", "TestKeybaseOpenClose")
assert.Nil(t, err)
kb := New(dbm.NewDB("TestKeybaseOpenClose", dbm.LevelDBBackend, dir))
kb.CloseDB()
// The DB has been closed. At the moment, the expected behaviour is to panic
assert.Panics(t, func() {
_, _ = kb.CreateAccount(
"some_account",
"key pair crucial catch public canyon evil outer stage ten gym tornado",
"", "", 0, 1)
})
}
func TestLanguage(t *testing.T) {
kb := New(dbm.NewMemDB())
_, _, err := kb.CreateMnemonic("something", Japanese, "no_pass", Secp256k1)
assert.Error(t, err)
assert.Equal(t, "unsupported language: only english is supported", err.Error())
}
func TestCreateAccountInvalidMnemonic(t *testing.T) {
kb := New(dbm.NewMemDB())
_, err := kb.CreateAccount(
"some_account",
"malarkey pair crucial catch public canyon evil outer stage ten gym tornado",
"", "", 0, 1)
assert.Error(t, err)
assert.Equal(t, "Invalid mnemonic", err.Error())
}
func TestCreateLedgerUnsupportedAlgo(t *testing.T) {
kb := New(dbm.NewMemDB())
_, err := kb.CreateLedger("some_account", Ed25519, 0, 1)
assert.Error(t, err)
assert.Equal(t, "unsupported signing algo: only secp256k1 is supported", err.Error())
}
func TestCreateLedger(t *testing.T) {
kb := New(dbm.NewMemDB())
// test_cover and test_unit will result in different answers
// test_cover does not compile some dependencies so ledger is disabled
// test_unit may add a ledger mock
// both cases are acceptable
ledger, err := kb.CreateLedger("some_account", Secp256k1, 0, 1)
if err != nil {
assert.Error(t, err)
assert.Equal(t, "ledger nano S: support for ledger devices is not available in this executable", err.Error())
assert.Nil(t, ledger)
} else {
// The mock is available, check that the address is correct
pubKey := ledger.GetPubKey()
addr, err := sdk.Bech32ifyAccPub(pubKey)
assert.NoError(t, err)
assert.Equal(t, "cosmospub1addwnpepqfsdqjr68h7wjg5wacksmqaypasnra232fkgu5sxdlnlu8j22ztxvlqvd65", addr)
}
}
// TestKeyManagement makes sure we can manipulate these keys well
func TestKeyManagement(t *testing.T) {
// make the storage with reasonable defaults
db := dbm.NewMemDB()
cstore := New(
db,
)
cstore := New(db)
algo := Secp256k1
n1, n2, n3 := "personal", "business", "other"
@ -112,9 +171,7 @@ func TestKeyManagement(t *testing.T) {
// TestSignVerify does some detailed checks on how we sign and validate
// signatures
func TestSignVerify(t *testing.T) {
cstore := New(
dbm.NewMemDB(),
)
cstore := New(dbm.NewMemDB())
algo := Secp256k1
n1, n2, n3 := "some dude", "a dudette", "dude-ish"

View File

@ -1,157 +0,0 @@
// +build cgo,ledger,test_real_ledger
package crypto
import (
"fmt"
"testing"
"github.com/cosmos/cosmos-sdk/crypto/keys/hd"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto/encoding/amino"
ledger "github.com/zondax/ledger-cosmos-go"
)
const (
// These tests expect a ledger device initialized to the following mnemonic
testMnemonic = "equip will roof matter pink blind book anxiety banner elbow sun young"
)
func TestDiscoverDevice(t *testing.T) {
device, err := discoverLedger()
require.NoError(t, err)
require.NotNil(t, device)
defer device.Close()
}
func TestDiscoverDeviceTwice(t *testing.T) {
// We expect the second call not to find a device
device, err := discoverLedger()
require.NoError(t, err)
require.NotNil(t, device)
defer device.Close()
device2, err := discoverLedger()
require.Error(t, err)
require.Equal(t, "no ledger connected", err.Error())
require.Nil(t, device2)
}
func TestDiscoverDeviceTwiceClosing(t *testing.T) {
{
device, err := ledger.FindLedgerCosmosUserApp()
require.NoError(t, err)
require.NotNil(t, device)
require.NoError(t, device.Close())
}
device2, err := discoverLedger()
require.NoError(t, err)
require.NotNil(t, device2)
require.NoError(t, device2.Close())
}
func TestPublicKey(t *testing.T) {
path := *hd.NewFundraiserParams(0, 0)
priv, err := NewPrivKeyLedgerSecp256k1(path)
require.Nil(t, err, "%s", err)
require.NotNil(t, priv)
pubKeyAddr, err := sdk.Bech32ifyAccPub(priv.PubKey())
require.NoError(t, err)
require.Equal(t, "cosmospub1addwnpepqd87l8xhcnrrtzxnkql7k55ph8fr9jarf4hn6udwukfprlalu8lgw0urza0", pubKeyAddr, "Is your device using test mnemonic: %s ?", testMnemonic)
require.Equal(t, "5075624b6579536563703235366b317b303334464546394344374334433633353838443342303"+
"3464542353238314239443233324342413334443646334437314145453539323131464642464531464538377d",
fmt.Sprintf("%x", priv.PubKey()))
}
func TestPublicKeyHDPath(t *testing.T) {
expectedAnswers := []string{
"cosmospub1addwnpepqd87l8xhcnrrtzxnkql7k55ph8fr9jarf4hn6udwukfprlalu8lgw0urza0",
"cosmospub1addwnpepqfsdqjr68h7wjg5wacksmqaypasnra232fkgu5sxdlnlu8j22ztxvlqvd65",
"cosmospub1addwnpepqw3xwqun6q43vtgw6p4qspq7srvxhcmvq4jrx5j5ma6xy3r7k6dtxmrkh3d",
"cosmospub1addwnpepqvez9lrp09g8w7gkv42y4yr5p6826cu28ydrhrujv862yf4njmqyyjr4pjs",
"cosmospub1addwnpepq06hw3enfrtmq8n67teytcmtnrgcr0yntmyt25kdukfjkerdc7lqg32rcz7",
"cosmospub1addwnpepqg3trf2gd0s2940nckrxherwqhgmm6xd5h4pcnrh4x7y35h6yafmcpk5qns",
"cosmospub1addwnpepqdm6rjpx6wsref8wjn7ym6ntejet430j4szpngfgc20caz83lu545vuv8hp",
"cosmospub1addwnpepqvdhtjzy2wf44dm03jxsketxc07vzqwvt3vawqqtljgsr9s7jvydjmt66ew",
"cosmospub1addwnpepqwystfpyxwcava7v3t7ndps5xzu6s553wxcxzmmnxevlzvwrlqpzz695nw9",
"cosmospub1addwnpepqw970u6gjqkccg9u3rfj99857wupj2z9fqfzy2w7e5dd7xn7kzzgkgqch0r",
}
// Check with device
for i := uint32(0); i < 10; i++ {
path := *hd.NewFundraiserParams(0, i)
fmt.Printf("Checking keys at %v\n", path)
priv, err := NewPrivKeyLedgerSecp256k1(path)
require.Nil(t, err, "%s", err)
require.NotNil(t, priv)
pubKeyAddr, err := sdk.Bech32ifyAccPub(priv.PubKey())
require.NoError(t, err)
require.Equal(t, expectedAnswers[i], pubKeyAddr, "Is your device using test mnemonic: %s ?", testMnemonic)
}
}
func getFakeTx(accountNumber uint32) []byte {
tmp := fmt.Sprintf(
`{"account_number":"%d","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"5000"},"memo":"memo","msgs":[[""]],"sequence":"6"}`,
accountNumber)
return []byte(tmp)
}
func TestSignaturesHD(t *testing.T) {
for account := uint32(0); account < 100; account += 30 {
msg := getFakeTx(account)
path := *hd.NewFundraiserParams(account, account/5)
fmt.Printf("Checking signature at %v\n", path)
priv, err := NewPrivKeyLedgerSecp256k1(path)
require.Nil(t, err, "%s", err)
pub := priv.PubKey()
sig, err := priv.Sign(msg)
require.Nil(t, err)
valid := pub.VerifyBytes(msg, sig)
require.True(t, valid, "Is your device using test mnemonic: %s ?", testMnemonic)
}
}
func TestRealLedgerSecp256k1(t *testing.T) {
msg := getFakeTx(50)
path := *hd.NewFundraiserParams(0, 0)
priv, err := NewPrivKeyLedgerSecp256k1(path)
require.Nil(t, err, "%s", err)
pub := priv.PubKey()
sig, err := priv.Sign(msg)
require.Nil(t, err)
valid := pub.VerifyBytes(msg, sig)
require.True(t, valid)
// now, let's serialize the public key and make sure it still works
bs := priv.PubKey().Bytes()
pub2, err := cryptoAmino.PubKeyFromBytes(bs)
require.Nil(t, err, "%+v", err)
// make sure we get the same pubkey when we load from disk
require.Equal(t, pub, pub2)
// signing with the loaded key should match the original pubkey
sig, err = priv.Sign(msg)
require.Nil(t, err)
valid = pub.VerifyBytes(msg, sig)
require.True(t, valid)
// make sure pubkeys serialize properly as well
bs = pub.Bytes()
bpub, err := cryptoAmino.PubKeyFromBytes(bs)
require.NoError(t, err)
require.Equal(t, pub, bpub)
}

79
crypto/ledger_mock.go Normal file
View File

@ -0,0 +1,79 @@
// +build ledger,test_ledger_mock
package crypto
import (
"github.com/btcsuite/btcd/btcec"
"github.com/cosmos/cosmos-sdk/crypto/keys/hd"
"github.com/cosmos/cosmos-sdk/tests"
"github.com/cosmos/go-bip39"
"github.com/pkg/errors"
secp256k1 "github.com/tendermint/btcd/btcec"
"github.com/tendermint/tendermint/crypto"
)
// If ledger support (build tag) has been enabled, which implies a CGO dependency,
// set the discoverLedger function which is responsible for loading the Ledger
// device at runtime or returning an error.
func init() {
discoverLedger = func() (LedgerSECP256K1, error) {
return LedgerSECP256K1Mock{}, nil
}
}
type LedgerSECP256K1Mock struct {
}
func (mock LedgerSECP256K1Mock) Close() error {
return nil
}
func (mock LedgerSECP256K1Mock) GetPublicKeySECP256K1(derivationPath []uint32) ([]byte, error) {
if derivationPath[0] != 44 {
return nil, errors.New("Invalid derivation path")
}
if derivationPath[1] != 118 {
return nil, errors.New("Invalid derivation path")
}
seed, err := bip39.NewSeedWithErrorChecking(tests.TestMnemonic, "")
if err != nil {
return nil, err
}
path := hd.NewParams(derivationPath[0], derivationPath[1], derivationPath[2], derivationPath[3] != 0, derivationPath[4])
masterPriv, ch := hd.ComputeMastersFromSeed(seed)
derivedPriv, err := hd.DerivePrivateKeyForPath(masterPriv, ch, path.String())
if err != nil {
return nil, err
}
_, pubkeyObject := secp256k1.PrivKeyFromBytes(secp256k1.S256(), derivedPriv[:])
return pubkeyObject.SerializeUncompressed(), nil
}
func (mock LedgerSECP256K1Mock) SignSECP256K1(derivationPath []uint32, message []byte) ([]byte, error) {
path := hd.NewParams(derivationPath[0], derivationPath[1], derivationPath[2], derivationPath[3] != 0, derivationPath[4])
seed, err := bip39.NewSeedWithErrorChecking(tests.TestMnemonic, "")
if err != nil {
return nil, err
}
masterPriv, ch := hd.ComputeMastersFromSeed(seed)
derivedPriv, err := hd.DerivePrivateKeyForPath(masterPriv, ch, path.String())
if err != nil {
return nil, err
}
priv, _ := secp256k1.PrivKeyFromBytes(secp256k1.S256(), derivedPriv[:])
sig, err := priv.Sign(crypto.Sha256(message))
if err != nil {
return nil, err
}
// Need to return DER as the ledger does
sig2 := btcec.Signature{R: sig.R, S: sig.S}
return sig2.Serialize(), nil
}

17
crypto/ledger_notavail.go Normal file
View File

@ -0,0 +1,17 @@
// +build !cgo !ledger
// test_ledger_mock
package crypto
import (
"github.com/pkg/errors"
)
// If ledger support (build tag) has been enabled, which implies a CGO dependency,
// set the discoverLedger function which is responsible for loading the Ledger
// device at runtime or returning an error.
func init() {
discoverLedger = func() (LedgerSECP256K1, error) {
return nil, errors.New("support for ledger devices is not available in this executable")
}
}

View File

@ -1,10 +1,8 @@
// +build cgo,ledger
// +build cgo,ledger,!test_ledger_mock
package crypto
import (
ledger "github.com/zondax/ledger-cosmos-go"
)
import ledger "github.com/zondax/ledger-cosmos-go"
// If ledger support (build tag) has been enabled, which implies a CGO dependency,
// set the discoverLedger function which is responsible for loading the Ledger

View File

@ -45,9 +45,6 @@ type (
// NewPrivKeyLedgerSecp256k1 will generate a new key and store the public key
// for later use.
//
// CONTRACT: The ledger device, ledgerDevice, must be loaded and set prior to
// any creation of a PrivKeyLedgerSecp256k1.
func NewPrivKeyLedgerSecp256k1(path hd.BIP44Params) (tmcrypto.PrivKey, error) {
device, err := getLedgerDevice()
if err != nil {
@ -103,8 +100,8 @@ func (pkl PrivKeyLedgerSecp256k1) Bytes() []byte {
// Equals implements the PrivKey interface. It makes sure two private keys
// refer to the same public key.
func (pkl PrivKeyLedgerSecp256k1) Equals(other tmcrypto.PrivKey) bool {
if ledger, ok := other.(*PrivKeyLedgerSecp256k1); ok {
return pkl.CachedPubKey.Equals(ledger.CachedPubKey)
if otherKey, ok := other.(PrivKeyLedgerSecp256k1); ok {
return pkl.CachedPubKey.Equals(otherKey.CachedPubKey)
}
return false
}

View File

@ -1,13 +1,19 @@
package crypto
import (
"fmt"
"testing"
"github.com/cosmos/cosmos-sdk/tests"
tmcrypto "github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/encoding/amino"
"github.com/cosmos/cosmos-sdk/crypto/keys/hd"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"
)
// This tests assume a ledger is not plugged in
func TestLedgerErrorHandling(t *testing.T) {
// first, try to generate a key, must return an error
// (no panic)
@ -15,3 +21,135 @@ func TestLedgerErrorHandling(t *testing.T) {
_, err := NewPrivKeyLedgerSecp256k1(path)
require.Error(t, err)
}
func TestPublicKey(t *testing.T) {
path := *hd.NewFundraiserParams(0, 0)
priv, err := NewPrivKeyLedgerSecp256k1(path)
require.Nil(t, err, "%s", err)
require.NotNil(t, priv)
pubKeyAddr, err := sdk.Bech32ifyAccPub(priv.PubKey())
require.NoError(t, err)
require.Equal(t, "cosmospub1addwnpepqd87l8xhcnrrtzxnkql7k55ph8fr9jarf4hn6udwukfprlalu8lgw0urza0",
pubKeyAddr, "Is your device using test mnemonic: %s ?", tests.TestMnemonic)
require.Equal(t, "5075624b6579536563703235366b317b303334464546394344374334433633353838443342303"+
"3464542353238314239443233324342413334443646334437314145453539323131464642464531464538377d",
fmt.Sprintf("%x", priv.PubKey()))
}
func TestPublicKeyHDPath(t *testing.T) {
expectedAnswers := []string{
"cosmospub1addwnpepqd87l8xhcnrrtzxnkql7k55ph8fr9jarf4hn6udwukfprlalu8lgw0urza0",
"cosmospub1addwnpepqfsdqjr68h7wjg5wacksmqaypasnra232fkgu5sxdlnlu8j22ztxvlqvd65",
"cosmospub1addwnpepqw3xwqun6q43vtgw6p4qspq7srvxhcmvq4jrx5j5ma6xy3r7k6dtxmrkh3d",
"cosmospub1addwnpepqvez9lrp09g8w7gkv42y4yr5p6826cu28ydrhrujv862yf4njmqyyjr4pjs",
"cosmospub1addwnpepq06hw3enfrtmq8n67teytcmtnrgcr0yntmyt25kdukfjkerdc7lqg32rcz7",
"cosmospub1addwnpepqg3trf2gd0s2940nckrxherwqhgmm6xd5h4pcnrh4x7y35h6yafmcpk5qns",
"cosmospub1addwnpepqdm6rjpx6wsref8wjn7ym6ntejet430j4szpngfgc20caz83lu545vuv8hp",
"cosmospub1addwnpepqvdhtjzy2wf44dm03jxsketxc07vzqwvt3vawqqtljgsr9s7jvydjmt66ew",
"cosmospub1addwnpepqwystfpyxwcava7v3t7ndps5xzu6s553wxcxzmmnxevlzvwrlqpzz695nw9",
"cosmospub1addwnpepqw970u6gjqkccg9u3rfj99857wupj2z9fqfzy2w7e5dd7xn7kzzgkgqch0r",
}
const numIters = 10
privKeys := make([]tmcrypto.PrivKey, numIters)
// Check with device
for i := uint32(0); i < 10; i++ {
path := *hd.NewFundraiserParams(0, i)
fmt.Printf("Checking keys at %v\n", path)
priv, err := NewPrivKeyLedgerSecp256k1(path)
require.Nil(t, err, "%s", err)
require.NotNil(t, priv)
// Check other methods
require.NoError(t, priv.(PrivKeyLedgerSecp256k1).ValidateKey())
tmp := priv.(PrivKeyLedgerSecp256k1)
(&tmp).AssertIsPrivKeyInner()
pubKeyAddr, err := sdk.Bech32ifyAccPub(priv.PubKey())
require.NoError(t, err)
require.Equal(t,
expectedAnswers[i], pubKeyAddr,
"Is your device using test mnemonic: %s ?", tests.TestMnemonic)
// Store and restore
serializedPk := priv.Bytes()
require.NotNil(t, serializedPk)
require.Equal(t, 44, len(serializedPk))
privKeys[i] = priv
}
// Now check equality
for i := 0; i < 10; i++ {
for j := 0; j < 10; j++ {
require.Equal(t, i == j, privKeys[i].Equals(privKeys[j]))
require.Equal(t, i == j, privKeys[j].Equals(privKeys[i]))
}
}
}
func getFakeTx(accountNumber uint32) []byte {
tmp := fmt.Sprintf(
`{"account_number":"%d","chain_id":"1234","fee":{"amount":[{"amount":"150","denom":"atom"}],"gas":"5000"},"memo":"memo","msgs":[[""]],"sequence":"6"}`,
accountNumber)
return []byte(tmp)
}
func TestSignaturesHD(t *testing.T) {
for account := uint32(0); account < 100; account += 30 {
msg := getFakeTx(account)
path := *hd.NewFundraiserParams(account, account/5)
fmt.Printf("Checking signature at %v --- PLEASE REVIEW AND ACCEPT IN THE DEVICE\n", path)
priv, err := NewPrivKeyLedgerSecp256k1(path)
require.Nil(t, err, "%s", err)
pub := priv.PubKey()
sig, err := priv.Sign(msg)
require.Nil(t, err)
valid := pub.VerifyBytes(msg, sig)
require.True(t, valid, "Is your device using test mnemonic: %s ?", tests.TestMnemonic)
}
}
func TestRealLedgerSecp256k1(t *testing.T) {
msg := getFakeTx(50)
path := *hd.NewFundraiserParams(0, 0)
priv, err := NewPrivKeyLedgerSecp256k1(path)
require.Nil(t, err, "%s", err)
pub := priv.PubKey()
sig, err := priv.Sign(msg)
require.Nil(t, err)
valid := pub.VerifyBytes(msg, sig)
require.True(t, valid)
// now, let's serialize the public key and make sure it still works
bs := priv.PubKey().Bytes()
pub2, err := cryptoAmino.PubKeyFromBytes(bs)
require.Nil(t, err, "%+v", err)
// make sure we get the same pubkey when we load from disk
require.Equal(t, pub, pub2)
// signing with the loaded key should match the original pubkey
sig, err = priv.Sign(msg)
require.Nil(t, err)
valid = pub.VerifyBytes(msg, sig)
require.True(t, valid)
// make sure pubkeys serialize properly as well
bs = pub.Bytes()
bpub, err := cryptoAmino.PubKeyFromBytes(bs)
require.NoError(t, err)
require.Equal(t, pub, bpub)
}

View File

@ -120,7 +120,7 @@ func interceptLoadConfig() (conf *cfg.Config, err error) {
// validate the config with the sdk's requirements.
func validateConfig(conf *cfg.Config) error {
if conf.Consensus.CreateEmptyBlocks == false {
if !conf.Consensus.CreateEmptyBlocks {
return errors.New("config option CreateEmptyBlocks = false is currently unsupported")
}
return nil

View File

@ -293,7 +293,7 @@ func newIAVLIterator(tree *iavl.ImmutableTree, start, end []byte, ascending bool
start: types.Cp(start),
end: types.Cp(end),
ascending: ascending,
iterCh: make(chan cmn.KVPair, 0), // Set capacity > 0?
iterCh: make(chan cmn.KVPair), // Set capacity > 0?
quitCh: make(chan struct{}),
initCh: make(chan struct{}),
}

View File

@ -1,18 +1,16 @@
package prefix
import (
"math/rand"
"crypto/rand"
"testing"
"github.com/stretchr/testify/require"
tiavl "github.com/tendermint/iavl"
dbm "github.com/tendermint/tendermint/libs/db"
"github.com/cosmos/cosmos-sdk/store/dbadapter"
"github.com/cosmos/cosmos-sdk/store/gaskv"
"github.com/cosmos/cosmos-sdk/store/iavl"
"github.com/cosmos/cosmos-sdk/store/types"
"github.com/stretchr/testify/require"
tiavl "github.com/tendermint/iavl"
dbm "github.com/tendermint/tendermint/libs/db"
)
// copied from iavl/store_test.go

View File

@ -33,11 +33,7 @@ func RequireProof(subpath string) bool {
// Currently, only when query subpath is "/key", will proof be included in
// response. If there are some changes about proof building in iavlstore.go,
// we must change code here to keep consistency with iavlStore#Query.
if subpath == "/key" {
return true
}
return false
return subpath == "/key"
}
//-----------------------------------------------------------------------------

6
tests/knownValues.go Normal file
View File

@ -0,0 +1,6 @@
package tests
const (
// Tests expect a ledger device initialized to the following mnemonic
TestMnemonic = "equip will roof matter pink blind book anxiety banner elbow sun young"
)

View File

@ -5,8 +5,8 @@ PKGS=$(go list ./... | grep -v /vendor/ | grep -v github.com/cosmos/cosmos-sdk/c
set -e
echo "mode: atomic" > coverage.txt
for pkg in ${PKGS}; do
go test -v -timeout 30m -race -coverprofile=profile.out -covermode=atomic "$pkg"
for pkg in ${PKGS[@]}; do
go test -v -timeout 30m -race -coverprofile=profile.out -covermode=atomic -tags='ledger test_ledger_mock' "$pkg"
if [ -f profile.out ]; then
tail -n +2 profile.out >> coverage.txt;
rm profile.out

View File

@ -4,6 +4,7 @@ import (
"fmt"
"io/ioutil"
"net/http"
"os"
"time"
"strings"
@ -201,3 +202,21 @@ var cdc = amino.NewCodec()
func init() {
ctypes.RegisterAmino(cdc)
}
// GetTempDir creates a temporary directory and returns a clean up function
// to be deferred
func GetTempDir(prefix string) (string, func(), error) {
rootDir, err := ioutil.TempDir("", prefix)
if err != nil {
return "", nil, err
}
cleanUp := func() {
err := os.RemoveAll(rootDir)
if err != nil {
panic(err)
}
}
return rootDir, cleanUp, nil
}

View File

@ -86,7 +86,7 @@ func (aa AccAddress) Equals(aa2 Address) bool {
return true
}
return bytes.Compare(aa.Bytes(), aa2.Bytes()) == 0
return bytes.Equal(aa.Bytes(), aa2.Bytes())
}
// Returns boolean for whether an AccAddress is empty
@ -96,7 +96,7 @@ func (aa AccAddress) Empty() bool {
}
aa2 := AccAddress{}
return bytes.Compare(aa.Bytes(), aa2.Bytes()) == 0
return bytes.Equal(aa.Bytes(), aa2.Bytes())
}
// Marshal returns the raw address bytes. It is needed for protobuf
@ -155,7 +155,7 @@ func (aa AccAddress) String() string {
func (aa AccAddress) Format(s fmt.State, verb rune) {
switch verb {
case 's':
s.Write([]byte(fmt.Sprintf("%s", aa.String())))
s.Write([]byte(aa.String()))
case 'p':
s.Write([]byte(fmt.Sprintf("%p", aa)))
default:
@ -202,7 +202,7 @@ func (va ValAddress) Equals(va2 Address) bool {
return true
}
return bytes.Compare(va.Bytes(), va2.Bytes()) == 0
return bytes.Equal(va.Bytes(), va2.Bytes())
}
// Returns boolean for whether an AccAddress is empty
@ -212,7 +212,7 @@ func (va ValAddress) Empty() bool {
}
va2 := ValAddress{}
return bytes.Compare(va.Bytes(), va2.Bytes()) == 0
return bytes.Equal(va.Bytes(), va2.Bytes())
}
// Marshal returns the raw address bytes. It is needed for protobuf
@ -272,7 +272,7 @@ func (va ValAddress) String() string {
func (va ValAddress) Format(s fmt.State, verb rune) {
switch verb {
case 's':
s.Write([]byte(fmt.Sprintf("%s", va.String())))
s.Write([]byte(va.String()))
case 'p':
s.Write([]byte(fmt.Sprintf("%p", va)))
default:
@ -324,7 +324,7 @@ func (ca ConsAddress) Equals(ca2 Address) bool {
return true
}
return bytes.Compare(ca.Bytes(), ca2.Bytes()) == 0
return bytes.Equal(ca.Bytes(), ca2.Bytes())
}
// Returns boolean for whether an ConsAddress is empty
@ -334,7 +334,7 @@ func (ca ConsAddress) Empty() bool {
}
ca2 := ConsAddress{}
return bytes.Compare(ca.Bytes(), ca2.Bytes()) == 0
return bytes.Equal(ca.Bytes(), ca2.Bytes())
}
// Marshal returns the raw address bytes. It is needed for protobuf
@ -394,7 +394,7 @@ func (ca ConsAddress) String() string {
func (ca ConsAddress) Format(s fmt.State, verb rune) {
switch verb {
case 's':
s.Write([]byte(fmt.Sprintf("%s", ca.String())))
s.Write([]byte(ca.String()))
case 'p':
s.Write([]byte(fmt.Sprintf("%p", ca)))
default:

View File

@ -5,13 +5,11 @@ import (
"math/rand"
"testing"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto/ed25519"
"strings"
"github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto/ed25519"
)
var invalidStrs = []string{

View File

@ -19,10 +19,7 @@ type CodespaceType string
// IsOK - is everything okay?
func (code CodeType) IsOK() bool {
if code == CodeOK {
return true
}
return false
return code == CodeOK
}
// SDK error codes

View File

@ -30,8 +30,7 @@ func TestCommitID(t *testing.T) {
var empty CommitID
require.True(t, empty.IsZero())
var nonempty CommitID
nonempty = CommitID{
var nonempty = CommitID{
Version: 1,
Hash: []byte("testhash"),
}

View File

@ -164,7 +164,7 @@ func (vo VoteOption) String() string {
func (vo VoteOption) Format(s fmt.State, verb rune) {
switch verb {
case 's':
s.Write([]byte(fmt.Sprintf("%s", vo.String())))
s.Write([]byte(vo.String()))
default:
s.Write([]byte(fmt.Sprintf("%v", byte(vo))))
}

View File

@ -238,7 +238,7 @@ func GenTx(msgs []sdk.Msg, accnums []uint64, seq []uint64, priv ...crypto.PrivKe
// GeneratePrivKeys generates a total n Ed25519 private keys.
func GeneratePrivKeys(n int) (keys []crypto.PrivKey) {
// TODO: Randomize this between ed25519 and secp256k1
keys = make([]crypto.PrivKey, n, n)
keys = make([]crypto.PrivKey, n)
for i := 0; i < n; i++ {
keys[i] = ed25519.GenPrivKey()
}
@ -249,8 +249,8 @@ func GeneratePrivKeys(n int) (keys []crypto.PrivKey) {
// GeneratePrivKeyAddressPairs generates a total of n private key, address
// pairs.
func GeneratePrivKeyAddressPairs(n int) (keys []crypto.PrivKey, addrs []sdk.AccAddress) {
keys = make([]crypto.PrivKey, n, n)
addrs = make([]sdk.AccAddress, n, n)
keys = make([]crypto.PrivKey, n)
addrs = make([]sdk.AccAddress, n)
for i := 0; i < n; i++ {
if rand.Int63()%2 == 0 {
keys[i] = secp256k1.GenPrivKey()
@ -265,8 +265,8 @@ func GeneratePrivKeyAddressPairs(n int) (keys []crypto.PrivKey, addrs []sdk.AccA
// GeneratePrivKeyAddressPairsFromRand generates a total of n private key, address
// pairs using the provided randomness source.
func GeneratePrivKeyAddressPairsFromRand(rand *rand.Rand, n int) (keys []crypto.PrivKey, addrs []sdk.AccAddress) {
keys = make([]crypto.PrivKey, n, n)
addrs = make([]sdk.AccAddress, n, n)
keys = make([]crypto.PrivKey, n)
addrs = make([]sdk.AccAddress, n)
for i := 0; i < n; i++ {
secret := make([]byte, 32)
_, err := rand.Read(secret)
@ -287,7 +287,7 @@ func GeneratePrivKeyAddressPairsFromRand(rand *rand.Rand, n int) (keys []crypto.
// provided addresses and coin denominations.
// nolint: errcheck
func RandomSetGenesis(r *rand.Rand, app *App, addrs []sdk.AccAddress, denoms []string) {
accts := make([]auth.Account, len(addrs), len(addrs))
accts := make([]auth.Account, len(addrs))
randCoinIntervals := []BigInterval{
{sdk.NewIntWithDecimal(1, 0), sdk.NewIntWithDecimal(1, 1)},
{sdk.NewIntWithDecimal(1, 2), sdk.NewIntWithDecimal(1, 3)},
@ -295,7 +295,7 @@ func RandomSetGenesis(r *rand.Rand, app *App, addrs []sdk.AccAddress, denoms []s
}
for i := 0; i < len(accts); i++ {
coins := make([]sdk.Coin, len(denoms), len(denoms))
coins := make([]sdk.Coin, len(denoms))
// generate a random coin for each denomination
for j := 0; j < len(denoms); j++ {
@ -328,7 +328,7 @@ func GetAllAccounts(mapper auth.AccountKeeper, ctx sdk.Context) []auth.Account {
// that they differ only by having the sequence numbers incremented between
// every transaction.
func GenSequenceOfTxs(msgs []sdk.Msg, accnums []uint64, initSeqNums []uint64, numToGenerate int, priv ...crypto.PrivKey) []auth.StdTx {
txs := make([]auth.StdTx, numToGenerate, numToGenerate)
txs := make([]auth.StdTx, numToGenerate)
for i := 0; i < numToGenerate; i++ {
txs[i] = GenTx(msgs, accnums, initSeqNums, priv...)
incrementAllSequenceNumbers(initSeqNums)

View File

@ -222,7 +222,7 @@ func (k Keeper) InsertUBDQueue(ctx sdk.Context, ubd types.UnbondingDelegation,
completionTime time.Time) {
timeSlice := k.GetUBDQueueTimeSlice(ctx, completionTime)
dvPair := types.DVPair{ubd.DelegatorAddr, ubd.ValidatorAddr}
dvPair := types.DVPair{DelegatorAddr: ubd.DelegatorAddr, ValidatorAddr: ubd.ValidatorAddr}
if len(timeSlice) == 0 {
k.SetUBDQueueTimeSlice(ctx, completionTime, []types.DVPair{dvPair})
} else {
@ -314,10 +314,7 @@ func (k Keeper) HasReceivingRedelegation(ctx sdk.Context,
iterator := sdk.KVStorePrefixIterator(store, prefix)
defer iterator.Close()
if iterator.Valid() {
return true
}
return false
return iterator.Valid()
}
// HasMaxRedelegationEntries - redelegation has maximum number of entries
@ -411,7 +408,11 @@ func (k Keeper) InsertRedelegationQueue(ctx sdk.Context, red types.Redelegation,
completionTime time.Time) {
timeSlice := k.GetRedelegationQueueTimeSlice(ctx, completionTime)
dvvTriplet := types.DVVTriplet{red.DelegatorAddr, red.ValidatorSrcAddr, red.ValidatorDstAddr}
dvvTriplet := types.DVVTriplet{
DelegatorAddr: red.DelegatorAddr,
ValidatorSrcAddr: red.ValidatorSrcAddr,
ValidatorDstAddr: red.ValidatorDstAddr}
if len(timeSlice) == 0 {
k.SetRedelegationQueueTimeSlice(ctx, completionTime, []types.DVVTriplet{dvvTriplet})
} else {

View File

@ -166,7 +166,7 @@ func TestAddr(addr string, bech string) sdk.AccAddress {
if err != nil {
panic(err)
}
if bytes.Compare(bechres, res) != 0 {
if !bytes.Equal(bechres, res) {
panic("Bech decode and hex decode don't match")
}

View File

@ -12,6 +12,10 @@ import (
"github.com/cosmos/cosmos-sdk/x/staking/keeper"
)
const (
noOperation = "no-operation"
)
// SimulateMsgCreateValidator
func SimulateMsgCreateValidator(m auth.AccountKeeper, k staking.Keeper) simulation.Operation {
handler := staking.NewHandler(k)
@ -39,7 +43,7 @@ func SimulateMsgCreateValidator(m auth.AccountKeeper, k staking.Keeper) simulati
}
if amount.Equal(sdk.ZeroInt()) {
return "no-operation", nil, nil
return noOperation, nil, nil
}
selfDelegation := sdk.NewCoin(denom, amount)
@ -146,13 +150,13 @@ func SimulateMsgUndelegate(m auth.AccountKeeper, k staking.Keeper) simulation.Op
delegatorAddress := delegatorAcc.Address
delegations := k.GetAllDelegatorDelegations(ctx, delegatorAddress)
if len(delegations) == 0 {
return "no-operation", nil, nil
return noOperation, nil, nil
}
delegation := delegations[r.Intn(len(delegations))]
numShares := simulation.RandomDecAmount(r, delegation.Shares)
if numShares.Equal(sdk.ZeroDec()) {
return "no-operation", nil, nil
return noOperation, nil, nil
}
msg := staking.MsgUndelegate{
DelegatorAddr: delegatorAddress,
@ -194,7 +198,7 @@ func SimulateMsgBeginRedelegate(m auth.AccountKeeper, k staking.Keeper) simulati
amount = simulation.RandomAmount(r, amount)
}
if amount.Equal(sdk.ZeroInt()) {
return "no-operation", nil, nil
return noOperation, nil, nil
}
msg := staking.MsgBeginRedelegate{
DelegatorAddr: delegatorAddress,