Merge branch 'master' into bez/5444-gov-proto-enc

This commit is contained in:
Alexander Bezobchuk 2020-03-02 13:08:26 -05:00 committed by GitHub
commit c0384a1b91
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
55 changed files with 1247 additions and 196 deletions

View File

@ -3,6 +3,7 @@
# timeout: 5m # timeout: 5m
linters: linters:
disable-all: true
enable: enable:
- bodyclose - bodyclose
- deadcode - deadcode
@ -30,8 +31,6 @@ linters:
- unconvert - unconvert
- unused - unused
- misspell - misspell
disable:
- errcheck
issues: issues:
exclude-rules: exclude-rules:

View File

@ -1,7 +1,7 @@
pull_request_rules: pull_request_rules:
- name: automerge to master with label automerge and branch protection passing - name: automerge to master with label automerge and branch protection passing
conditions: conditions:
- "#approved-reviews-by>=1" - "#approved-reviews-by>1"
- base=master - base=master
- label=automerge - label=automerge
actions: actions:

View File

@ -43,6 +43,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
balances or a single balance by denom when the `denom` query parameter is present. balances or a single balance by denom when the `denom` query parameter is present.
* (client) [\#5640](https://github.com/cosmos/cosmos-sdk/pull/5640) The rest server endpoint `/swagger-ui/` is replaced by ´/´. * (client) [\#5640](https://github.com/cosmos/cosmos-sdk/pull/5640) The rest server endpoint `/swagger-ui/` is replaced by ´/´.
* (x/auth) [\#5702](https://github.com/cosmos/cosmos-sdk/pull/5702) The `x/auth` querier route has changed from `"acc"` to `"auth"`. * (x/auth) [\#5702](https://github.com/cosmos/cosmos-sdk/pull/5702) The `x/auth` querier route has changed from `"acc"` to `"auth"`.
* (store/types) [\#5730](https://github.com/cosmos/cosmos-sdk/pull/5730) store.types.Cp() is removed in favour of types.CopyBytes().
### API Breaking Changes ### API Breaking Changes
@ -60,6 +61,7 @@ and provided directly the IAVL store.
* (modules) [\#5572](https://github.com/cosmos/cosmos-sdk/pull/5572) Move account balance logic and APIs from `x/auth` to `x/bank`. * (modules) [\#5572](https://github.com/cosmos/cosmos-sdk/pull/5572) Move account balance logic and APIs from `x/auth` to `x/bank`.
* (types) [\#5533](https://github.com/cosmos/cosmos-sdk/pull/5533) Refactored `AppModuleBasic` and `AppModuleGenesis` * (types) [\#5533](https://github.com/cosmos/cosmos-sdk/pull/5533) Refactored `AppModuleBasic` and `AppModuleGenesis`
to now accept a `codec.JSONMarshaler` for modular serialization of genesis state. to now accept a `codec.JSONMarshaler` for modular serialization of genesis state.
* (crypto/keys) [\#5735](https://github.com/cosmos/cosmos-sdk/pull/5735) Keyring's Update() function is now no-op.
### Features ### Features
@ -148,6 +150,8 @@ Buffers for state serialization instead of Amino.
* (rest) [\#5648](https://github.com/cosmos/cosmos-sdk/pull/5648) Enhance /txs usability: * (rest) [\#5648](https://github.com/cosmos/cosmos-sdk/pull/5648) Enhance /txs usability:
* Add `tx.minheight` key to filter transaction with an inclusive minimum block height * Add `tx.minheight` key to filter transaction with an inclusive minimum block height
* Add `tx.maxheight` key to filter transaction with an inclusive maximum block height * Add `tx.maxheight` key to filter transaction with an inclusive maximum block height
* (server) [\#5709](https://github.com/cosmos/cosmos-sdk/pull/5709) There are two new flags for pruning, `--pruning-keep-every`
and `--pruning-snapshot-every` as an alternative to `--pruning`. They allow to fine tune the strategy for pruning the state.
## [v0.38.1] - 2020-02-11 ## [v0.38.1] - 2020-02-11

View File

@ -26,6 +26,7 @@ build: go.sum
mocks: $(MOCKS_DIR) mocks: $(MOCKS_DIR)
mockgen -source=x/auth/types/account_retriever.go -package mocks -destination tests/mocks/account_retriever.go mockgen -source=x/auth/types/account_retriever.go -package mocks -destination tests/mocks/account_retriever.go
mockgen -package mocks -destination tests/mocks/tendermint_tm_db_DB.go github.com/tendermint/tm-db DB
.PHONY: mocks .PHONY: mocks
$(MOCKS_DIR): $(MOCKS_DIR):

View File

@ -39,7 +39,7 @@ func Test_runAddCmdLedgerWithCustomCoinType(t *testing.T) {
// Prepare a keybase // Prepare a keybase
kbHome, kbCleanUp := tests.NewTestCaseDir(t) kbHome, kbCleanUp := tests.NewTestCaseDir(t)
require.NotNil(t, kbHome) require.NotNil(t, kbHome)
defer kbCleanUp() t.Cleanup(kbCleanUp)
viper.Set(flags.FlagHome, kbHome) viper.Set(flags.FlagHome, kbHome)
viper.Set(flags.FlagUseLedger, true) viper.Set(flags.FlagUseLedger, true)
@ -54,9 +54,9 @@ func Test_runAddCmdLedgerWithCustomCoinType(t *testing.T) {
kb, err := keys.NewKeyring(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), viper.GetString(flags.FlagHome), mockIn) kb, err := keys.NewKeyring(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), viper.GetString(flags.FlagHome), mockIn)
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, kb) require.NotNil(t, kb)
defer func() { t.Cleanup(func() {
kb.Delete("keyname1", "", false) kb.Delete("keyname1", "", false)
}() })
mockIn.Reset("test1234\n") mockIn.Reset("test1234\n")
if runningUnattended { if runningUnattended {
mockIn.Reset("test1234\ntest1234\n") mockIn.Reset("test1234\ntest1234\n")
@ -87,7 +87,7 @@ func Test_runAddCmdLedger(t *testing.T) {
// Prepare a keybase // Prepare a keybase
kbHome, kbCleanUp := tests.NewTestCaseDir(t) kbHome, kbCleanUp := tests.NewTestCaseDir(t)
require.NotNil(t, kbHome) require.NotNil(t, kbHome)
defer kbCleanUp() t.Cleanup(kbCleanUp)
viper.Set(flags.FlagHome, kbHome) viper.Set(flags.FlagHome, kbHome)
viper.Set(flags.FlagUseLedger, true) viper.Set(flags.FlagUseLedger, true)
@ -101,9 +101,9 @@ func Test_runAddCmdLedger(t *testing.T) {
kb, err := keys.NewKeyring(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), kbHome, mockIn) kb, err := keys.NewKeyring(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), kbHome, mockIn)
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, kb) require.NotNil(t, kb)
defer func() { t.Cleanup(func() {
kb.Delete("keyname1", "", false) kb.Delete("keyname1", "", false)
}() })
mockIn.Reset("test1234\n") mockIn.Reset("test1234\n")
if runningUnattended { if runningUnattended {
mockIn.Reset("test1234\ntest1234\n") mockIn.Reset("test1234\ntest1234\n")

View File

@ -23,7 +23,7 @@ func Test_runAddCmdBasic(t *testing.T) {
kbHome, kbCleanUp := tests.NewTestCaseDir(t) kbHome, kbCleanUp := tests.NewTestCaseDir(t)
assert.NotNil(t, kbHome) assert.NotNil(t, kbHome)
defer kbCleanUp() t.Cleanup(kbCleanUp)
viper.Set(flags.FlagHome, kbHome) viper.Set(flags.FlagHome, kbHome)
viper.Set(cli.OutputFlag, OutputFormatText) viper.Set(cli.OutputFlag, OutputFormatText)
@ -33,10 +33,10 @@ func Test_runAddCmdBasic(t *testing.T) {
mockIn.Reset("y\n") mockIn.Reset("y\n")
kb, err := keys.NewKeyring(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), kbHome, mockIn) kb, err := keys.NewKeyring(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), kbHome, mockIn)
require.NoError(t, err) require.NoError(t, err)
defer func() { t.Cleanup(func() {
kb.Delete("keyname1", "", false) kb.Delete("keyname1", "", false)
kb.Delete("keyname2", "", false) kb.Delete("keyname2", "", false)
}() })
} }
assert.NoError(t, runAddCmd(cmd, []string{"keyname1"})) assert.NoError(t, runAddCmd(cmd, []string{"keyname1"}))

View File

@ -29,15 +29,15 @@ func Test_runDeleteCmd(t *testing.T) {
if !runningUnattended { if !runningUnattended {
kb, err := keys.NewKeyring(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), viper.GetString(flags.FlagHome), mockIn) kb, err := keys.NewKeyring(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), viper.GetString(flags.FlagHome), mockIn)
require.NoError(t, err) require.NoError(t, err)
defer func() { t.Cleanup(func() {
kb.Delete("runDeleteCmd_Key1", "", false) kb.Delete("runDeleteCmd_Key1", "", false)
kb.Delete("runDeleteCmd_Key2", "", false) kb.Delete("runDeleteCmd_Key2", "", false)
}() })
} }
// Now add a temporary keybase // Now add a temporary keybase
kbHome, cleanUp := tests.NewTestCaseDir(t) kbHome, cleanUp := tests.NewTestCaseDir(t)
defer cleanUp() t.Cleanup(cleanUp)
viper.Set(flags.FlagHome, kbHome) viper.Set(flags.FlagHome, kbHome)
// Now // Now

View File

@ -19,16 +19,16 @@ func Test_runExportCmd(t *testing.T) {
// Now add a temporary keybase // Now add a temporary keybase
kbHome, cleanUp := tests.NewTestCaseDir(t) kbHome, cleanUp := tests.NewTestCaseDir(t)
defer cleanUp() t.Cleanup(cleanUp)
viper.Set(flags.FlagHome, kbHome) viper.Set(flags.FlagHome, kbHome)
// create a key // create a key
kb, err := keys.NewKeyring(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), viper.GetString(flags.FlagHome), mockIn) kb, err := keys.NewKeyring(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), viper.GetString(flags.FlagHome), mockIn)
require.NoError(t, err) require.NoError(t, err)
if !runningUnattended { if !runningUnattended {
defer func() { t.Cleanup(func() {
kb.Delete("keyname1", "", false) kb.Delete("keyname1", "", false)
}() })
} }
if runningUnattended { if runningUnattended {

View File

@ -21,15 +21,15 @@ func Test_runImportCmd(t *testing.T) {
// Now add a temporary keybase // Now add a temporary keybase
kbHome, cleanUp := tests.NewTestCaseDir(t) kbHome, cleanUp := tests.NewTestCaseDir(t)
defer cleanUp() t.Cleanup(cleanUp)
viper.Set(flags.FlagHome, kbHome) viper.Set(flags.FlagHome, kbHome)
if !runningUnattended { if !runningUnattended {
kb, err := keys.NewKeyring(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), viper.GetString(flags.FlagHome), mockIn) kb, err := keys.NewKeyring(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), viper.GetString(flags.FlagHome), mockIn)
require.NoError(t, err) require.NoError(t, err)
defer func() { t.Cleanup(func() {
kb.Delete("keyname1", "", false) kb.Delete("keyname1", "", false)
}() })
} }
keyfile := filepath.Join(kbHome, "key.asc") keyfile := filepath.Join(kbHome, "key.asc")

View File

@ -24,11 +24,11 @@ func Test_runListCmd(t *testing.T) {
// Prepare some keybases // Prepare some keybases
kbHome1, cleanUp1 := tests.NewTestCaseDir(t) kbHome1, cleanUp1 := tests.NewTestCaseDir(t)
defer cleanUp1() t.Cleanup(cleanUp1)
// Do nothing, leave home1 empty // Do nothing, leave home1 empty
kbHome2, cleanUp2 := tests.NewTestCaseDir(t) kbHome2, cleanUp2 := tests.NewTestCaseDir(t)
defer cleanUp2() t.Cleanup(cleanUp2)
viper.Set(flags.FlagHome, kbHome2) viper.Set(flags.FlagHome, kbHome2)
mockIn, _, _ := tests.ApplyMockIO(cmdBasic) mockIn, _, _ := tests.ApplyMockIO(cmdBasic)
@ -41,9 +41,9 @@ func Test_runListCmd(t *testing.T) {
_, err = kb.CreateAccount("something", tests.TestMnemonic, "", "", "", keys.Secp256k1) _, err = kb.CreateAccount("something", tests.TestMnemonic, "", "", "", keys.Secp256k1)
require.NoError(t, err) require.NoError(t, err)
defer func() { t.Cleanup(func() {
kb.Delete("something", "", false) kb.Delete("something", "", false)
}() })
testData := []struct { testData := []struct {
name string name string
kbDir string kbDir string

View File

@ -19,14 +19,13 @@ func Test_runMigrateCmd(t *testing.T) {
kbHome, kbCleanUp := tests.NewTestCaseDir(t) kbHome, kbCleanUp := tests.NewTestCaseDir(t)
assert.NotNil(t, kbHome) assert.NotNil(t, kbHome)
defer kbCleanUp() t.Cleanup(kbCleanUp)
viper.Set(flags.FlagHome, kbHome) viper.Set(flags.FlagHome, kbHome)
viper.Set(cli.OutputFlag, OutputFormatText) viper.Set(cli.OutputFlag, OutputFormatText)
mockIn.Reset("test1234\ntest1234\n") mockIn.Reset("test1234\ntest1234\n")
err := runAddCmd(cmd, []string{"keyname1"}) assert.NoError(t, runAddCmd(cmd, []string{"keyname1"}))
assert.NoError(t, err)
viper.Set(flags.FlagDryRun, true) viper.Set(flags.FlagDryRun, true)
cmd = MigrateCommand() cmd = MigrateCommand()

View File

@ -12,8 +12,7 @@ import (
func Test_RunMnemonicCmdNormal(t *testing.T) { func Test_RunMnemonicCmdNormal(t *testing.T) {
cmdBasic := MnemonicKeyCommand() cmdBasic := MnemonicKeyCommand()
err := runMnemonicCmd(cmdBasic, []string{}) require.NoError(t, runMnemonicCmd(cmdBasic, []string{}))
require.NoError(t, err)
} }
func Test_RunMnemonicCmdUser(t *testing.T) { func Test_RunMnemonicCmdUser(t *testing.T) {
@ -37,18 +36,15 @@ func Test_RunMnemonicCmdUser(t *testing.T) {
// Now provide "good" entropy :) // Now provide "good" entropy :)
fakeEntropy := strings.Repeat(":)", 40) + "\ny\n" // entropy + accept count fakeEntropy := strings.Repeat(":)", 40) + "\ny\n" // entropy + accept count
mockIn.Reset(fakeEntropy) mockIn.Reset(fakeEntropy)
err = runMnemonicCmd(cmdUser, []string{}) require.NoError(t, runMnemonicCmd(cmdUser, []string{}))
require.NoError(t, err)
// Now provide "good" entropy but no answer // Now provide "good" entropy but no answer
fakeEntropy = strings.Repeat(":)", 40) + "\n" // entropy + accept count fakeEntropy = strings.Repeat(":)", 40) + "\n" // entropy + accept count
mockIn.Reset(fakeEntropy) mockIn.Reset(fakeEntropy)
err = runMnemonicCmd(cmdUser, []string{}) require.Error(t, runMnemonicCmd(cmdUser, []string{}))
require.Error(t, err)
// Now provide "good" entropy but say no // Now provide "good" entropy but say no
fakeEntropy = strings.Repeat(":)", 40) + "\nn\n" // entropy + accept count fakeEntropy = strings.Repeat(":)", 40) + "\nn\n" // entropy + accept count
mockIn.Reset(fakeEntropy) mockIn.Reset(fakeEntropy)
err = runMnemonicCmd(cmdUser, []string{}) require.NoError(t, runMnemonicCmd(cmdUser, []string{}))
require.NoError(t, err)
} }

View File

@ -136,7 +136,7 @@ func runShowCmd(cmd *cobra.Command, args []string) (err error) {
return nil return nil
} }
return crypto.LedgerShowAddress(*hdpath, info.GetPubKey()) return crypto.LedgerShowAddress(*hdpath, info.GetPubKey(), sdk.GetConfig().GetBech32AccountAddrPrefix())
} }
return nil return nil

View File

@ -44,17 +44,17 @@ func Test_runShowCmd(t *testing.T) {
// Prepare a key base // Prepare a key base
// Now add a temporary keybase // Now add a temporary keybase
kbHome, cleanUp := tests.NewTestCaseDir(t) kbHome, cleanUp := tests.NewTestCaseDir(t)
defer cleanUp() t.Cleanup(cleanUp)
viper.Set(flags.FlagHome, kbHome) viper.Set(flags.FlagHome, kbHome)
fakeKeyName1 := "runShowCmd_Key1" fakeKeyName1 := "runShowCmd_Key1"
fakeKeyName2 := "runShowCmd_Key2" fakeKeyName2 := "runShowCmd_Key2"
kb, err := keys.NewKeyring(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), viper.GetString(flags.FlagHome), mockIn) kb, err := keys.NewKeyring(sdk.KeyringServiceName(), viper.GetString(flags.FlagKeyringBackend), viper.GetString(flags.FlagHome), mockIn)
require.NoError(t, err) require.NoError(t, err)
defer func() { t.Cleanup(func() {
kb.Delete("runShowCmd_Key1", "", false) kb.Delete("runShowCmd_Key1", "", false)
kb.Delete("runShowCmd_Key2", "", false) kb.Delete("runShowCmd_Key2", "", false)
}() })
if runningUnattended { if runningUnattended {
mockIn.Reset("testpass1\ntestpass1\n") mockIn.Reset("testpass1\ntestpass1\n")
} }

29
client/keys/types_test.go Normal file
View File

@ -0,0 +1,29 @@
package keys_test
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/client/keys"
)
func TestConstructors(t *testing.T) {
require.Equal(t, keys.AddNewKey{
Name: "name",
Password: "password",
Mnemonic: "mnemonic",
Account: 1,
Index: 1,
}, keys.NewAddNewKey("name", "password", "mnemonic", 1, 1))
require.Equal(t, keys.RecoverKey{
Password: "password",
Mnemonic: "mnemonic",
Account: 1,
Index: 1,
}, keys.NewRecoverKey("password", "mnemonic", 1, 1))
require.Equal(t, keys.UpdateKeyReq{OldPassword: "old", NewPassword: "new"}, keys.NewUpdateKeyReq("old", "new"))
require.Equal(t, keys.DeleteKeyReq{Password: "password"}, keys.NewDeleteKeyReq("password"))
}

View File

@ -12,8 +12,7 @@ import (
) )
func Test_updateKeyCommand(t *testing.T) { func Test_updateKeyCommand(t *testing.T) {
cmd := UpdateKeyCommand() assert.NotNil(t, UpdateKeyCommand())
assert.NotNil(t, cmd)
// No flags or defaults to validate // No flags or defaults to validate
} }
@ -34,7 +33,7 @@ func Test_runUpdateCmd(t *testing.T) {
// Prepare a key base // Prepare a key base
// Now add a temporary keybase // Now add a temporary keybase
kbHome, cleanUp1 := tests.NewTestCaseDir(t) kbHome, cleanUp1 := tests.NewTestCaseDir(t)
defer cleanUp1() t.Cleanup(cleanUp1)
viper.Set(flags.FlagHome, kbHome) viper.Set(flags.FlagHome, kbHome)
kb, err := NewKeyBaseFromDir(viper.GetString(flags.FlagHome)) kb, err := NewKeyBaseFromDir(viper.GetString(flags.FlagHome))

View File

@ -212,7 +212,7 @@ func (kb dbKeybase) Sign(name, passphrase string, msg []byte) (sig []byte, pub t
} }
case ledgerInfo: case ledgerInfo:
return kb.base.SignWithLedger(info, msg) return SignWithLedger(info, msg)
case offlineInfo, multiInfo: case offlineInfo, multiInfo:
return kb.base.DecodeSignature(info, msg) return kb.base.DecodeSignature(info, msg)

View File

@ -104,24 +104,6 @@ func SecpPrivKeyGen(bz []byte) tmcrypto.PrivKey {
return secp256k1.PrivKeySecp256k1(bzArr) return secp256k1.PrivKeySecp256k1(bzArr)
} }
// SignWithLedger signs a binary message with the ledger device referenced by an Info object
// and returns the signed bytes and the public key. It returns an error if the device could
// not be queried or it returned an error.
func (kb baseKeybase) SignWithLedger(info Info, msg []byte) (sig []byte, pub tmcrypto.PubKey, err error) {
i := info.(ledgerInfo)
priv, err := crypto.NewPrivKeyLedgerSecp256k1Unsafe(i.Path)
if err != nil {
return
}
sig, err = priv.Sign(msg)
if err != nil {
return nil, nil, err
}
return sig, priv.PubKey(), nil
}
// DecodeSignature decodes a an length-prefixed binary signature from standard input // DecodeSignature decodes a an length-prefixed binary signature from standard input
// and return it as a byte slice. // and return it as a byte slice.
func (kb baseKeybase) DecodeSignature(info Info, msg []byte) (sig []byte, pub tmcrypto.PubKey, err error) { func (kb baseKeybase) DecodeSignature(info Info, msg []byte) (sig []byte, pub tmcrypto.PubKey, err error) {
@ -296,3 +278,30 @@ func IsSupportedAlgorithm(supported []SigningAlgo, algo SigningAlgo) bool {
} }
return false return false
} }
// SignWithLedger signs a binary message with the ledger device referenced by an Info object
// and returns the signed bytes and the public key. It returns an error if the device could
// not be queried or it returned an error.
func SignWithLedger(info Info, msg []byte) (sig []byte, pub tmcrypto.PubKey, err error) {
switch info.(type) {
case *ledgerInfo, ledgerInfo:
default:
return nil, nil, errors.New("not a ledger object")
}
path, err := info.GetPath()
if err != nil {
return
}
priv, err := crypto.NewPrivKeyLedgerSecp256k1Unsafe(*path)
if err != nil {
return
}
sig, err = priv.Sign(msg)
if err != nil {
return nil, nil, err
}
return sig, priv.PubKey(), nil
}

View File

@ -2,7 +2,9 @@
package keys package keys
import ( import (
"errors"
"fmt" "fmt"
"io"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -278,7 +280,7 @@ func TestSignVerify(t *testing.T) {
// Now try to sign data with a secret-less key // Now try to sign data with a secret-less key
_, _, err = cstore.Sign(n3, p3, d3) _, _, err = cstore.Sign(n3, p3, d3)
require.NotNil(t, err) require.True(t, errors.Is(io.EOF, err))
} }
func assertPassword(t *testing.T, cstore Keybase, name, pass, badpass string) { func assertPassword(t *testing.T, cstore Keybase, name, pass, badpass string) {

View File

@ -0,0 +1,24 @@
package keyerror_test
import (
"errors"
"testing"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/crypto/keys/keyerror"
)
func TestErrors(t *testing.T) {
err := keyerror.NewErrKeyNotFound("test")
require.True(t, keyerror.IsErrKeyNotFound(err))
require.Equal(t, "Key test not found", err.Error())
require.False(t, keyerror.IsErrKeyNotFound(errors.New("test")))
require.False(t, keyerror.IsErrKeyNotFound(nil))
err = keyerror.NewErrWrongPassword()
require.True(t, keyerror.IsErrWrongPassword(err))
require.Equal(t, "invalid account password", err.Error())
require.False(t, keyerror.IsErrWrongPassword(errors.New("test")))
require.False(t, keyerror.IsErrWrongPassword(nil))
}

View File

@ -7,7 +7,6 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"reflect"
"sort" "sort"
"strings" "strings"
@ -218,7 +217,7 @@ func (kb keyringKeybase) Sign(name, passphrase string, msg []byte) (sig []byte,
} }
case ledgerInfo: case ledgerInfo:
return kb.base.SignWithLedger(info, msg) return SignWithLedger(info, msg)
case offlineInfo, multiInfo: case offlineInfo, multiInfo:
return kb.base.DecodeSignature(info, msg) return kb.base.DecodeSignature(info, msg)
@ -419,29 +418,7 @@ func (kb keyringKeybase) Delete(name, _ string, _ bool) error {
// The oldpass must be the current passphrase used for encryption, getNewpass is // The oldpass must be the current passphrase used for encryption, getNewpass is
// a function to get the passphrase to permanently replace the current passphrase. // a function to get the passphrase to permanently replace the current passphrase.
func (kb keyringKeybase) Update(name, oldpass string, getNewpass func() (string, error)) error { func (kb keyringKeybase) Update(name, oldpass string, getNewpass func() (string, error)) error {
info, err := kb.Get(name) return errors.New("unsupported operation")
if err != nil {
return err
}
switch linfo := info.(type) {
case localInfo:
key, _, err := mintkey.UnarmorDecryptPrivKey(linfo.PrivKeyArmor, oldpass)
if err != nil {
return err
}
newpass, err := getNewpass()
if err != nil {
return err
}
kb.writeLocalKey(name, key, newpass, linfo.GetAlgo())
return nil
default:
return fmt.Errorf("locally stored key required; received: %v", reflect.TypeOf(info).String())
}
} }
// SupportedAlgos returns a list of supported signing algorithms. // SupportedAlgos returns a list of supported signing algorithms.

View File

@ -2,6 +2,7 @@
package keys package keys
import ( import (
"bytes"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -16,7 +17,7 @@ import (
func TestLazyKeyManagementKeyRing(t *testing.T) { func TestLazyKeyManagementKeyRing(t *testing.T) {
dir, cleanup := tests.NewTestCaseDir(t) dir, cleanup := tests.NewTestCaseDir(t)
defer cleanup() t.Cleanup(cleanup)
kb, err := NewKeyring("keybasename", "test", dir, nil) kb, err := NewKeyring("keybasename", "test", dir, nil)
require.NoError(t, err) require.NoError(t, err)
@ -94,13 +95,51 @@ func TestLazyKeyManagementKeyRing(t *testing.T) {
require.Equal(t, 1, len(keyS)) require.Equal(t, 1, len(keyS))
// addr cache gets nuked - and test skip flag // addr cache gets nuked - and test skip flag
err = kb.Delete(n2, "", true) require.NoError(t, kb.Delete(n2, "", true))
require.NotPanics(t, kb.CloseDB)
}
// TestSignVerify does some detailed checks on how we sign and validate
// signatures
func TestLazySignVerifyKeyRingWithLedger(t *testing.T) {
dir, cleanup := tests.NewTestCaseDir(t)
t.Cleanup(cleanup)
kb, err := NewKeyring("keybasename", "test", dir, nil)
require.NoError(t, err) require.NoError(t, err)
i1, err := kb.CreateLedger("key", Secp256k1, "cosmos", 0, 0)
if err != nil {
require.Equal(t, "ledger nano S: support for ledger devices is not available in this executable", err.Error())
t.Skip("ledger nano S: support for ledger devices is not available in this executable")
return
}
require.Equal(t, "key", i1.GetName())
p1 := "1234"
d1 := []byte("my first message")
s1, pub1, err := kb.Sign("key", p1, d1)
require.NoError(t, err)
s2, pub2, err := SignWithLedger(i1, d1)
require.NoError(t, err)
require.Equal(t, i1.GetPubKey(), pub1)
require.Equal(t, i1.GetPubKey(), pub2)
require.True(t, pub1.VerifyBytes(d1, s1))
require.True(t, i1.GetPubKey().VerifyBytes(d1, s1))
require.True(t, bytes.Equal(s1, s2))
localInfo, _, err := kb.CreateMnemonic("test", English, p1, Secp256k1)
require.NoError(t, err)
_, _, err = SignWithLedger(localInfo, d1)
require.Error(t, err)
require.Equal(t, "not a ledger object", err.Error())
} }
func TestLazySignVerifyKeyRing(t *testing.T) { func TestLazySignVerifyKeyRing(t *testing.T) {
dir, cleanup := tests.NewTestCaseDir(t) dir, cleanup := tests.NewTestCaseDir(t)
defer cleanup() t.Cleanup(cleanup)
kb, err := NewKeyring("keybasename", "test", dir, nil) kb, err := NewKeyring("keybasename", "test", dir, nil)
require.NoError(t, err) require.NoError(t, err)
algo := Secp256k1 algo := Secp256k1
@ -176,7 +215,7 @@ func TestLazySignVerifyKeyRing(t *testing.T) {
func TestLazyExportImportKeyRing(t *testing.T) { func TestLazyExportImportKeyRing(t *testing.T) {
dir, cleanup := tests.NewTestCaseDir(t) dir, cleanup := tests.NewTestCaseDir(t)
defer cleanup() t.Cleanup(cleanup)
kb, err := NewKeyring("keybasename", "test", dir, nil) kb, err := NewKeyring("keybasename", "test", dir, nil)
require.NoError(t, err) require.NoError(t, err)
@ -205,7 +244,7 @@ func TestLazyExportImportKeyRing(t *testing.T) {
func TestLazyExportImportPubKeyKeyRing(t *testing.T) { func TestLazyExportImportPubKeyKeyRing(t *testing.T) {
dir, cleanup := tests.NewTestCaseDir(t) dir, cleanup := tests.NewTestCaseDir(t)
defer cleanup() t.Cleanup(cleanup)
kb, err := NewKeyring("keybasename", "test", dir, nil) kb, err := NewKeyring("keybasename", "test", dir, nil)
require.NoError(t, err) require.NoError(t, err)
algo := Secp256k1 algo := Secp256k1
@ -246,7 +285,7 @@ func TestLazyExportImportPubKeyKeyRing(t *testing.T) {
func TestLazyExportPrivateKeyObjectKeyRing(t *testing.T) { func TestLazyExportPrivateKeyObjectKeyRing(t *testing.T) {
dir, cleanup := tests.NewTestCaseDir(t) dir, cleanup := tests.NewTestCaseDir(t)
defer cleanup() t.Cleanup(cleanup)
kb, err := NewKeyring("keybasename", "test", dir, nil) kb, err := NewKeyring("keybasename", "test", dir, nil)
require.NoError(t, err) require.NoError(t, err)
@ -262,7 +301,7 @@ func TestLazyExportPrivateKeyObjectKeyRing(t *testing.T) {
func TestLazyAdvancedKeyManagementKeyRing(t *testing.T) { func TestLazyAdvancedKeyManagementKeyRing(t *testing.T) {
dir, cleanup := tests.NewTestCaseDir(t) dir, cleanup := tests.NewTestCaseDir(t)
defer cleanup() t.Cleanup(cleanup)
kb, err := NewKeyring("keybasename", "test", dir, nil) kb, err := NewKeyring("keybasename", "test", dir, nil)
require.NoError(t, err) require.NoError(t, err)
@ -296,7 +335,7 @@ func TestLazyAdvancedKeyManagementKeyRing(t *testing.T) {
func TestLazySeedPhraseKeyRing(t *testing.T) { func TestLazySeedPhraseKeyRing(t *testing.T) {
dir, cleanup := tests.NewTestCaseDir(t) dir, cleanup := tests.NewTestCaseDir(t)
defer cleanup() t.Cleanup(cleanup)
kb, err := NewKeyring("keybasename", "test", dir, nil) kb, err := NewKeyring("keybasename", "test", dir, nil)
require.NoError(t, err) require.NoError(t, err)
@ -325,3 +364,50 @@ func TestLazySeedPhraseKeyRing(t *testing.T) {
require.Equal(t, info.GetPubKey().Address(), newInfo.GetPubKey().Address()) require.Equal(t, info.GetPubKey().Address(), newInfo.GetPubKey().Address())
require.Equal(t, info.GetPubKey(), newInfo.GetPubKey()) require.Equal(t, info.GetPubKey(), newInfo.GetPubKey())
} }
func TestKeyringKeybaseExportImportPrivKey(t *testing.T) {
dir, cleanup := tests.NewTestCaseDir(t)
t.Cleanup(cleanup)
kb, err := NewKeyring("keybasename", "test", dir, nil)
require.NoError(t, err)
_, _, err = kb.CreateMnemonic("john", English, "password", Secp256k1)
require.NoError(t, err)
// no error, password is irrelevant, keystr cointains ASCII armored private key
keystr, err := kb.ExportPrivKey("john", "wrongpassword", "password")
require.NoError(t, err)
require.NotEmpty(t, keystr)
// try import the key - wrong password
err = kb.ImportPrivKey("john2", keystr, "somepassword")
require.Equal(t, "failed to decrypt private key: ciphertext decryption failed", err.Error())
// try import the key with the correct password
require.NoError(t, kb.ImportPrivKey("john2", keystr, "password"))
// overwrite is not allowed
err = kb.ImportPrivKey("john2", keystr, "password")
require.Equal(t, "cannot overwrite key: john2", err.Error())
// try export non existing key
_, err = kb.ExportPrivKey("john3", "wrongpassword", "password")
require.Equal(t, "The specified item could not be found in the keyring", err.Error())
}
func TestKeyringKeybaseUpdate(t *testing.T) {
dir, cleanup := tests.NewTestCaseDir(t)
t.Cleanup(cleanup)
kb, err := NewKeyring("keybasename", "test", dir, nil)
require.NoError(t, err)
require.Equal(t, "unsupported operation", kb.Update("john", "oldpassword",
func() (string, error) { return "", nil }).Error())
}
func TestSupportedAlgos(t *testing.T) {
dir, cleanup := tests.NewTestCaseDir(t)
t.Cleanup(cleanup)
kb, err := NewKeyring("keybasename", "test", dir, nil)
require.NoError(t, err)
require.Equal(t, []SigningAlgo([]SigningAlgo{"secp256k1"}), kb.SupportedAlgos())
require.Equal(t, []SigningAlgo([]SigningAlgo{"secp256k1"}), kb.SupportedAlgosLedger())
}

View File

@ -18,7 +18,7 @@ import (
func TestNew(t *testing.T) { func TestNew(t *testing.T) {
dir, cleanup := tests.NewTestCaseDir(t) dir, cleanup := tests.NewTestCaseDir(t)
defer cleanup() t.Cleanup(cleanup)
kb := New("keybasename", dir) kb := New("keybasename", dir)
lazykb, ok := kb.(lazyKeybase) lazykb, ok := kb.(lazyKeybase)
require.True(t, ok) require.True(t, ok)
@ -28,7 +28,7 @@ func TestNew(t *testing.T) {
func TestLazyKeyManagement(t *testing.T) { func TestLazyKeyManagement(t *testing.T) {
dir, cleanup := tests.NewTestCaseDir(t) dir, cleanup := tests.NewTestCaseDir(t)
defer cleanup() t.Cleanup(cleanup)
kb := New("keybasename", dir) kb := New("keybasename", dir)
algo := Secp256k1 algo := Secp256k1
@ -111,7 +111,7 @@ func TestLazyKeyManagement(t *testing.T) {
func TestLazySignVerify(t *testing.T) { func TestLazySignVerify(t *testing.T) {
dir, cleanup := tests.NewTestCaseDir(t) dir, cleanup := tests.NewTestCaseDir(t)
defer cleanup() t.Cleanup(cleanup)
kb := New("keybasename", dir) kb := New("keybasename", dir)
algo := Secp256k1 algo := Secp256k1
@ -186,7 +186,7 @@ func TestLazySignVerify(t *testing.T) {
func TestLazyExportImport(t *testing.T) { func TestLazyExportImport(t *testing.T) {
dir, cleanup := tests.NewTestCaseDir(t) dir, cleanup := tests.NewTestCaseDir(t)
defer cleanup() t.Cleanup(cleanup)
kb := New("keybasename", dir) kb := New("keybasename", dir)
info, _, err := kb.CreateMnemonic("john", English, "secretcpw", Secp256k1) info, _, err := kb.CreateMnemonic("john", English, "secretcpw", Secp256k1)
@ -214,7 +214,7 @@ func TestLazyExportImport(t *testing.T) {
func TestLazyExportImportPrivKey(t *testing.T) { func TestLazyExportImportPrivKey(t *testing.T) {
dir, cleanup := tests.NewTestCaseDir(t) dir, cleanup := tests.NewTestCaseDir(t)
defer cleanup() t.Cleanup(cleanup)
kb := New("keybasename", dir) kb := New("keybasename", dir)
info, _, err := kb.CreateMnemonic("john", English, "secretcpw", Secp256k1) info, _, err := kb.CreateMnemonic("john", English, "secretcpw", Secp256k1)
@ -243,7 +243,7 @@ func TestLazyExportImportPrivKey(t *testing.T) {
func TestLazyExportImportPubKey(t *testing.T) { func TestLazyExportImportPubKey(t *testing.T) {
dir, cleanup := tests.NewTestCaseDir(t) dir, cleanup := tests.NewTestCaseDir(t)
defer cleanup() t.Cleanup(cleanup)
kb := New("keybasename", dir) kb := New("keybasename", dir)
algo := Secp256k1 algo := Secp256k1
@ -283,7 +283,7 @@ func TestLazyExportImportPubKey(t *testing.T) {
func TestLazyExportPrivateKeyObject(t *testing.T) { func TestLazyExportPrivateKeyObject(t *testing.T) {
dir, cleanup := tests.NewTestCaseDir(t) dir, cleanup := tests.NewTestCaseDir(t)
defer cleanup() t.Cleanup(cleanup)
kb := New("keybasename", dir) kb := New("keybasename", dir)
info, _, err := kb.CreateMnemonic("john", English, "secretcpw", Secp256k1) info, _, err := kb.CreateMnemonic("john", English, "secretcpw", Secp256k1)
@ -300,7 +300,7 @@ func TestLazyExportPrivateKeyObject(t *testing.T) {
func TestLazyAdvancedKeyManagement(t *testing.T) { func TestLazyAdvancedKeyManagement(t *testing.T) {
dir, cleanup := tests.NewTestCaseDir(t) dir, cleanup := tests.NewTestCaseDir(t)
defer cleanup() t.Cleanup(cleanup)
kb := New("keybasename", dir) kb := New("keybasename", dir)
algo := Secp256k1 algo := Secp256k1
@ -348,7 +348,7 @@ func TestLazyAdvancedKeyManagement(t *testing.T) {
// TestSeedPhrase verifies restoring from a seed phrase // TestSeedPhrase verifies restoring from a seed phrase
func TestLazySeedPhrase(t *testing.T) { func TestLazySeedPhrase(t *testing.T) {
dir, cleanup := tests.NewTestCaseDir(t) dir, cleanup := tests.NewTestCaseDir(t)
defer cleanup() t.Cleanup(cleanup)
kb := New("keybasename", dir) kb := New("keybasename", dir)
algo := Secp256k1 algo := Secp256k1
@ -401,13 +401,13 @@ func (key testPub) Equals(other crypto.PubKey) bool { return true }
func TestKeygenOverride(t *testing.T) { func TestKeygenOverride(t *testing.T) {
dir, cleanup := tests.NewTestCaseDir(t) dir, cleanup := tests.NewTestCaseDir(t)
defer cleanup() t.Cleanup(cleanup)
// Save existing codec and reset after test // Save existing codec and reset after test
cryptoCdc := CryptoCdc cryptoCdc := CryptoCdc
defer func() { t.Cleanup(func() {
CryptoCdc = cryptoCdc CryptoCdc = cryptoCdc
}() })
// Setup testCdc encoding and decoding new key type // Setup testCdc encoding and decoding new key type
testCdc = codec.New() testCdc = codec.New()

View File

@ -11,9 +11,8 @@ import (
cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino" cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
"github.com/tendermint/tendermint/crypto/xsalsa20symmetric" "github.com/tendermint/tendermint/crypto/xsalsa20symmetric"
tmos "github.com/tendermint/tendermint/libs/os"
"github.com/cosmos/cosmos-sdk/crypto/keys/keyerror" "github.com/cosmos/cosmos-sdk/crypto/keys/keyerror"
"github.com/cosmos/cosmos-sdk/types/errors"
) )
const ( const (
@ -134,7 +133,7 @@ func encryptPrivKey(privKey crypto.PrivKey, passphrase string) (saltBytes []byte
saltBytes = crypto.CRandBytes(16) saltBytes = crypto.CRandBytes(16)
key, err := bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), BcryptSecurityParameter) key, err := bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), BcryptSecurityParameter)
if err != nil { if err != nil {
tmos.Exit("Error generating bcrypt key from passphrase: " + err.Error()) panic(errors.Wrap(err, "error generating bcrypt key from passphrase"))
} }
key = crypto.Sha256(key) // get 32 bytes key = crypto.Sha256(key) // get 32 bytes
privKeyBytes := privKey.Bytes() privKeyBytes := privKey.Bytes()
@ -151,7 +150,7 @@ func UnarmorDecryptPrivKey(armorStr string, passphrase string) (privKey crypto.P
return privKey, "", fmt.Errorf("unrecognized armor type: %v", blockType) return privKey, "", fmt.Errorf("unrecognized armor type: %v", blockType)
} }
if header["kdf"] != "bcrypt" { if header["kdf"] != "bcrypt" {
return privKey, "", fmt.Errorf("unrecognized KDF type: %v", header["KDF"]) return privKey, "", fmt.Errorf("unrecognized KDF type: %v", header["kdf"])
} }
if header["salt"] == "" { if header["salt"] == "" {
return privKey, "", fmt.Errorf("missing salt bytes") return privKey, "", fmt.Errorf("missing salt bytes")
@ -171,7 +170,7 @@ func UnarmorDecryptPrivKey(armorStr string, passphrase string) (privKey crypto.P
func decryptPrivKey(saltBytes []byte, encBytes []byte, passphrase string) (privKey crypto.PrivKey, err error) { func decryptPrivKey(saltBytes []byte, encBytes []byte, passphrase string) (privKey crypto.PrivKey, err error) {
key, err := bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), BcryptSecurityParameter) key, err := bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), BcryptSecurityParameter)
if err != nil { if err != nil {
tmos.Exit("error generating bcrypt key from passphrase: " + err.Error()) return privKey, errors.Wrap(err, "error generating bcrypt key from passphrase")
} }
key = crypto.Sha256(key) // Get 32 bytes key = crypto.Sha256(key) // Get 32 bytes
privKeyBytes, err := xsalsa20symmetric.DecryptSymmetric(encBytes, key) privKeyBytes, err := xsalsa20symmetric.DecryptSymmetric(encBytes, key)

View File

@ -1,11 +1,19 @@
package mintkey_test package mintkey_test
import ( import (
"bytes"
"errors"
"fmt"
"io"
"testing" "testing"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/tendermint/crypto/bcrypt"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/armor"
cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino" cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
"github.com/tendermint/tendermint/crypto/secp256k1" "github.com/tendermint/tendermint/crypto/secp256k1"
"github.com/tendermint/tendermint/crypto/xsalsa20symmetric"
"github.com/cosmos/cosmos-sdk/crypto/keys" "github.com/cosmos/cosmos-sdk/crypto/keys"
"github.com/cosmos/cosmos-sdk/crypto/keys/mintkey" "github.com/cosmos/cosmos-sdk/crypto/keys/mintkey"
@ -13,13 +21,48 @@ import (
func TestArmorUnarmorPrivKey(t *testing.T) { func TestArmorUnarmorPrivKey(t *testing.T) {
priv := secp256k1.GenPrivKey() priv := secp256k1.GenPrivKey()
armor := mintkey.EncryptArmorPrivKey(priv, "passphrase", "") armored := mintkey.EncryptArmorPrivKey(priv, "passphrase", "")
_, _, err := mintkey.UnarmorDecryptPrivKey(armor, "wrongpassphrase") _, _, err := mintkey.UnarmorDecryptPrivKey(armored, "wrongpassphrase")
require.Error(t, err) require.Error(t, err)
decrypted, algo, err := mintkey.UnarmorDecryptPrivKey(armor, "passphrase") decrypted, algo, err := mintkey.UnarmorDecryptPrivKey(armored, "passphrase")
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, string(keys.Secp256k1), algo) require.Equal(t, string(keys.Secp256k1), algo)
require.True(t, priv.Equals(decrypted)) require.True(t, priv.Equals(decrypted))
// empty string
decrypted, algo, err = mintkey.UnarmorDecryptPrivKey("", "passphrase")
require.Error(t, err)
require.True(t, errors.Is(io.EOF, err))
require.Nil(t, decrypted)
require.Empty(t, algo)
// wrong key type
armored = mintkey.ArmorPubKeyBytes(priv.PubKey().Bytes(), "")
decrypted, algo, err = mintkey.UnarmorDecryptPrivKey(armored, "passphrase")
require.Error(t, err)
require.Contains(t, err.Error(), "unrecognized armor type")
// armor key manually
encryptPrivKeyFn := func(privKey crypto.PrivKey, passphrase string) (saltBytes []byte, encBytes []byte) {
saltBytes = crypto.CRandBytes(16)
key, err := bcrypt.GenerateFromPassword(saltBytes, []byte(passphrase), mintkey.BcryptSecurityParameter)
require.NoError(t, err)
key = crypto.Sha256(key) // get 32 bytes
privKeyBytes := privKey.Bytes()
return saltBytes, xsalsa20symmetric.EncryptSymmetric(privKeyBytes, key)
}
saltBytes, encBytes := encryptPrivKeyFn(priv, "passphrase")
// wrong kdf header
headerWrongKdf := map[string]string{
"kdf": "wrong",
"salt": fmt.Sprintf("%X", saltBytes),
"type": "secp256k",
}
armored = armor.EncodeArmor("TENDERMINT PRIVATE KEY", headerWrongKdf, encBytes)
_, _, err = mintkey.UnarmorDecryptPrivKey(armored, "passphrase")
require.Error(t, err)
require.Equal(t, "unrecognized KDF type: wrong", err.Error())
} }
func TestArmorUnarmorPubKey(t *testing.T) { func TestArmorUnarmorPubKey(t *testing.T) {
@ -29,11 +72,66 @@ func TestArmorUnarmorPubKey(t *testing.T) {
// Add keys and see they return in alphabetical order // Add keys and see they return in alphabetical order
info, _, err := cstore.CreateMnemonic("Bob", keys.English, "passphrase", keys.Secp256k1) info, _, err := cstore.CreateMnemonic("Bob", keys.English, "passphrase", keys.Secp256k1)
require.NoError(t, err) require.NoError(t, err)
armor := mintkey.ArmorPubKeyBytes(info.GetPubKey().Bytes(), "") armored := mintkey.ArmorPubKeyBytes(info.GetPubKey().Bytes(), "")
pubBytes, algo, err := mintkey.UnarmorPubKeyBytes(armor) pubBytes, algo, err := mintkey.UnarmorPubKeyBytes(armored)
require.NoError(t, err) require.NoError(t, err)
pub, err := cryptoAmino.PubKeyFromBytes(pubBytes) pub, err := cryptoAmino.PubKeyFromBytes(pubBytes)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, string(keys.Secp256k1), algo) require.Equal(t, string(keys.Secp256k1), algo)
require.True(t, pub.Equals(info.GetPubKey())) require.True(t, pub.Equals(info.GetPubKey()))
armored = mintkey.ArmorPubKeyBytes(info.GetPubKey().Bytes(), "unknown")
pubBytes, algo, err = mintkey.UnarmorPubKeyBytes(armored)
require.NoError(t, err)
pub, err = cryptoAmino.PubKeyFromBytes(pubBytes)
require.NoError(t, err)
require.Equal(t, "unknown", algo)
require.True(t, pub.Equals(info.GetPubKey()))
// armor pubkey manually
header := map[string]string{
"version": "0.0.0",
"type": "unknown",
}
armored = armor.EncodeArmor("TENDERMINT PUBLIC KEY", header, pubBytes)
_, algo, err = mintkey.UnarmorPubKeyBytes(armored)
require.NoError(t, err)
// return secp256k1 if version is 0.0.0
require.Equal(t, "secp256k1", algo)
// missing version header
header = map[string]string{
"type": "unknown",
}
armored = armor.EncodeArmor("TENDERMINT PUBLIC KEY", header, pubBytes)
bz, algo, err := mintkey.UnarmorPubKeyBytes(armored)
require.Nil(t, bz)
require.Empty(t, algo)
require.Error(t, err)
require.Contains(t, err.Error(), "unrecognized version")
}
func TestArmorInfoBytes(t *testing.T) {
bs := []byte("test")
armoredString := mintkey.ArmorInfoBytes(bs)
unarmoredBytes, err := mintkey.UnarmorInfoBytes(armoredString)
require.NoError(t, err)
require.True(t, bytes.Equal(bs, unarmoredBytes))
}
func TestUnarmorInfoBytesErrors(t *testing.T) {
unarmoredBytes, err := mintkey.UnarmorInfoBytes("")
require.Error(t, err)
require.True(t, errors.Is(io.EOF, err))
require.Nil(t, unarmoredBytes)
header := map[string]string{
"type": "Info",
"version": "0.0.1",
}
unarmoredBytes, err = mintkey.UnarmorInfoBytes(armor.EncodeArmor(
"TENDERMINT KEY INFO", header, []byte("plain-text")))
require.Error(t, err)
require.Equal(t, "unrecognized version: 0.0.1", err.Error())
require.Nil(t, unarmoredBytes)
} }

View File

@ -12,7 +12,6 @@ import (
tmsecp256k1 "github.com/tendermint/tendermint/crypto/secp256k1" tmsecp256k1 "github.com/tendermint/tendermint/crypto/secp256k1"
"github.com/cosmos/cosmos-sdk/crypto/keys/hd" "github.com/cosmos/cosmos-sdk/crypto/keys/hd"
sdk "github.com/cosmos/cosmos-sdk/types"
) )
var ( var (
@ -103,7 +102,9 @@ func (pkl PrivKeyLedgerSecp256k1) Sign(message []byte) ([]byte, error) {
} }
// LedgerShowAddress triggers a ledger device to show the corresponding address. // LedgerShowAddress triggers a ledger device to show the corresponding address.
func LedgerShowAddress(path hd.BIP44Params, expectedPubKey tmcrypto.PubKey) error { func LedgerShowAddress(path hd.BIP44Params, expectedPubKey tmcrypto.PubKey,
accountAddressPrefix string) error {
device, err := getLedgerDevice() device, err := getLedgerDevice()
if err != nil { if err != nil {
return err return err
@ -119,8 +120,7 @@ func LedgerShowAddress(path hd.BIP44Params, expectedPubKey tmcrypto.PubKey) erro
return fmt.Errorf("the key's pubkey does not match with the one retrieved from Ledger. Check that the HD path and device are the correct ones") return fmt.Errorf("the key's pubkey does not match with the one retrieved from Ledger. Check that the HD path and device are the correct ones")
} }
config := sdk.GetConfig() pubKey2, _, err := getPubKeyAddrSafe(device, path, accountAddressPrefix)
pubKey2, _, err := getPubKeyAddrSafe(device, path, config.GetBech32AccountAddrPrefix())
if err != nil { if err != nil {
return err return err
} }

View File

@ -104,6 +104,8 @@ func TestPublicKeySafe(t *testing.T) {
require.Nil(t, err, "%s", err) require.Nil(t, err, "%s", err)
require.NotNil(t, priv) require.NotNil(t, priv)
require.Nil(t, LedgerShowAddress(path, priv.PubKey(), sdk.GetConfig().GetBech32AccountAddrPrefix()))
require.Equal(t, "eb5ae98721034fef9cd7c4c63588d3b03feb5281b9d232cba34d6f3d71aee59211ffbfe1fe87", require.Equal(t, "eb5ae98721034fef9cd7c4c63588d3b03feb5281b9d232cba34d6f3d71aee59211ffbfe1fe87",
fmt.Sprintf("%x", priv.PubKey().Bytes()), fmt.Sprintf("%x", priv.PubKey().Bytes()),
"Is your device using test mnemonic: %s ?", tests.TestMnemonic) "Is your device using test mnemonic: %s ?", tests.TestMnemonic)

View File

@ -12,7 +12,7 @@ import (
func Test_openDB(t *testing.T) { func Test_openDB(t *testing.T) {
t.Parallel() t.Parallel()
dir, cleanup := tests.NewTestCaseDir(t) dir, cleanup := tests.NewTestCaseDir(t)
defer cleanup() t.Cleanup(cleanup)
_, err := openDB(dir) _, err := openDB(dir)
require.NoError(t, err) require.NoError(t, err)
} }
@ -20,7 +20,7 @@ func Test_openDB(t *testing.T) {
func Test_openTraceWriter(t *testing.T) { func Test_openTraceWriter(t *testing.T) {
t.Parallel() t.Parallel()
dir, cleanup := tests.NewTestCaseDir(t) dir, cleanup := tests.NewTestCaseDir(t)
defer cleanup() t.Cleanup(cleanup)
fname := filepath.Join(dir, "logfile") fname := filepath.Join(dir, "logfile")
w, err := openTraceWriter(fname) w, err := openTraceWriter(fname)
require.NoError(t, err) require.NoError(t, err)

View File

@ -25,7 +25,7 @@ func TestGenerateCoinKey(t *testing.T) {
func TestGenerateSaveCoinKey(t *testing.T) { func TestGenerateSaveCoinKey(t *testing.T) {
t.Parallel() t.Parallel()
dir, cleanup := tests.NewTestCaseDir(t) dir, cleanup := tests.NewTestCaseDir(t)
defer cleanup() // clean after itself t.Cleanup(cleanup)
kb, err := crkeys.NewKeyring(t.Name(), "test", dir, nil) kb, err := crkeys.NewKeyring(t.Name(), "test", dir, nil)
require.NoError(t, err) require.NoError(t, err)
@ -47,7 +47,7 @@ func TestGenerateSaveCoinKey(t *testing.T) {
func TestGenerateSaveCoinKeyOverwriteFlag(t *testing.T) { func TestGenerateSaveCoinKeyOverwriteFlag(t *testing.T) {
t.Parallel() t.Parallel()
dir, cleanup := tests.NewTestCaseDir(t) dir, cleanup := tests.NewTestCaseDir(t)
defer cleanup() // clean after itself t.Cleanup(cleanup)
kb, err := crkeys.NewKeyring(t.Name(), "test", dir, nil) kb, err := crkeys.NewKeyring(t.Name(), "test", dir, nil)
require.NoError(t, err) require.NoError(t, err)

24
server/pruning.go Normal file
View File

@ -0,0 +1,24 @@
package server
import (
"github.com/cosmos/cosmos-sdk/store"
"github.com/spf13/viper"
)
// GetPruningOptionsFromFlags parses start command flags and returns the correct PruningOptions.
// flagPruning prevails over flagPruningKeepEvery and flagPruningSnapshotEvery.
// Default option is PruneSyncable.
func GetPruningOptionsFromFlags() store.PruningOptions {
if viper.IsSet(flagPruning) {
return store.NewPruningOptionsFromString(viper.GetString(flagPruning))
}
if viper.IsSet(flagPruningKeepEvery) && viper.IsSet(flagPruningSnapshotEvery) {
return store.PruningOptions{
KeepEvery: viper.GetInt64(flagPruningKeepEvery),
SnapshotEvery: viper.GetInt64(flagPruningSnapshotEvery),
}
}
return store.PruneSyncable
}

51
server/pruning_test.go Normal file
View File

@ -0,0 +1,51 @@
package server
import (
"testing"
"github.com/spf13/viper"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/store"
)
func TestGetPruningOptionsFromFlags(t *testing.T) {
tests := []struct {
name string
initParams func()
expectedOptions store.PruningOptions
}{
{
name: "pruning",
initParams: func() {
viper.Set(flagPruning, store.PruningStrategyNothing)
},
expectedOptions: store.PruneNothing,
},
{
name: "granular pruning",
initParams: func() {
viper.Set(flagPruningSnapshotEvery, 1234)
viper.Set(flagPruningKeepEvery, 4321)
},
expectedOptions: store.PruningOptions{
SnapshotEvery: 1234,
KeepEvery: 4321,
},
},
{
name: "default",
initParams: func() {},
expectedOptions: store.PruneSyncable,
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(j *testing.T) {
viper.Reset()
tt.initParams()
require.Equal(t, tt.expectedOptions, GetPruningOptionsFromFlags())
})
}
}

View File

@ -20,16 +20,29 @@ import (
// Tendermint full-node start flags // Tendermint full-node start flags
const ( const (
flagWithTendermint = "with-tendermint" flagWithTendermint = "with-tendermint"
flagAddress = "address" flagAddress = "address"
flagTraceStore = "trace-store" flagTraceStore = "trace-store"
flagPruning = "pruning" flagPruning = "pruning"
flagCPUProfile = "cpu-profile" flagPruningKeepEvery = "pruning-keep-every"
FlagMinGasPrices = "minimum-gas-prices" flagPruningSnapshotEvery = "pruning-snapshot-every"
FlagHaltHeight = "halt-height" flagCPUProfile = "cpu-profile"
FlagHaltTime = "halt-time" FlagMinGasPrices = "minimum-gas-prices"
FlagInterBlockCache = "inter-block-cache" FlagHaltHeight = "halt-height"
FlagUnsafeSkipUpgrades = "unsafe-skip-upgrades" FlagHaltTime = "halt-time"
FlagInterBlockCache = "inter-block-cache"
FlagUnsafeSkipUpgrades = "unsafe-skip-upgrades"
)
var (
errPruningWithGranularOptions = fmt.Errorf(
"'--%s' flag is not compatible with granular options '--%s' or '--%s'",
flagPruning, flagPruningKeepEvery, flagPruningSnapshotEvery,
)
errPruningGranularOptions = fmt.Errorf(
"'--%s' and '--%s' must be set together",
flagPruningSnapshotEvery, flagPruningKeepEvery,
)
) )
// StartCmd runs the service passed in, either stand-alone or in-process with // StartCmd runs the service passed in, either stand-alone or in-process with
@ -41,7 +54,9 @@ func StartCmd(ctx *Context, appCreator AppCreator) *cobra.Command {
Long: `Run the full node application with Tendermint in or out of process. By Long: `Run the full node application with Tendermint in or out of process. By
default, the application will run with Tendermint in process. default, the application will run with Tendermint in process.
Pruning options can be provided via the '--pruning' flag. The options are as follows: Pruning options can be provided via the '--pruning' flag or alternatively with '--pruning-snapshot-every' and 'pruning-keep-every' together.
For '--pruning' the options are as follows:
syncable: only those states not needed for state syncing will be deleted (flushes every 100th to disk and keeps every 10000th) syncable: only those states not needed for state syncing will be deleted (flushes every 100th to disk and keeps every 10000th)
nothing: all historic states will be saved, nothing will be deleted (i.e. archiving node) nothing: all historic states will be saved, nothing will be deleted (i.e. archiving node)
@ -56,6 +71,9 @@ will not be able to commit subsequent blocks.
For profiling and benchmarking purposes, CPU profiling can be enabled via the '--cpu-profile' flag For profiling and benchmarking purposes, CPU profiling can be enabled via the '--cpu-profile' flag
which accepts a path for the resulting pprof file. which accepts a path for the resulting pprof file.
`, `,
PreRunE: func(cmd *cobra.Command, args []string) error {
return checkPruningParams()
},
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
if !viper.GetBool(flagWithTendermint) { if !viper.GetBool(flagWithTendermint) {
ctx.Logger.Info("starting ABCI without Tendermint") ctx.Logger.Info("starting ABCI without Tendermint")
@ -74,6 +92,8 @@ which accepts a path for the resulting pprof file.
cmd.Flags().String(flagAddress, "tcp://0.0.0.0:26658", "Listen address") cmd.Flags().String(flagAddress, "tcp://0.0.0.0:26658", "Listen address")
cmd.Flags().String(flagTraceStore, "", "Enable KVStore tracing to an output file") cmd.Flags().String(flagTraceStore, "", "Enable KVStore tracing to an output file")
cmd.Flags().String(flagPruning, "syncable", "Pruning strategy: syncable, nothing, everything") cmd.Flags().String(flagPruning, "syncable", "Pruning strategy: syncable, nothing, everything")
cmd.Flags().Int64(flagPruningKeepEvery, 0, "Define the state number that will be kept")
cmd.Flags().Int64(flagPruningSnapshotEvery, 0, "Defines the state that will be snapshot for pruning")
cmd.Flags().String( cmd.Flags().String(
FlagMinGasPrices, "", FlagMinGasPrices, "",
"Minimum gas prices to accept for transactions; Any fee in a tx must meet this minimum (e.g. 0.01photino;0.0001stake)", "Minimum gas prices to accept for transactions; Any fee in a tx must meet this minimum (e.g. 0.01photino;0.0001stake)",
@ -89,6 +109,27 @@ which accepts a path for the resulting pprof file.
return cmd return cmd
} }
// checkPruningParams checks that the provided pruning params are correct
func checkPruningParams() error {
if !viper.IsSet(flagPruning) && !viper.IsSet(flagPruningKeepEvery) && !viper.IsSet(flagPruningSnapshotEvery) {
return nil
}
if viper.IsSet(flagPruning) {
if viper.IsSet(flagPruningKeepEvery) || viper.IsSet(flagPruningSnapshotEvery) {
return errPruningWithGranularOptions
}
return nil
}
if !(viper.IsSet(flagPruningKeepEvery) && viper.IsSet(flagPruningSnapshotEvery)) {
return errPruningGranularOptions
}
return nil
}
func startStandAlone(ctx *Context, appCreator AppCreator) error { func startStandAlone(ctx *Context, appCreator AppCreator) error {
addr := viper.GetString(flagAddress) addr := viper.GetString(flagAddress)
home := viper.GetString("home") home := viper.GetString("home")

104
server/start_test.go Normal file
View File

@ -0,0 +1,104 @@
package server
import (
"testing"
"github.com/spf13/viper"
"github.com/stretchr/testify/require"
)
func TestPruningOptions(t *testing.T) {
startCommand := StartCmd(nil, nil)
tests := []struct {
name string
paramInit func()
returnsErr bool
expectedErr error
}{
{
name: "none set, returns nil and will use default from flags",
paramInit: func() {},
returnsErr: false,
expectedErr: nil,
},
{
name: "only keep-every provided",
paramInit: func() {
viper.Set(flagPruningKeepEvery, 12345)
},
returnsErr: true,
expectedErr: errPruningGranularOptions,
},
{
name: "only snapshot-every provided",
paramInit: func() {
viper.Set(flagPruningSnapshotEvery, 12345)
},
returnsErr: true,
expectedErr: errPruningGranularOptions,
},
{
name: "pruning flag with other granular options 1",
paramInit: func() {
viper.Set(flagPruning, "set")
viper.Set(flagPruningSnapshotEvery, 1234)
},
returnsErr: true,
expectedErr: errPruningWithGranularOptions,
},
{
name: "pruning flag with other granular options 2",
paramInit: func() {
viper.Set(flagPruning, "set")
viper.Set(flagPruningKeepEvery, 1234)
},
returnsErr: true,
expectedErr: errPruningWithGranularOptions,
},
{
name: "pruning flag with other granular options 3",
paramInit: func() {
viper.Set(flagPruning, "set")
viper.Set(flagPruningKeepEvery, 1234)
viper.Set(flagPruningSnapshotEvery, 1234)
},
returnsErr: true,
expectedErr: errPruningWithGranularOptions,
},
{
name: "only prunning set",
paramInit: func() {
viper.Set(flagPruning, "set")
},
returnsErr: false,
expectedErr: nil,
},
{
name: "only granular set",
paramInit: func() {
viper.Set(flagPruningSnapshotEvery, 12345)
viper.Set(flagPruningKeepEvery, 12345)
},
returnsErr: false,
expectedErr: nil,
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
viper.Reset()
tt.paramInit()
err := startCommand.PreRunE(nil, nil)
if tt.returnsErr {
require.EqualError(t, err, tt.expectedErr.Error())
} else {
require.NoError(t, err)
}
})
}
}

View File

@ -0,0 +1,70 @@
package dbadapter_test
import (
"bytes"
"errors"
"testing"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/store/dbadapter"
"github.com/cosmos/cosmos-sdk/store/types"
"github.com/cosmos/cosmos-sdk/tests/mocks"
)
var errFoo = errors.New("dummy")
func TestAccessors(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
mockDB := mocks.NewMockDB(mockCtrl)
store := dbadapter.Store{mockDB}
key := []byte("test")
value := []byte("testvalue")
require.Equal(t, types.StoreTypeDB, store.GetStoreType())
store.GetStoreType()
retFoo := []byte("xxx")
mockDB.EXPECT().Get(gomock.Eq(key)).Times(1).Return(retFoo, nil)
require.True(t, bytes.Equal(retFoo, store.Get(key)))
mockDB.EXPECT().Get(gomock.Eq(key)).Times(1).Return(nil, errFoo)
require.Panics(t, func() { store.Get(key) })
mockDB.EXPECT().Has(gomock.Eq(key)).Times(1).Return(true, nil)
require.True(t, store.Has(key))
mockDB.EXPECT().Has(gomock.Eq(key)).Times(1).Return(false, nil)
require.False(t, store.Has(key))
mockDB.EXPECT().Has(gomock.Eq(key)).Times(1).Return(false, errFoo)
require.Panics(t, func() { store.Has(key) })
mockDB.EXPECT().Set(gomock.Eq(key), gomock.Eq(value)).Times(1).Return(nil)
require.NotPanics(t, func() { store.Set(key, value) })
mockDB.EXPECT().Set(gomock.Eq(key), gomock.Eq(value)).Times(1).Return(errFoo)
require.Panics(t, func() { store.Set(key, value) })
mockDB.EXPECT().Delete(gomock.Eq(key)).Times(1).Return(nil)
require.NotPanics(t, func() { store.Delete(key) })
mockDB.EXPECT().Delete(gomock.Eq(key)).Times(1).Return(errFoo)
require.Panics(t, func() { store.Delete(key) })
start, end := []byte("start"), []byte("end")
mockDB.EXPECT().Iterator(gomock.Eq(start), gomock.Eq(end)).Times(1).Return(nil, nil)
require.NotPanics(t, func() { store.Iterator(start, end) })
mockDB.EXPECT().Iterator(gomock.Eq(start), gomock.Eq(end)).Times(1).Return(nil, errFoo)
require.Panics(t, func() { store.Iterator(start, end) })
mockDB.EXPECT().ReverseIterator(gomock.Eq(start), gomock.Eq(end)).Times(1).Return(nil, nil)
require.NotPanics(t, func() { store.ReverseIterator(start, end) })
mockDB.EXPECT().ReverseIterator(gomock.Eq(start), gomock.Eq(end)).Times(1).Return(nil, errFoo)
require.Panics(t, func() { store.ReverseIterator(start, end) })
}

View File

@ -5,7 +5,7 @@ import (
tmkv "github.com/tendermint/tendermint/libs/kv" tmkv "github.com/tendermint/tendermint/libs/kv"
"github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types"
) )
// Gets the first item. // Gets the first item.
@ -24,7 +24,7 @@ func Last(st KVStore, start, end []byte) (kv tmkv.Pair, ok bool) {
iter := st.ReverseIterator(end, start) iter := st.ReverseIterator(end, start)
if !iter.Valid() { if !iter.Valid() {
if v := st.Get(start); v != nil { if v := st.Get(start); v != nil {
return tmkv.Pair{Key: types.Cp(start), Value: types.Cp(v)}, true return tmkv.Pair{Key: sdk.CopyBytes(start), Value: sdk.CopyBytes(v)}, true
} }
return kv, false return kv, false
} }

View File

@ -22,6 +22,11 @@ func TestGasKVStoreBasic(t *testing.T) {
mem := dbadapter.Store{DB: dbm.NewMemDB()} mem := dbadapter.Store{DB: dbm.NewMemDB()}
meter := types.NewGasMeter(10000) meter := types.NewGasMeter(10000)
st := gaskv.NewStore(mem, meter, types.KVGasConfig()) st := gaskv.NewStore(mem, meter, types.KVGasConfig())
require.Equal(t, types.StoreTypeDB, st.GetStoreType())
require.Panics(t, func() { st.CacheWrap() })
require.Panics(t, func() { st.CacheWrapWithTrace(nil, nil) })
require.Empty(t, st.Get(keyFmt(1)), "Expected `key1` to be empty") require.Empty(t, st.Get(keyFmt(1)), "Expected `key1` to be empty")
st.Set(keyFmt(1), valFmt(1)) st.Set(keyFmt(1), valFmt(1))
require.Equal(t, valFmt(1), st.Get(keyFmt(1))) require.Equal(t, valFmt(1), st.Get(keyFmt(1)))
@ -34,11 +39,20 @@ func TestGasKVStoreIterator(t *testing.T) {
mem := dbadapter.Store{DB: dbm.NewMemDB()} mem := dbadapter.Store{DB: dbm.NewMemDB()}
meter := types.NewGasMeter(10000) meter := types.NewGasMeter(10000)
st := gaskv.NewStore(mem, meter, types.KVGasConfig()) st := gaskv.NewStore(mem, meter, types.KVGasConfig())
require.False(t, st.Has(keyFmt(1)))
require.Empty(t, st.Get(keyFmt(1)), "Expected `key1` to be empty") require.Empty(t, st.Get(keyFmt(1)), "Expected `key1` to be empty")
require.Empty(t, st.Get(keyFmt(2)), "Expected `key2` to be empty") require.Empty(t, st.Get(keyFmt(2)), "Expected `key2` to be empty")
st.Set(keyFmt(1), valFmt(1)) st.Set(keyFmt(1), valFmt(1))
require.True(t, st.Has(keyFmt(1)))
st.Set(keyFmt(2), valFmt(2)) st.Set(keyFmt(2), valFmt(2))
iterator := st.Iterator(nil, nil) iterator := st.Iterator(nil, nil)
start, end := iterator.Domain()
require.Nil(t, start)
require.Nil(t, end)
require.NoError(t, iterator.Error())
t.Cleanup(iterator.Close)
ka := iterator.Key() ka := iterator.Key()
require.Equal(t, ka, keyFmt(1)) require.Equal(t, ka, keyFmt(1))
va := iterator.Value() va := iterator.Value()
@ -51,7 +65,18 @@ func TestGasKVStoreIterator(t *testing.T) {
iterator.Next() iterator.Next()
require.False(t, iterator.Valid()) require.False(t, iterator.Valid())
require.Panics(t, iterator.Next) require.Panics(t, iterator.Next)
require.Equal(t, meter.GasConsumed(), types.Gas(6987)) require.NoError(t, iterator.Error())
reverseIterator := st.ReverseIterator(nil, nil)
t.Cleanup(reverseIterator.Close)
require.Equal(t, reverseIterator.Key(), keyFmt(2))
reverseIterator.Next()
require.Equal(t, reverseIterator.Key(), keyFmt(1))
reverseIterator.Next()
require.False(t, reverseIterator.Valid())
require.Panics(t, reverseIterator.Next)
require.Equal(t, types.Gas(9194), meter.GasConsumed())
} }
func TestGasKVStoreOutOfGasSet(t *testing.T) { func TestGasKVStoreOutOfGasSet(t *testing.T) {

View File

@ -15,6 +15,7 @@ import (
"github.com/cosmos/cosmos-sdk/store/cachekv" "github.com/cosmos/cosmos-sdk/store/cachekv"
"github.com/cosmos/cosmos-sdk/store/tracekv" "github.com/cosmos/cosmos-sdk/store/tracekv"
"github.com/cosmos/cosmos-sdk/store/types" "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
) )
@ -357,8 +358,8 @@ var _ types.Iterator = (*iavlIterator)(nil)
func newIAVLIterator(tree *iavl.ImmutableTree, start, end []byte, ascending bool) *iavlIterator { func newIAVLIterator(tree *iavl.ImmutableTree, start, end []byte, ascending bool) *iavlIterator {
iter := &iavlIterator{ iter := &iavlIterator{
tree: tree, tree: tree,
start: types.Cp(start), start: sdk.CopyBytes(start),
end: types.Cp(end), end: sdk.CopyBytes(end),
ascending: ascending, ascending: ascending,
iterCh: make(chan tmkv.Pair), // Set capacity > 0? iterCh: make(chan tmkv.Pair), // Set capacity > 0?
quitCh: make(chan struct{}), quitCh: make(chan struct{}),

37
store/iavl/tree_test.go Normal file
View File

@ -0,0 +1,37 @@
package iavl
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/tendermint/iavl"
dbm "github.com/tendermint/tm-db"
)
func TestImmutableTreePanics(t *testing.T) {
t.Parallel()
immTree := iavl.NewImmutableTree(dbm.NewMemDB(), 100)
it := &immutableTree{immTree}
require.Panics(t, func() { it.Set([]byte{}, []byte{}) })
require.Panics(t, func() { it.Remove([]byte{}) })
require.Panics(t, func() { it.SaveVersion() })
require.Panics(t, func() { it.DeleteVersion(int64(1)) })
v, _ := it.GetVersioned([]byte{0x01}, 1)
require.Equal(t, int64(-1), v)
v, _ = it.GetVersioned([]byte{0x01}, 0)
require.Equal(t, int64(0), v)
val, proof, err := it.GetVersionedWithProof(nil, 1)
require.Error(t, err)
require.Nil(t, val)
require.Nil(t, proof)
imm, err := it.GetImmutable(1)
require.Error(t, err)
require.Nil(t, imm)
imm, err = it.GetImmutable(0)
require.NoError(t, err)
require.NotNil(t, imm)
require.Equal(t, immTree, imm)
}

View File

@ -1,15 +1,18 @@
package transient package transient_test
import ( import (
"bytes"
"testing" "testing"
"github.com/cosmos/cosmos-sdk/store/transient"
"github.com/cosmos/cosmos-sdk/store/types"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
var k, v = []byte("hello"), []byte("world") var k, v = []byte("hello"), []byte("world")
func TestTransientStore(t *testing.T) { func TestTransientStore(t *testing.T) {
tstore := NewStore() tstore := transient.NewStore()
require.Nil(t, tstore.Get(k)) require.Nil(t, tstore.Get(k))
@ -20,4 +23,12 @@ func TestTransientStore(t *testing.T) {
tstore.Commit() tstore.Commit()
require.Nil(t, tstore.Get(k)) require.Nil(t, tstore.Get(k))
// no-op
tstore.SetPruning(types.PruningOptions{})
emptyCommitID := tstore.LastCommitID()
require.Equal(t, emptyCommitID.Version, int64(0))
require.True(t, bytes.Equal(emptyCommitID.Hash, nil))
require.Equal(t, types.StoreTypeTransient, tstore.GetStoreType())
} }

View File

@ -7,7 +7,23 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
func TestInfiniteGasMeter(t *testing.T) {
t.Parallel()
meter := NewInfiniteGasMeter()
require.Equal(t, uint64(0), meter.Limit())
require.Equal(t, uint64(0), meter.GasConsumed())
require.Equal(t, uint64(0), meter.GasConsumedToLimit())
meter.ConsumeGas(10, "consume 10")
require.Equal(t, uint64(10), meter.GasConsumed())
require.Equal(t, uint64(10), meter.GasConsumedToLimit())
require.False(t, meter.IsPastLimit())
require.False(t, meter.IsOutOfGas())
meter.ConsumeGas(Gas(math.MaxUint64/2), "consume half max uint64")
require.Panics(t, func() { meter.ConsumeGas(Gas(math.MaxUint64/2)+2, "panic") })
}
func TestGasMeter(t *testing.T) { func TestGasMeter(t *testing.T) {
t.Parallel()
cases := []struct { cases := []struct {
limit Gas limit Gas
usage []Gas usage []Gas
@ -41,11 +57,14 @@ func TestGasMeter(t *testing.T) {
require.Panics(t, func() { meter.ConsumeGas(1, "") }, "Exceeded but not panicked. tc #%d", tcnum) require.Panics(t, func() { meter.ConsumeGas(1, "") }, "Exceeded but not panicked. tc #%d", tcnum)
require.Equal(t, meter.GasConsumedToLimit(), meter.Limit(), "Gas consumption (to limit) not match limit") require.Equal(t, meter.GasConsumedToLimit(), meter.Limit(), "Gas consumption (to limit) not match limit")
require.Equal(t, meter.GasConsumed(), meter.Limit()+1, "Gas consumption not match limit+1") require.Equal(t, meter.GasConsumed(), meter.Limit()+1, "Gas consumption not match limit+1")
meter2 := NewGasMeter(math.MaxUint64)
meter2.ConsumeGas(Gas(math.MaxUint64/2), "consume half max uint64")
require.Panics(t, func() { meter2.ConsumeGas(Gas(math.MaxUint64/2)+2, "panic") })
} }
} }
func TestAddUint64Overflow(t *testing.T) { func TestAddUint64Overflow(t *testing.T) {
t.Parallel()
testCases := []struct { testCases := []struct {
a, b uint64 a, b uint64
result uint64 result uint64
@ -69,3 +88,17 @@ func TestAddUint64Overflow(t *testing.T) {
) )
} }
} }
func TestTransientGasConfig(t *testing.T) {
t.Parallel()
config := TransientGasConfig()
require.Equal(t, config, GasConfig{
HasCost: 1000,
DeleteCost: 1000,
ReadCostFlat: 1000,
ReadCostPerByte: 3,
WriteCostFlat: 2000,
WriteCostPerByte: 30,
IterNextCostFlat: 30,
})
}

View File

@ -0,0 +1,79 @@
package types_test
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/store/types"
)
func TestPruningOptions_FlushVersion(t *testing.T) {
t.Parallel()
require.True(t, types.PruneEverything.FlushVersion(-1))
require.True(t, types.PruneEverything.FlushVersion(0))
require.True(t, types.PruneEverything.FlushVersion(1))
require.True(t, types.PruneEverything.FlushVersion(2))
require.True(t, types.PruneNothing.FlushVersion(-1))
require.True(t, types.PruneNothing.FlushVersion(0))
require.True(t, types.PruneNothing.FlushVersion(1))
require.True(t, types.PruneNothing.FlushVersion(2))
require.False(t, types.PruneSyncable.FlushVersion(-1))
require.True(t, types.PruneSyncable.FlushVersion(0))
require.False(t, types.PruneSyncable.FlushVersion(1))
require.True(t, types.PruneSyncable.FlushVersion(100))
require.False(t, types.PruneSyncable.FlushVersion(101))
}
func TestPruningOptions_SnapshotVersion(t *testing.T) {
t.Parallel()
require.False(t, types.PruneEverything.SnapshotVersion(-1))
require.False(t, types.PruneEverything.SnapshotVersion(0))
require.False(t, types.PruneEverything.SnapshotVersion(1))
require.False(t, types.PruneEverything.SnapshotVersion(2))
require.True(t, types.PruneNothing.SnapshotVersion(-1))
require.True(t, types.PruneNothing.SnapshotVersion(0))
require.True(t, types.PruneNothing.SnapshotVersion(1))
require.True(t, types.PruneNothing.SnapshotVersion(2))
require.False(t, types.PruneSyncable.SnapshotVersion(-1))
require.True(t, types.PruneSyncable.SnapshotVersion(0))
require.False(t, types.PruneSyncable.SnapshotVersion(1))
require.True(t, types.PruneSyncable.SnapshotVersion(10000))
require.False(t, types.PruneSyncable.SnapshotVersion(10001))
}
func TestPruningOptions_IsValid(t *testing.T) {
t.Parallel()
type fields struct {
KeepEvery int64
SnapshotEvery int64
}
tests := []struct {
name string
fields fields
want bool
}{
{"PruneEverything", fields{types.PruneEverything.KeepEvery, types.PruneEverything.SnapshotEvery}, true},
{"PruneNothing", fields{types.PruneNothing.KeepEvery, types.PruneNothing.SnapshotEvery}, true},
{"PruneSyncable", fields{types.PruneSyncable.KeepEvery, types.PruneSyncable.SnapshotEvery}, true},
{"KeepEvery=0", fields{0, 0}, false},
{"KeepEvery<0", fields{-1, 0}, false},
{"SnapshotEvery<0", fields{1, -1}, false},
{"SnapshotEvery%KeepEvery!=0", fields{15, 30}, true},
{"SnapshotEvery%KeepEvery!=0", fields{15, 20}, false},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
po := types.PruningOptions{
KeepEvery: tt.fields.KeepEvery,
SnapshotEvery: tt.fields.SnapshotEvery,
}
require.Equal(t, tt.want, po.IsValid(), "IsValid() = %v, want %v", po.IsValid(), tt.want)
})
}
}

View File

@ -1,12 +1,15 @@
package types package types
import ( import (
"fmt"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
) )
func TestStoreUpgrades(t *testing.T) { func TestStoreUpgrades(t *testing.T) {
t.Parallel()
type toDelete struct { type toDelete struct {
key string key string
delete bool delete bool
@ -55,3 +58,27 @@ func TestStoreUpgrades(t *testing.T) {
}) })
} }
} }
func TestCommitID(t *testing.T) {
t.Parallel()
require.True(t, CommitID{}.IsZero())
require.False(t, CommitID{Version: int64(1)}.IsZero())
require.False(t, CommitID{Hash: []byte("x")}.IsZero())
require.Equal(t, "CommitID{[120 120 120 120]:64}", CommitID{Version: int64(100), Hash: []byte("xxxx")}.String())
}
func TestKVStoreKey(t *testing.T) {
t.Parallel()
key := NewKVStoreKey("test")
require.Equal(t, "test", key.name)
require.Equal(t, key.name, key.Name())
require.Equal(t, fmt.Sprintf("KVStoreKey{%p, test}", key), key.String())
}
func TestTransientStoreKey(t *testing.T) {
t.Parallel()
key := NewTransientStoreKey("test")
require.Equal(t, "test", key.name)
require.Equal(t, key.name, key.Name())
require.Equal(t, fmt.Sprintf("TransientStoreKey{%p, test}", key), key.String())
}

View File

@ -17,15 +17,18 @@ func KVStoreReversePrefixIterator(kvs KVStore, prefix []byte) Iterator {
} }
// DiffKVStores compares two KVstores and returns all the key/value pairs // DiffKVStores compares two KVstores and returns all the key/value pairs
// that differ from one another. It also skips value comparison for a set of provided prefixes // that differ from one another. It also skips value comparison for a set of provided prefixes.
func DiffKVStores(a KVStore, b KVStore, prefixesToSkip [][]byte) (kvAs, kvBs []tmkv.Pair) { func DiffKVStores(a KVStore, b KVStore, prefixesToSkip [][]byte) (kvAs, kvBs []tmkv.Pair) {
iterA := a.Iterator(nil, nil) iterA := a.Iterator(nil, nil)
defer iterA.Close()
iterB := b.Iterator(nil, nil) iterB := b.Iterator(nil, nil)
defer iterB.Close()
for { for {
if !iterA.Valid() && !iterB.Valid() { if !iterA.Valid() && !iterB.Valid() {
break return kvAs, kvBs
} }
var kvA, kvB tmkv.Pair var kvA, kvB tmkv.Pair
if iterA.Valid() { if iterA.Valid() {
kvA = tmkv.Pair{Key: iterA.Key(), Value: iterA.Value()} kvA = tmkv.Pair{Key: iterA.Key(), Value: iterA.Value()}
@ -38,7 +41,9 @@ func DiffKVStores(a KVStore, b KVStore, prefixesToSkip [][]byte) (kvAs, kvBs []t
if !bytes.Equal(kvA.Key, kvB.Key) { if !bytes.Equal(kvA.Key, kvB.Key) {
kvAs = append(kvAs, kvA) kvAs = append(kvAs, kvA)
kvBs = append(kvBs, kvB) kvBs = append(kvBs, kvB)
continue // no need to compare the value
} }
compareValue := true compareValue := true
for _, prefix := range prefixesToSkip { for _, prefix := range prefixesToSkip {
// Skip value comparison if we matched a prefix // Skip value comparison if we matched a prefix
@ -51,7 +56,6 @@ func DiffKVStores(a KVStore, b KVStore, prefixesToSkip [][]byte) (kvAs, kvBs []t
kvBs = append(kvBs, kvB) kvBs = append(kvBs, kvB)
} }
} }
return kvAs, kvBs
} }
// PrefixEndBytes returns the []byte that would end a // PrefixEndBytes returns the []byte that would end a
@ -69,13 +73,13 @@ func PrefixEndBytes(prefix []byte) []byte {
if end[len(end)-1] != byte(255) { if end[len(end)-1] != byte(255) {
end[len(end)-1]++ end[len(end)-1]++
break break
} else {
end = end[:len(end)-1]
if len(end) == 0 {
end = nil
break
}
} }
end = end[:len(end)-1]
if len(end) == 0 {
end = nil
break
}
} }
return end return end
} }
@ -85,13 +89,3 @@ func PrefixEndBytes(prefix []byte) []byte {
func InclusiveEndBytes(inclusiveBytes []byte) []byte { func InclusiveEndBytes(inclusiveBytes []byte) []byte {
return append(inclusiveBytes, byte(0x00)) return append(inclusiveBytes, byte(0x00))
} }
//----------------------------------------
func Cp(bz []byte) (ret []byte) {
if bz == nil {
return nil
}
ret = make([]byte, len(bz))
copy(ret, bz)
return ret
}

88
store/types/utils_test.go Normal file
View File

@ -0,0 +1,88 @@
package types_test
import (
"bytes"
"testing"
"github.com/stretchr/testify/require"
dbm "github.com/tendermint/tm-db"
"github.com/cosmos/cosmos-sdk/store/rootmulti"
"github.com/cosmos/cosmos-sdk/store/types"
)
func initTestStores(t *testing.T) (types.KVStore, types.KVStore) {
db := dbm.NewMemDB()
ms := rootmulti.NewStore(db)
key1 := types.NewKVStoreKey("store1")
key2 := types.NewKVStoreKey("store2")
require.NotPanics(t, func() { ms.MountStoreWithDB(key1, types.StoreTypeIAVL, db) })
require.NotPanics(t, func() { ms.MountStoreWithDB(key2, types.StoreTypeIAVL, db) })
require.NoError(t, ms.LoadLatestVersion())
return ms.GetKVStore(key1), ms.GetKVStore(key2)
}
func TestDiffKVStores(t *testing.T) {
t.Parallel()
store1, store2 := initTestStores(t)
// Two equal stores
k1, v1 := []byte("k1"), []byte("v1")
store1.Set(k1, v1)
store2.Set(k1, v1)
kvAs, kvBs := types.DiffKVStores(store1, store2, nil)
require.Equal(t, 0, len(kvAs))
require.Equal(t, len(kvAs), len(kvBs))
// delete k1 from store2, which is now empty
store2.Delete(k1)
kvAs, kvBs = types.DiffKVStores(store1, store2, nil)
require.Equal(t, 1, len(kvAs))
require.Equal(t, len(kvAs), len(kvBs))
// set k1 in store2, different value than what store1 holds for k1
v2 := []byte("v2")
store2.Set(k1, v2)
kvAs, kvBs = types.DiffKVStores(store1, store2, nil)
require.Equal(t, 1, len(kvAs))
require.Equal(t, len(kvAs), len(kvBs))
// add k2 to store2
k2 := []byte("k2")
store2.Set(k2, v2)
kvAs, kvBs = types.DiffKVStores(store1, store2, nil)
require.Equal(t, 2, len(kvAs))
require.Equal(t, len(kvAs), len(kvBs))
// Reset stores
store1.Delete(k1)
store2.Delete(k1)
store2.Delete(k2)
// Same keys, different value. Comparisons will be nil as prefixes are skipped.
prefix := []byte("prefix:")
k1Prefixed := append(prefix, k1...)
store1.Set(k1Prefixed, v1)
store2.Set(k1Prefixed, v2)
kvAs, kvBs = types.DiffKVStores(store1, store2, [][]byte{prefix})
require.Equal(t, 0, len(kvAs))
require.Equal(t, len(kvAs), len(kvBs))
}
func TestPrefixEndBytes(t *testing.T) {
t.Parallel()
bs1 := []byte{0x23, 0xA5, 0x06}
require.True(t, bytes.Equal([]byte{0x23, 0xA5, 0x07}, types.PrefixEndBytes(bs1)))
bs2 := []byte{0x23, 0xA5, 0xFF}
require.True(t, bytes.Equal([]byte{0x23, 0xA6}, types.PrefixEndBytes(bs2)))
require.Nil(t, types.PrefixEndBytes([]byte{0xFF}))
require.Nil(t, types.PrefixEndBytes(nil))
}
func TestInclusiveEndBytes(t *testing.T) {
t.Parallel()
require.True(t, bytes.Equal([]byte{0x00}, types.InclusiveEndBytes(nil)))
bs := []byte("test")
require.True(t, bytes.Equal(append(bs, byte(0x00)), types.InclusiveEndBytes(bs)))
}

View File

@ -0,0 +1,23 @@
package types_test
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/cosmos/cosmos-sdk/store/types"
)
func TestAssertValidKey(t *testing.T) {
t.Parallel()
require.NotPanics(t, func() { types.AssertValidKey([]byte{}) })
require.NotPanics(t, func() { types.AssertValidKey([]byte{0x01}) })
require.Panics(t, func() { types.AssertValidKey(nil) })
}
func TestAssertValidValue(t *testing.T) {
t.Parallel()
require.NotPanics(t, func() { types.AssertValidValue([]byte{}) })
require.NotPanics(t, func() { types.AssertValidValue([]byte{0x01}) })
require.Panics(t, func() { types.AssertValidValue(nil) })
}

View File

@ -1,30 +1,38 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: x/auth/types/account_retriever.go
// Package mocks is a generated GoMock package.
package mocks package mocks
import ( import (
reflect "reflect"
gomock "github.com/golang/mock/gomock" gomock "github.com/golang/mock/gomock"
reflect "reflect"
) )
// MockNodeQuerier is a mock of NodeQuerier interface
type MockNodeQuerier struct { type MockNodeQuerier struct {
ctrl *gomock.Controller ctrl *gomock.Controller
recorder *MockNodeQuerierMockRecorder recorder *MockNodeQuerierMockRecorder
} }
// MockNodeQuerierMockRecorder is the mock recorder for MockNodeQuerier
type MockNodeQuerierMockRecorder struct { type MockNodeQuerierMockRecorder struct {
mock *MockNodeQuerier mock *MockNodeQuerier
} }
// NewMockNodeQuerier creates a new mock instance
func NewMockNodeQuerier(ctrl *gomock.Controller) *MockNodeQuerier { func NewMockNodeQuerier(ctrl *gomock.Controller) *MockNodeQuerier {
mock := &MockNodeQuerier{ctrl: ctrl} mock := &MockNodeQuerier{ctrl: ctrl}
mock.recorder = &MockNodeQuerierMockRecorder{mock} mock.recorder = &MockNodeQuerierMockRecorder{mock}
return mock return mock
} }
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockNodeQuerier) EXPECT() *MockNodeQuerierMockRecorder { func (m *MockNodeQuerier) EXPECT() *MockNodeQuerierMockRecorder {
return m.recorder return m.recorder
} }
// QueryWithData mocks base method
func (m *MockNodeQuerier) QueryWithData(path string, data []byte) ([]byte, int64, error) { func (m *MockNodeQuerier) QueryWithData(path string, data []byte) ([]byte, int64, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "QueryWithData", path, data) ret := m.ctrl.Call(m, "QueryWithData", path, data)
@ -34,6 +42,7 @@ func (m *MockNodeQuerier) QueryWithData(path string, data []byte) ([]byte, int64
return ret0, ret1, ret2 return ret0, ret1, ret2
} }
// QueryWithData indicates an expected call of QueryWithData
func (mr *MockNodeQuerierMockRecorder) QueryWithData(path, data interface{}) *gomock.Call { func (mr *MockNodeQuerierMockRecorder) QueryWithData(path, data interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper() mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryWithData", reflect.TypeOf((*MockNodeQuerier)(nil).QueryWithData), path, data) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryWithData", reflect.TypeOf((*MockNodeQuerier)(nil).QueryWithData), path, data)

View File

@ -0,0 +1,206 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/tendermint/tm-db (interfaces: DB)
// Package mocks is a generated GoMock package.
package mocks
import (
gomock "github.com/golang/mock/gomock"
tm_db "github.com/tendermint/tm-db"
reflect "reflect"
)
// MockDB is a mock of DB interface
type MockDB struct {
ctrl *gomock.Controller
recorder *MockDBMockRecorder
}
// MockDBMockRecorder is the mock recorder for MockDB
type MockDBMockRecorder struct {
mock *MockDB
}
// NewMockDB creates a new mock instance
func NewMockDB(ctrl *gomock.Controller) *MockDB {
mock := &MockDB{ctrl: ctrl}
mock.recorder = &MockDBMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockDB) EXPECT() *MockDBMockRecorder {
return m.recorder
}
// Close mocks base method
func (m *MockDB) Close() error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Close")
ret0, _ := ret[0].(error)
return ret0
}
// Close indicates an expected call of Close
func (mr *MockDBMockRecorder) Close() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockDB)(nil).Close))
}
// Delete mocks base method
func (m *MockDB) Delete(arg0 []byte) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Delete", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// Delete indicates an expected call of Delete
func (mr *MockDBMockRecorder) Delete(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockDB)(nil).Delete), arg0)
}
// DeleteSync mocks base method
func (m *MockDB) DeleteSync(arg0 []byte) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "DeleteSync", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// DeleteSync indicates an expected call of DeleteSync
func (mr *MockDBMockRecorder) DeleteSync(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteSync", reflect.TypeOf((*MockDB)(nil).DeleteSync), arg0)
}
// Get mocks base method
func (m *MockDB) Get(arg0 []byte) ([]byte, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Get", arg0)
ret0, _ := ret[0].([]byte)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Get indicates an expected call of Get
func (mr *MockDBMockRecorder) Get(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockDB)(nil).Get), arg0)
}
// Has mocks base method
func (m *MockDB) Has(arg0 []byte) (bool, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Has", arg0)
ret0, _ := ret[0].(bool)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Has indicates an expected call of Has
func (mr *MockDBMockRecorder) Has(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Has", reflect.TypeOf((*MockDB)(nil).Has), arg0)
}
// Iterator mocks base method
func (m *MockDB) Iterator(arg0, arg1 []byte) (tm_db.Iterator, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Iterator", arg0, arg1)
ret0, _ := ret[0].(tm_db.Iterator)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Iterator indicates an expected call of Iterator
func (mr *MockDBMockRecorder) Iterator(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Iterator", reflect.TypeOf((*MockDB)(nil).Iterator), arg0, arg1)
}
// NewBatch mocks base method
func (m *MockDB) NewBatch() tm_db.Batch {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "NewBatch")
ret0, _ := ret[0].(tm_db.Batch)
return ret0
}
// NewBatch indicates an expected call of NewBatch
func (mr *MockDBMockRecorder) NewBatch() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewBatch", reflect.TypeOf((*MockDB)(nil).NewBatch))
}
// Print mocks base method
func (m *MockDB) Print() error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Print")
ret0, _ := ret[0].(error)
return ret0
}
// Print indicates an expected call of Print
func (mr *MockDBMockRecorder) Print() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Print", reflect.TypeOf((*MockDB)(nil).Print))
}
// ReverseIterator mocks base method
func (m *MockDB) ReverseIterator(arg0, arg1 []byte) (tm_db.Iterator, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ReverseIterator", arg0, arg1)
ret0, _ := ret[0].(tm_db.Iterator)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// ReverseIterator indicates an expected call of ReverseIterator
func (mr *MockDBMockRecorder) ReverseIterator(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReverseIterator", reflect.TypeOf((*MockDB)(nil).ReverseIterator), arg0, arg1)
}
// Set mocks base method
func (m *MockDB) Set(arg0, arg1 []byte) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Set", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// Set indicates an expected call of Set
func (mr *MockDBMockRecorder) Set(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Set", reflect.TypeOf((*MockDB)(nil).Set), arg0, arg1)
}
// SetSync mocks base method
func (m *MockDB) SetSync(arg0, arg1 []byte) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SetSync", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// SetSync indicates an expected call of SetSync
func (mr *MockDBMockRecorder) SetSync(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSync", reflect.TypeOf((*MockDB)(nil).SetSync), arg0, arg1)
}
// Stats mocks base method
func (m *MockDB) Stats() map[string]string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Stats")
ret0, _ := ret[0].(map[string]string)
return ret0
}
// Stats indicates an expected call of Stats
func (mr *MockDBMockRecorder) Stats() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stats", reflect.TypeOf((*MockDB)(nil).Stats))
}

View File

@ -1,11 +0,0 @@
package types
// copy bytes
func CopyBytes(bz []byte) (ret []byte) {
if bz == nil {
return nil
}
ret = make([]byte, len(bz))
copy(ret, bz)
return ret
}

View File

@ -80,3 +80,13 @@ func NewLevelDB(name, dir string) (db dbm.DB, err error) {
}() }()
return dbm.NewDB(name, backend, dir), err return dbm.NewDB(name, backend, dir), err
} }
// copy bytes
func CopyBytes(bz []byte) (ret []byte) {
if bz == nil {
return nil
}
ret = make([]byte, len(bz))
copy(ret, bz)
return ret
}

View File

@ -1,6 +1,7 @@
package types package types
import ( import (
"bytes"
"testing" "testing"
"time" "time"
@ -66,3 +67,12 @@ func TestTimeFormatAndParse(t *testing.T) {
require.Equal(t, timeFromRFC.Format(SortableTimeFormat), tc.SDKSortableTimeStr) require.Equal(t, timeFromRFC.Format(SortableTimeFormat), tc.SDKSortableTimeStr)
} }
} }
func TestCopyBytes(t *testing.T) {
t.Parallel()
require.Nil(t, CopyBytes(nil))
require.Equal(t, 0, len(CopyBytes([]byte{})))
bs := []byte("test")
bsCopy := CopyBytes(bs)
require.True(t, bytes.Equal(bs, bsCopy))
}

View File

@ -27,10 +27,10 @@ import (
var testMbm = module.NewBasicManager(genutil.AppModuleBasic{}) var testMbm = module.NewBasicManager(genutil.AppModuleBasic{})
func TestInitCmd(t *testing.T) { func TestInitCmd(t *testing.T) {
defer server.SetupViper(t)() t.Cleanup(server.SetupViper(t))
defer setupClientHome(t)() t.Cleanup(server.SetupViper(t))
home, cleanup := tests.NewTestCaseDir(t) home, cleanup := tests.NewTestCaseDir(t)
defer cleanup() t.Cleanup(cleanup)
logger := log.NewNopLogger() logger := log.NewNopLogger()
cfg, err := tcmd.ParseConfig() cfg, err := tcmd.ParseConfig()
@ -50,11 +50,11 @@ func setupClientHome(t *testing.T) func() {
} }
func TestEmptyState(t *testing.T) { func TestEmptyState(t *testing.T) {
defer server.SetupViper(t)() t.Cleanup(server.SetupViper(t))
defer setupClientHome(t)() t.Cleanup(setupClientHome(t))
home, cleanup := tests.NewTestCaseDir(t) home, cleanup := tests.NewTestCaseDir(t)
defer cleanup() t.Cleanup(cleanup)
logger := log.NewNopLogger() logger := log.NewNopLogger()
cfg, err := tcmd.ParseConfig() cfg, err := tcmd.ParseConfig()
@ -94,9 +94,9 @@ func TestEmptyState(t *testing.T) {
func TestStartStandAlone(t *testing.T) { func TestStartStandAlone(t *testing.T) {
home, cleanup := tests.NewTestCaseDir(t) home, cleanup := tests.NewTestCaseDir(t)
defer cleanup() t.Cleanup(cleanup)
viper.Set(cli.HomeFlag, home) viper.Set(cli.HomeFlag, home)
defer setupClientHome(t)() t.Cleanup(setupClientHome(t))
logger := log.NewNopLogger() logger := log.NewNopLogger()
cfg, err := tcmd.ParseConfig() cfg, err := tcmd.ParseConfig()
@ -124,7 +124,7 @@ func TestStartStandAlone(t *testing.T) {
func TestInitNodeValidatorFiles(t *testing.T) { func TestInitNodeValidatorFiles(t *testing.T) {
home, cleanup := tests.NewTestCaseDir(t) home, cleanup := tests.NewTestCaseDir(t)
defer cleanup() t.Cleanup(cleanup)
viper.Set(cli.HomeFlag, home) viper.Set(cli.HomeFlag, home)
viper.Set(flags.FlagName, "moniker") viper.Set(flags.FlagName, "moniker")
cfg, err := tcmd.ParseConfig() cfg, err := tcmd.ParseConfig()

View File

@ -38,6 +38,7 @@ func TestGetMigrationCallback(t *testing.T) {
func TestMigrateGenesis(t *testing.T) { func TestMigrateGenesis(t *testing.T) {
home, cleanup := tests.NewTestCaseDir(t) home, cleanup := tests.NewTestCaseDir(t)
t.Cleanup(cleanup)
viper.Set(cli.HomeFlag, home) viper.Set(cli.HomeFlag, home)
viper.Set(flags.FlagName, "moniker") viper.Set(flags.FlagName, "moniker")
logger := log.NewNopLogger() logger := log.NewNopLogger()
@ -49,8 +50,6 @@ func TestMigrateGenesis(t *testing.T) {
genesisPath := path.Join(home, "genesis.json") genesisPath := path.Join(home, "genesis.json")
target := "v0.36" target := "v0.36"
defer cleanup()
// Reject if we dont' have the right parameters or genesis does not exists // Reject if we dont' have the right parameters or genesis does not exists
require.Error(t, MigrateGenesisCmd(ctx, cdc).RunE(nil, []string{target, genesisPath})) require.Error(t, MigrateGenesisCmd(ctx, cdc).RunE(nil, []string{target, genesisPath}))

View File

@ -14,7 +14,7 @@ import (
func TestExportGenesisFileWithTime(t *testing.T) { func TestExportGenesisFileWithTime(t *testing.T) {
t.Parallel() t.Parallel()
dir, cleanup := tests.NewTestCaseDir(t) dir, cleanup := tests.NewTestCaseDir(t)
defer cleanup() t.Cleanup(cleanup)
fname := filepath.Join(dir, "genesis.json") fname := filepath.Join(dir, "genesis.json")
require.NoError(t, ExportGenesisFileWithTime(fname, "test", nil, json.RawMessage(""), time.Now())) require.NoError(t, ExportGenesisFileWithTime(fname, "test", nil, json.RawMessage(""), time.Now()))

View File

@ -56,10 +56,6 @@ var (
pubkeys = []crypto.PubKey{ pubkeys = []crypto.PubKey{
delPk1, delPk2, delPk3, valOpPk1, valOpPk2, valOpPk3, delPk1, delPk2, delPk3, valOpPk1, valOpPk2, valOpPk3,
} }
emptyDelAddr sdk.AccAddress
emptyValAddr sdk.ValAddress
emptyPubkey crypto.PubKey
) )
// TODO: remove dependency with staking // TODO: remove dependency with staking
@ -76,7 +72,7 @@ func newPubKey(pk string) (res crypto.PubKey) {
panic(err) panic(err)
} }
var pkEd ed25519.PubKeyEd25519 var pkEd ed25519.PubKeyEd25519
copy(pkEd[:], pkBytes[:]) copy(pkEd[:], pkBytes)
return pkEd return pkEd
} }

View File

@ -68,8 +68,8 @@ func checkStore(t *testing.T, db dbm.DB, ver int64, storeKey string, k, v []byte
// Test that LoadLatestVersion actually does. // Test that LoadLatestVersion actually does.
func TestSetLoader(t *testing.T) { func TestSetLoader(t *testing.T) {
// set a temporary home dir // set a temporary home dir
homeDir, cleanUp := tests.NewTestCaseDir(t) homeDir, cleanup := tests.NewTestCaseDir(t)
defer cleanUp() t.Cleanup(cleanup)
// TODO cleanup viper // TODO cleanup viper
viper.Set(flags.FlagHome, homeDir) viper.Set(flags.FlagHome, homeDir)