Merge PR #3517: Increasing test coverage in keys/client package
This commit is contained in:
parent
cff985ffc5
commit
b5fdb83830
|
@ -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
|
||||
|
|
7
Makefile
7
Makefile
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"})
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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[:]))
|
||||
}
|
|
@ -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])
|
||||
})
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
|
@ -22,7 +22,7 @@ func Commands() *cobra.Command {
|
|||
cmd.AddCommand(
|
||||
mnemonicKeyCommand(),
|
||||
addKeyCommand(),
|
||||
listKeysCmd,
|
||||
listKeysCmd(),
|
||||
showKeysCmd(),
|
||||
client.LineBreak,
|
||||
deleteKeyCommand(),
|
||||
|
|
|
@ -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)
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
//}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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?
|
||||
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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")
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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{}),
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -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"
|
||||
)
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"),
|
||||
}
|
||||
|
|
|
@ -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))))
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue