Merge pull request #248 from cosmos/feature/separate-out-viper
Separate out viper
This commit is contained in:
commit
7c4cc3785e
|
@ -4,4 +4,3 @@ vendor
|
||||||
merkleeyes.db
|
merkleeyes.db
|
||||||
build
|
build
|
||||||
docs/guide/*.sh
|
docs/guide/*.sh
|
||||||
keys/
|
|
||||||
|
|
3
Makefile
3
Makefile
|
@ -3,7 +3,7 @@ GOTOOLS = github.com/mitchellh/gox \
|
||||||
github.com/rigelrozanski/shelldown/cmd/shelldown
|
github.com/rigelrozanski/shelldown/cmd/shelldown
|
||||||
TUTORIALS=$(shell find docs/guide -name "*md" -type f)
|
TUTORIALS=$(shell find docs/guide -name "*md" -type f)
|
||||||
|
|
||||||
EXAMPLES := counter eyes basecoin
|
EXAMPLES := counter eyes basecoin
|
||||||
INSTALL_EXAMPLES := $(addprefix install_,${EXAMPLES})
|
INSTALL_EXAMPLES := $(addprefix install_,${EXAMPLES})
|
||||||
TEST_EXAMPLES := $(addprefix testex_,${EXAMPLES})
|
TEST_EXAMPLES := $(addprefix testex_,${EXAMPLES})
|
||||||
|
|
||||||
|
@ -37,7 +37,6 @@ test_unit:
|
||||||
@go test `glide novendor`
|
@go test `glide novendor`
|
||||||
|
|
||||||
test_cli: $(TEST_EXAMPLES)
|
test_cli: $(TEST_EXAMPLES)
|
||||||
./tests/cli/init-server.sh
|
|
||||||
# sudo apt-get install jq
|
# sudo apt-get install jq
|
||||||
# wget "https://raw.githubusercontent.com/kward/shunit2/master/source/2.1/src/shunit2"
|
# wget "https://raw.githubusercontent.com/kward/shunit2/master/source/2.1/src/shunit2"
|
||||||
|
|
||||||
|
|
13
app/store.go
13
app/store.go
|
@ -10,7 +10,7 @@ import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
abci "github.com/tendermint/abci/types"
|
abci "github.com/tendermint/abci/types"
|
||||||
"github.com/tendermint/go-wire"
|
"github.com/tendermint/go-wire"
|
||||||
"github.com/tendermint/merkleeyes/iavl"
|
"github.com/tendermint/iavl"
|
||||||
cmn "github.com/tendermint/tmlibs/common"
|
cmn "github.com/tendermint/tmlibs/common"
|
||||||
dbm "github.com/tendermint/tmlibs/db"
|
dbm "github.com/tendermint/tmlibs/db"
|
||||||
"github.com/tendermint/tmlibs/log"
|
"github.com/tendermint/tmlibs/log"
|
||||||
|
@ -180,18 +180,13 @@ func (s *Store) Query(reqQuery abci.RequestQuery) (resQuery abci.ResponseQuery)
|
||||||
key := reqQuery.Data // Data holds the key bytes
|
key := reqQuery.Data // Data holds the key bytes
|
||||||
resQuery.Key = key
|
resQuery.Key = key
|
||||||
if reqQuery.Prove {
|
if reqQuery.Prove {
|
||||||
value, proofExists, proofNotExists, err := tree.GetWithProof(key)
|
value, proof, err := tree.GetWithProof(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resQuery.Log = err.Error()
|
resQuery.Log = err.Error()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
resQuery.Value = value
|
||||||
if value != nil {
|
resQuery.Proof = proof.Bytes()
|
||||||
resQuery.Value = value
|
|
||||||
resQuery.Proof = wire.BinaryBytes(proofExists)
|
|
||||||
} else {
|
|
||||||
resQuery.Proof = wire.BinaryBytes(proofNotExists)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
value := tree.Get(key)
|
value := tree.Get(key)
|
||||||
resQuery.Value = value
|
resQuery.Value = value
|
||||||
|
|
|
@ -13,14 +13,13 @@ import (
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
"github.com/tendermint/light-client/certifiers"
|
"github.com/tendermint/light-client/certifiers"
|
||||||
"github.com/tendermint/light-client/certifiers/client"
|
|
||||||
"github.com/tendermint/light-client/certifiers/files"
|
|
||||||
"github.com/tendermint/tmlibs/cli"
|
"github.com/tendermint/tmlibs/cli"
|
||||||
cmn "github.com/tendermint/tmlibs/common"
|
cmn "github.com/tendermint/tmlibs/common"
|
||||||
|
|
||||||
rpcclient "github.com/tendermint/tendermint/rpc/client"
|
rpcclient "github.com/tendermint/tendermint/rpc/client"
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk"
|
sdk "github.com/cosmos/cosmos-sdk"
|
||||||
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
"github.com/cosmos/cosmos-sdk/modules/auth"
|
"github.com/cosmos/cosmos-sdk/modules/auth"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -47,41 +46,40 @@ func GetChainID() string {
|
||||||
|
|
||||||
// GetNode prepares a simple rpc.Client from the flags
|
// GetNode prepares a simple rpc.Client from the flags
|
||||||
func GetNode() rpcclient.Client {
|
func GetNode() rpcclient.Client {
|
||||||
return rpcclient.NewHTTP(viper.GetString(NodeFlag), "/websocket")
|
return client.GetNode(viper.GetString(NodeFlag))
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSourceProvider returns a provider pointing to an rpc handler
|
||||||
|
func GetSourceProvider() certifiers.Provider {
|
||||||
|
if sourceProv == nil {
|
||||||
|
node := viper.GetString(NodeFlag)
|
||||||
|
sourceProv = client.GetRPCProvider(node)
|
||||||
|
}
|
||||||
|
return sourceProv
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTrustedProvider returns a reference to a local store with cache
|
||||||
|
func GetTrustedProvider() certifiers.Provider {
|
||||||
|
if trustedProv == nil {
|
||||||
|
rootDir := viper.GetString(cli.HomeFlag)
|
||||||
|
trustedProv = client.GetLocalProvider(rootDir)
|
||||||
|
}
|
||||||
|
return trustedProv
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetProviders creates a trusted (local) seed provider and a remote
|
// GetProviders creates a trusted (local) seed provider and a remote
|
||||||
// provider based on configuration.
|
// provider based on configuration.
|
||||||
func GetProviders() (trusted certifiers.Provider, source certifiers.Provider) {
|
func GetProviders() (trusted certifiers.Provider, source certifiers.Provider) {
|
||||||
if trustedProv == nil || sourceProv == nil {
|
return GetTrustedProvider(), GetSourceProvider()
|
||||||
// initialize provider with files stored in homedir
|
|
||||||
rootDir := viper.GetString(cli.HomeFlag)
|
|
||||||
trustedProv = certifiers.NewCacheProvider(
|
|
||||||
certifiers.NewMemStoreProvider(),
|
|
||||||
files.NewProvider(rootDir),
|
|
||||||
)
|
|
||||||
node := viper.GetString(NodeFlag)
|
|
||||||
sourceProv = client.NewHTTP(node)
|
|
||||||
}
|
|
||||||
return trustedProv, sourceProv
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCertifier constructs a dynamic certifier from the config info
|
// GetCertifier constructs a dynamic certifier from the config info
|
||||||
func GetCertifier() (*certifiers.InquiringCertifier, error) {
|
func GetCertifier() (*certifiers.InquiringCertifier, error) {
|
||||||
// load up the latest store....
|
// load up the latest store....
|
||||||
trust, source := GetProviders()
|
trust := GetTrustedProvider()
|
||||||
|
source := GetSourceProvider()
|
||||||
// this gets the most recent verified seed
|
chainID := GetChainID()
|
||||||
seed, err := certifiers.LatestSeed(trust)
|
return client.GetCertifier(chainID, trust, source)
|
||||||
if certifiers.IsSeedNotFoundErr(err) {
|
|
||||||
return nil, errors.New("Please run init first to establish a root of trust")
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
cert := certifiers.NewInquiring(
|
|
||||||
viper.GetString(ChainFlag), seed, trust, source)
|
|
||||||
return cert, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseActor parses an address of form:
|
// ParseActor parses an address of form:
|
||||||
|
|
|
@ -0,0 +1,117 @@
|
||||||
|
# Keys CLI
|
||||||
|
|
||||||
|
This is as much an example how to expose cobra/viper, as for a cli itself
|
||||||
|
(I think this code is overkill for what go-keys needs). But please look at
|
||||||
|
the commands, and give feedback and changes.
|
||||||
|
|
||||||
|
`RootCmd` calls some initialization functions (`cobra.OnInitialize` and `RootCmd.PersistentPreRunE`) which serve to connect environmental variables and cobra flags, as well as load the config file. It also validates the flags registered on root and creates the cryptomanager, which will be used by all subcommands.
|
||||||
|
|
||||||
|
## Help info
|
||||||
|
|
||||||
|
```
|
||||||
|
# keys help
|
||||||
|
|
||||||
|
Keys allows you to manage your local keystore for tendermint.
|
||||||
|
|
||||||
|
These keys may be in any format supported by go-crypto and can be
|
||||||
|
used by light-clients, full nodes, or any other application that
|
||||||
|
needs to sign with a private key.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
keys [command]
|
||||||
|
|
||||||
|
Available Commands:
|
||||||
|
get Get details of one key
|
||||||
|
list List all keys
|
||||||
|
new Create a new public/private key pair
|
||||||
|
serve Run the key manager as an http server
|
||||||
|
update Change the password for a private key
|
||||||
|
|
||||||
|
Flags:
|
||||||
|
--keydir string Directory to store private keys (subdir of root) (default "keys")
|
||||||
|
-o, --output string Output format (text|json) (default "text")
|
||||||
|
-r, --root string root directory for config and data (default "/Users/ethan/.tlc")
|
||||||
|
|
||||||
|
Use "keys [command] --help" for more information about a command.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Getting the config file
|
||||||
|
|
||||||
|
The first step is to load in root, by checking the following in order:
|
||||||
|
|
||||||
|
* -r, --root command line flag
|
||||||
|
* TM_ROOT environmental variable
|
||||||
|
* default ($HOME/.tlc evaluated at runtime)
|
||||||
|
|
||||||
|
Once the `rootDir` is established, the script looks for a config file named `keys.{json,toml,yaml,hcl}` in that directory and parses it. These values will provide defaults for flags of the same name.
|
||||||
|
|
||||||
|
There is an example config file for testing out locally, which writes keys to `./.mykeys`. You can
|
||||||
|
|
||||||
|
## Getting/Setting variables
|
||||||
|
|
||||||
|
When we want to get the value of a user-defined variable (eg. `output`), we can call `viper.GetString("output")`, which will do the following checks, until it finds a match:
|
||||||
|
|
||||||
|
* Is `--output` command line flag present?
|
||||||
|
* Is `TM_OUTPUT` environmental variable set?
|
||||||
|
* Was a config file found and does it have an `output` variable?
|
||||||
|
* Is there a default set on the command line flag?
|
||||||
|
|
||||||
|
If no variable is set and there was no default, we get back "".
|
||||||
|
|
||||||
|
This setup allows us to have powerful command line flags, but use env variables or config files (local or 12-factor style) to avoid passing these arguments every time.
|
||||||
|
|
||||||
|
## Nesting structures
|
||||||
|
|
||||||
|
Sometimes we don't just need key-value pairs, but actually a multi-level config file, like
|
||||||
|
|
||||||
|
```
|
||||||
|
[mail]
|
||||||
|
from = "no-reply@example.com"
|
||||||
|
server = "mail.example.com"
|
||||||
|
port = 567
|
||||||
|
password = "XXXXXX"
|
||||||
|
```
|
||||||
|
|
||||||
|
This CLI is too simple to warant such a structure, but I think eg. tendermint could benefit from such an approach. Here are some pointers:
|
||||||
|
|
||||||
|
* [Accessing nested keys from config files](https://github.com/spf13/viper#accessing-nested-keys)
|
||||||
|
* [Overriding nested values with envvars](https://www.netlify.com/blog/2016/09/06/creating-a-microservice-boilerplate-in-go/#nested-config-values) - the mentioned outstanding PR is already merged into master!
|
||||||
|
* Overriding nested values with cli flags? (use `--log_config.level=info` ??)
|
||||||
|
|
||||||
|
I'd love to see an example of this fully worked out in a more complex CLI.
|
||||||
|
|
||||||
|
## Have your cake and eat it too
|
||||||
|
|
||||||
|
It's easy to render data different ways. Some better for viewing, some better for importing to other programs. You can just add some global (persistent) flags to control the output formatting, and everyone gets what they want.
|
||||||
|
|
||||||
|
```
|
||||||
|
# keys list -e hex
|
||||||
|
All keys:
|
||||||
|
betty d0789984492b1674e276b590d56b7ae077f81adc
|
||||||
|
john b77f4720b220d1411a649b6c7f1151eb6b1c226a
|
||||||
|
|
||||||
|
# keys list -e btc
|
||||||
|
All keys:
|
||||||
|
betty 3uTF4r29CbtnzsNHZoPSYsE4BDwH
|
||||||
|
john 3ZGp2Md35iw4XVtRvZDUaAEkCUZP
|
||||||
|
|
||||||
|
# keys list -e b64 -o json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "betty",
|
||||||
|
"address": "0HiZhEkrFnTidrWQ1Wt64Hf4Gtw=",
|
||||||
|
"pubkey": {
|
||||||
|
"type": "secp256k1",
|
||||||
|
"data": "F83WvhT0KwttSoqQqd_0_r2ztUUaQix5EXdO8AZyREoV31Og780NW59HsqTAb2O4hZ-w-j0Z-4b2IjfdqqfhVQ=="
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "john",
|
||||||
|
"address": "t39HILIg0UEaZJtsfxFR62scImo=",
|
||||||
|
"pubkey": {
|
||||||
|
"type": "ed25519",
|
||||||
|
"data": "t1LFmbg_8UTwj-n1wkqmnTp6NfaOivokEhlYySlGYCY="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
|
@ -0,0 +1,49 @@
|
||||||
|
// Copyright © 2017 Ethan Frey
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package keys
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// deleteCmd represents the delete command
|
||||||
|
var deleteCmd = &cobra.Command{
|
||||||
|
Use: "delete [name]",
|
||||||
|
Short: "DANGER: Delete a private key from your system",
|
||||||
|
RunE: runDeleteCmd,
|
||||||
|
}
|
||||||
|
|
||||||
|
func runDeleteCmd(cmd *cobra.Command, args []string) error {
|
||||||
|
if len(args) != 1 || len(args[0]) == 0 {
|
||||||
|
return errors.New("You must provide a name for the key")
|
||||||
|
}
|
||||||
|
name := args[0]
|
||||||
|
|
||||||
|
oldpass, err := getPassword("DANGER - enter password to permanently delete key:")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = GetKeyManager().Delete(name, oldpass)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println("Password deleted forever (uh oh!)")
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
// Copyright © 2017 Ethan Frey
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package keys
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// getCmd represents the get command
|
||||||
|
var getCmd = &cobra.Command{
|
||||||
|
Use: "get [name]",
|
||||||
|
Short: "Get details of one key",
|
||||||
|
Long: `Return public details of one local key.`,
|
||||||
|
RunE: runGetCmd,
|
||||||
|
}
|
||||||
|
|
||||||
|
func runGetCmd(cmd *cobra.Command, args []string) error {
|
||||||
|
if len(args) != 1 || len(args[0]) == 0 {
|
||||||
|
return errors.New("You must provide a name for the key")
|
||||||
|
}
|
||||||
|
name := args[0]
|
||||||
|
|
||||||
|
info, err := GetKeyManager().Get(name)
|
||||||
|
if err == nil {
|
||||||
|
printInfo(info)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
// Copyright © 2017 Ethan Frey
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package keys
|
||||||
|
|
||||||
|
import "github.com/spf13/cobra"
|
||||||
|
|
||||||
|
// listCmd represents the list command
|
||||||
|
var listCmd = &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,
|
||||||
|
}
|
||||||
|
|
||||||
|
func runListCmd(cmd *cobra.Command, args []string) error {
|
||||||
|
infos, err := GetKeyManager().List()
|
||||||
|
if err == nil {
|
||||||
|
printInfos(infos)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
// Copyright © 2017 Ethan Frey
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package keys
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/tendermint/go-crypto/keys"
|
||||||
|
"github.com/tendermint/go-wire/data"
|
||||||
|
"github.com/tendermint/tmlibs/cli"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
flagType = "type"
|
||||||
|
flagNoBackup = "no-backup"
|
||||||
|
)
|
||||||
|
|
||||||
|
// newCmd represents the new command
|
||||||
|
var newCmd = &cobra.Command{
|
||||||
|
Use: "new [name]",
|
||||||
|
Short: "Create a new public/private key pair",
|
||||||
|
Long: `Add a public/private key pair to the key store.
|
||||||
|
The password muts be entered in the terminal and not
|
||||||
|
passed as a command line argument for security.`,
|
||||||
|
RunE: runNewCmd,
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
newCmd.Flags().StringP(flagType, "t", "ed25519", "Type of key (ed25519|secp256k1)")
|
||||||
|
newCmd.Flags().Bool(flagNoBackup, false, "Don't print out seed phrase (if others are watching the terminal)")
|
||||||
|
}
|
||||||
|
|
||||||
|
func runNewCmd(cmd *cobra.Command, args []string) error {
|
||||||
|
if len(args) != 1 || len(args[0]) == 0 {
|
||||||
|
return errors.New("You must provide a name for the key")
|
||||||
|
}
|
||||||
|
name := args[0]
|
||||||
|
algo := viper.GetString(flagType)
|
||||||
|
|
||||||
|
pass, err := getCheckPassword("Enter a passphrase:", "Repeat the passphrase:")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
info, seed, err := GetKeyManager().Create(name, pass, algo)
|
||||||
|
if err == nil {
|
||||||
|
printCreate(info, seed)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
type NewOutput struct {
|
||||||
|
Key keys.Info `json:"key"`
|
||||||
|
Seed string `json:"seed"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func printCreate(info keys.Info, seed string) {
|
||||||
|
switch viper.Get(cli.OutputFlag) {
|
||||||
|
case "text":
|
||||||
|
printInfo(info)
|
||||||
|
// print seed unless requested not to.
|
||||||
|
if !viper.GetBool(flagNoBackup) {
|
||||||
|
fmt.Println("**Important** write this seed phrase in a safe place.")
|
||||||
|
fmt.Println("It is the only way to recover your account if you ever forget your password.\n")
|
||||||
|
fmt.Println(seed)
|
||||||
|
}
|
||||||
|
case "json":
|
||||||
|
out := NewOutput{Key: info}
|
||||||
|
if !viper.GetBool(flagNoBackup) {
|
||||||
|
out.Seed = seed
|
||||||
|
}
|
||||||
|
json, err := data.ToJSON(out)
|
||||||
|
if err != nil {
|
||||||
|
panic(err) // really shouldn't happen...
|
||||||
|
}
|
||||||
|
fmt.Println(string(json))
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
// Copyright © 2017 Ethan Frey
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package keys
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// recoverCmd represents the recover command
|
||||||
|
var recoverCmd = &cobra.Command{
|
||||||
|
Use: "recover [name]",
|
||||||
|
Short: "Recover a private key from a seed phrase",
|
||||||
|
Long: `Recover a private key from a seed phrase.
|
||||||
|
|
||||||
|
I really hope you wrote this down when you created the new key.
|
||||||
|
The seed is only displayed on creation, never again.
|
||||||
|
|
||||||
|
You can also use this to copy a key between multiple testnets,
|
||||||
|
simply by "recovering" the key in the other nets you want to copy
|
||||||
|
to. Of course, it has no coins on the other nets, just the same address.`,
|
||||||
|
RunE: runRecoverCmd,
|
||||||
|
}
|
||||||
|
|
||||||
|
func runRecoverCmd(cmd *cobra.Command, args []string) error {
|
||||||
|
if len(args) != 1 || len(args[0]) == 0 {
|
||||||
|
return errors.New("You must provide a name for the key")
|
||||||
|
}
|
||||||
|
name := args[0]
|
||||||
|
|
||||||
|
pass, err := getPassword("Enter the new passphrase:")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// not really a password... huh?
|
||||||
|
seed, err := getSeed("Enter your recovery seed phrase:")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
info, err := GetKeyManager().Recover(name, pass, seed)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
printInfo(info)
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
// Copyright © 2017 Ethan Frey
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package keys
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
keys "github.com/tendermint/go-crypto/keys"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
manager keys.Manager
|
||||||
|
)
|
||||||
|
|
||||||
|
// RootCmd represents the base command when called without any subcommands
|
||||||
|
var RootCmd = &cobra.Command{
|
||||||
|
Use: "keys",
|
||||||
|
Short: "Key manager for tendermint clients",
|
||||||
|
Long: `Keys allows you to manage your local keystore for tendermint.
|
||||||
|
|
||||||
|
These keys may be in any format supported by go-crypto and can be
|
||||||
|
used by light-clients, full nodes, or any other application that
|
||||||
|
needs to sign with a private key.`,
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
RootCmd.AddCommand(getCmd)
|
||||||
|
RootCmd.AddCommand(listCmd)
|
||||||
|
RootCmd.AddCommand(newCmd)
|
||||||
|
RootCmd.AddCommand(updateCmd)
|
||||||
|
RootCmd.AddCommand(deleteCmd)
|
||||||
|
RootCmd.AddCommand(recoverCmd)
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
// Copyright © 2017 Ethan Frey
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package keys
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// updateCmd represents the update command
|
||||||
|
var updateCmd = &cobra.Command{
|
||||||
|
Use: "update [name]",
|
||||||
|
Short: "Change the password for a private key",
|
||||||
|
RunE: runUpdateCmd,
|
||||||
|
}
|
||||||
|
|
||||||
|
func runUpdateCmd(cmd *cobra.Command, args []string) error {
|
||||||
|
if len(args) != 1 || len(args[0]) == 0 {
|
||||||
|
return errors.New("You must provide a name for the key")
|
||||||
|
}
|
||||||
|
name := args[0]
|
||||||
|
|
||||||
|
oldpass, err := getPassword("Enter the current passphrase:")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
newpass, err := getCheckPassword("Enter the new passphrase:", "Repeat the new passphrase:")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = GetKeyManager().Update(name, oldpass, newpass)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println("Password successfully updated!")
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,131 @@
|
||||||
|
package keys
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/bgentry/speakeasy"
|
||||||
|
isatty "github.com/mattn/go-isatty"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
|
keys "github.com/tendermint/go-crypto/keys"
|
||||||
|
data "github.com/tendermint/go-wire/data"
|
||||||
|
"github.com/tendermint/tmlibs/cli"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
const MinPassLength = 10
|
||||||
|
|
||||||
|
// GetKeyManager initializes a key manager based on the configuration
|
||||||
|
func GetKeyManager() keys.Manager {
|
||||||
|
if manager == nil {
|
||||||
|
rootDir := viper.GetString(cli.HomeFlag)
|
||||||
|
manager = client.GetKeyManager(rootDir)
|
||||||
|
}
|
||||||
|
return manager
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we read from non-tty, we just need to init the buffer reader once,
|
||||||
|
// in case we try to read multiple passwords (eg. update)
|
||||||
|
var buf *bufio.Reader
|
||||||
|
|
||||||
|
func inputIsTty() bool {
|
||||||
|
return isatty.IsTerminal(os.Stdin.Fd()) || isatty.IsCygwinTerminal(os.Stdin.Fd())
|
||||||
|
}
|
||||||
|
|
||||||
|
func stdinPassword() (string, error) {
|
||||||
|
if buf == nil {
|
||||||
|
buf = bufio.NewReader(os.Stdin)
|
||||||
|
}
|
||||||
|
pass, err := buf.ReadString('\n')
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return strings.TrimSpace(pass), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPassword(prompt string) (pass string, err error) {
|
||||||
|
if inputIsTty() {
|
||||||
|
pass, err = speakeasy.Ask(prompt)
|
||||||
|
} else {
|
||||||
|
pass, err = stdinPassword()
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if len(pass) < MinPassLength {
|
||||||
|
return "", errors.Errorf("Password must be at least %d characters", MinPassLength)
|
||||||
|
}
|
||||||
|
return pass, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSeed(prompt string) (seed string, err error) {
|
||||||
|
if inputIsTty() {
|
||||||
|
fmt.Println(prompt)
|
||||||
|
}
|
||||||
|
seed, err = stdinPassword()
|
||||||
|
seed = strings.TrimSpace(seed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCheckPassword(prompt, prompt2 string) (string, error) {
|
||||||
|
// simple read on no-tty
|
||||||
|
if !inputIsTty() {
|
||||||
|
return getPassword(prompt)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: own function???
|
||||||
|
pass, err := getPassword(prompt)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
pass2, err := getPassword(prompt2)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if pass != pass2 {
|
||||||
|
return "", errors.New("Passphrases don't match")
|
||||||
|
}
|
||||||
|
return pass, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func printInfo(info keys.Info) {
|
||||||
|
switch viper.Get(cli.OutputFlag) {
|
||||||
|
case "text":
|
||||||
|
addr, err := data.ToText(info.Address)
|
||||||
|
if err != nil {
|
||||||
|
panic(err) // really shouldn't happen...
|
||||||
|
}
|
||||||
|
sep := "\t\t"
|
||||||
|
if len(info.Name) > 7 {
|
||||||
|
sep = "\t"
|
||||||
|
}
|
||||||
|
fmt.Printf("%s%s%s\n", info.Name, sep, addr)
|
||||||
|
case "json":
|
||||||
|
json, err := data.ToJSON(info)
|
||||||
|
if err != nil {
|
||||||
|
panic(err) // really shouldn't happen...
|
||||||
|
}
|
||||||
|
fmt.Println(string(json))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func printInfos(infos keys.Infos) {
|
||||||
|
switch viper.Get(cli.OutputFlag) {
|
||||||
|
case "text":
|
||||||
|
fmt.Println("All keys:")
|
||||||
|
for _, i := range infos {
|
||||||
|
printInfo(i)
|
||||||
|
}
|
||||||
|
case "json":
|
||||||
|
json, err := data.ToJSON(infos)
|
||||||
|
if err != nil {
|
||||||
|
panic(err) // really shouldn't happen...
|
||||||
|
}
|
||||||
|
fmt.Println(string(json))
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,19 +1,15 @@
|
||||||
package proxy
|
package proxy
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
certclient "github.com/tendermint/light-client/certifiers/client"
|
|
||||||
"github.com/tendermint/tendermint/rpc/client"
|
|
||||||
"github.com/tendermint/tendermint/rpc/core"
|
|
||||||
rpc "github.com/tendermint/tendermint/rpc/lib/server"
|
|
||||||
cmn "github.com/tendermint/tmlibs/common"
|
cmn "github.com/tendermint/tmlibs/common"
|
||||||
"github.com/tendermint/tmlibs/log"
|
"github.com/tendermint/tmlibs/log"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
"github.com/cosmos/cosmos-sdk/client/commands"
|
"github.com/cosmos/cosmos-sdk/client/commands"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -32,8 +28,7 @@ just with added trust and running locally.`,
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
bindFlag = "serve"
|
bindFlag = "serve"
|
||||||
wsEndpoint = "/websocket"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -50,24 +45,15 @@ func init() {
|
||||||
|
|
||||||
func runProxy(cmd *cobra.Command, args []string) error {
|
func runProxy(cmd *cobra.Command, args []string) error {
|
||||||
// First, connect a client
|
// First, connect a client
|
||||||
c := commands.GetNode()
|
node := commands.GetNode()
|
||||||
|
bind := viper.GetString(bindFlag)
|
||||||
cert, err := commands.GetCertifier()
|
cert, err := commands.GetCertifier()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
sc := certclient.Wrap(c, cert)
|
sc := client.SecureClient(node, cert)
|
||||||
sc.Start()
|
|
||||||
r := routes(sc)
|
|
||||||
|
|
||||||
// build the handler...
|
err = client.StartProxy(sc, bind, logger)
|
||||||
mux := http.NewServeMux()
|
|
||||||
rpc.RegisterRPCFuncs(mux, r, logger)
|
|
||||||
wm := rpc.NewWebsocketManager(r, c)
|
|
||||||
wm.SetLogger(logger)
|
|
||||||
core.SetLogger(logger)
|
|
||||||
mux.HandleFunc(wsEndpoint, wm.WebsocketHandler)
|
|
||||||
|
|
||||||
_, err = rpc.StartHTTPServer(viper.GetString(bindFlag), mux, logger)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -78,33 +64,3 @@ func runProxy(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// First step, proxy with no checks....
|
|
||||||
func routes(c client.Client) map[string]*rpc.RPCFunc {
|
|
||||||
|
|
||||||
return map[string]*rpc.RPCFunc{
|
|
||||||
// Subscribe/unsubscribe are reserved for websocket events.
|
|
||||||
// We can just use the core tendermint impl, which uses the
|
|
||||||
// EventSwitch we registered in NewWebsocketManager above
|
|
||||||
"subscribe": rpc.NewWSRPCFunc(core.Subscribe, "event"),
|
|
||||||
"unsubscribe": rpc.NewWSRPCFunc(core.Unsubscribe, "event"),
|
|
||||||
|
|
||||||
// info API
|
|
||||||
"status": rpc.NewRPCFunc(c.Status, ""),
|
|
||||||
"blockchain": rpc.NewRPCFunc(c.BlockchainInfo, "minHeight,maxHeight"),
|
|
||||||
"genesis": rpc.NewRPCFunc(c.Genesis, ""),
|
|
||||||
"block": rpc.NewRPCFunc(c.Block, "height"),
|
|
||||||
"commit": rpc.NewRPCFunc(c.Commit, "height"),
|
|
||||||
"tx": rpc.NewRPCFunc(c.Tx, "hash,prove"),
|
|
||||||
"validators": rpc.NewRPCFunc(c.Validators, ""),
|
|
||||||
|
|
||||||
// broadcast API
|
|
||||||
"broadcast_tx_commit": rpc.NewRPCFunc(c.BroadcastTxCommit, "tx"),
|
|
||||||
"broadcast_tx_sync": rpc.NewRPCFunc(c.BroadcastTxSync, "tx"),
|
|
||||||
"broadcast_tx_async": rpc.NewRPCFunc(c.BroadcastTxAsync, "tx"),
|
|
||||||
|
|
||||||
// abci API
|
|
||||||
"abci_query": rpc.NewRPCFunc(c.ABCIQuery, "path,data,prove"),
|
|
||||||
"abci_info": rpc.NewRPCFunc(c.ABCIInfo, ""),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -10,12 +10,10 @@ import (
|
||||||
|
|
||||||
wire "github.com/tendermint/go-wire"
|
wire "github.com/tendermint/go-wire"
|
||||||
"github.com/tendermint/go-wire/data"
|
"github.com/tendermint/go-wire/data"
|
||||||
lc "github.com/tendermint/light-client"
|
"github.com/tendermint/iavl"
|
||||||
"github.com/tendermint/light-client/certifiers"
|
|
||||||
"github.com/tendermint/light-client/proofs"
|
"github.com/tendermint/light-client/proofs"
|
||||||
"github.com/tendermint/merkleeyes/iavl"
|
|
||||||
"github.com/tendermint/tendermint/rpc/client"
|
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
"github.com/cosmos/cosmos-sdk/client/commands"
|
"github.com/cosmos/cosmos-sdk/client/commands"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -52,113 +50,20 @@ func Get(key []byte, prove bool) (data.Bytes, uint64, error) {
|
||||||
resp, err := node.ABCIQuery("/key", key, false)
|
resp, err := node.ABCIQuery("/key", key, false)
|
||||||
return data.Bytes(resp.Value), resp.Height, err
|
return data.Bytes(resp.Value), resp.Height, err
|
||||||
}
|
}
|
||||||
val, h, _, _, err := GetWithProof(key)
|
val, h, _, err := GetWithProof(key)
|
||||||
return val, h, err
|
return val, h, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWithProof returns the values stored under a given key at the named
|
// GetWithProof returns the values stored under a given key at the named
|
||||||
// height as in Get. Additionally, it will return a validated merkle
|
// height as in Get. Additionally, it will return a validated merkle
|
||||||
// proof for the key-value pair if it exists, and all checks pass.
|
// proof for the key-value pair if it exists, and all checks pass.
|
||||||
func GetWithProof(key []byte) (data.Bytes, uint64,
|
func GetWithProof(key []byte) (data.Bytes, uint64, iavl.KeyProof, error) {
|
||||||
*iavl.KeyExistsProof, *iavl.KeyNotExistsProof, error) {
|
|
||||||
|
|
||||||
node := commands.GetNode()
|
node := commands.GetNode()
|
||||||
cert, err := commands.GetCertifier()
|
cert, err := commands.GetCertifier()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, nil, nil, err
|
return nil, 0, nil, err
|
||||||
}
|
}
|
||||||
return getWithProof(key, node, cert)
|
return client.GetWithProof(key, node, cert)
|
||||||
}
|
|
||||||
|
|
||||||
func getWithProof(key []byte, node client.Client, cert certifiers.Certifier) (
|
|
||||||
val data.Bytes, height uint64, eproof *iavl.KeyExistsProof, neproof *iavl.KeyNotExistsProof, err error) {
|
|
||||||
|
|
||||||
resp, err := node.ABCIQuery("/key", key, true)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// make sure the proof is the proper height
|
|
||||||
if !resp.Code.IsOK() {
|
|
||||||
err = errors.Errorf("Query error %d: %s", resp.Code, resp.Code.String())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if len(resp.Key) == 0 || len(resp.Proof) == 0 {
|
|
||||||
err = lc.ErrNoData()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if resp.Height == 0 {
|
|
||||||
err = errors.New("Height returned is zero")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
check, err := getCertifiedCheckpoint(int(resp.Height), node, cert)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(resp.Value) > 0 {
|
|
||||||
// The key was found, construct a proof of existence.
|
|
||||||
eproof = new(iavl.KeyExistsProof)
|
|
||||||
err = wire.ReadBinaryBytes(resp.Proof, &eproof)
|
|
||||||
if err != nil {
|
|
||||||
err = errors.Wrap(err, "Error reading proof")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate the proof against the certified header to ensure data integrity.
|
|
||||||
err = eproof.Verify(resp.Key, resp.Value, check.Header.AppHash)
|
|
||||||
if err != nil {
|
|
||||||
err = errors.Wrap(err, "Couldn't verify proof")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
val = data.Bytes(resp.Value)
|
|
||||||
} else {
|
|
||||||
// The key wasn't found, construct a proof of non-existence.
|
|
||||||
neproof = new(iavl.KeyNotExistsProof)
|
|
||||||
err = wire.ReadBinaryBytes(resp.Proof, &neproof)
|
|
||||||
if err != nil {
|
|
||||||
err = errors.Wrap(err, "Error reading proof")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate the proof against the certified header to ensure data integrity.
|
|
||||||
err = neproof.Verify(resp.Key, check.Header.AppHash)
|
|
||||||
if err != nil {
|
|
||||||
err = errors.Wrap(err, "Couldn't verify proof")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = lc.ErrNoData()
|
|
||||||
}
|
|
||||||
|
|
||||||
height = resp.Height
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// getCertifiedCheckpoint gets the signed header for a given height
|
|
||||||
// and certifies it. Returns error if unable to get a proven header.
|
|
||||||
func getCertifiedCheckpoint(h int, node client.Client,
|
|
||||||
cert certifiers.Certifier) (empty lc.Checkpoint, err error) {
|
|
||||||
|
|
||||||
// FIXME: cannot use cert.GetByHeight for now, as it also requires
|
|
||||||
// Validators and will fail on querying tendermint for non-current height.
|
|
||||||
// When this is supported, we should use it instead...
|
|
||||||
client.WaitForHeight(node, h, nil)
|
|
||||||
commit, err := node.Commit(h)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
check := lc.Checkpoint{
|
|
||||||
Header: commit.Header,
|
|
||||||
Commit: commit.Commit,
|
|
||||||
}
|
|
||||||
|
|
||||||
// validate downloaded checkpoint with our request and trust store.
|
|
||||||
if check.Height() != h {
|
|
||||||
return empty, lc.ErrHeightMismatch(h, check.Height())
|
|
||||||
}
|
|
||||||
err = cert.Certify(check)
|
|
||||||
return check, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseHexKey parses the key flag as hex and converts to bytes or returns error
|
// ParseHexKey parses the key flag as hex and converts to bytes or returns error
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
wire "github.com/tendermint/go-wire"
|
wire "github.com/tendermint/go-wire"
|
||||||
"github.com/tendermint/tendermint/types"
|
"github.com/tendermint/tendermint/types"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
"github.com/cosmos/cosmos-sdk/client/commands"
|
"github.com/cosmos/cosmos-sdk/client/commands"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -51,7 +52,7 @@ func txQueryCmd(cmd *cobra.Command, args []string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
check, err := getCertifiedCheckpoint(res.Height, node, cert)
|
check, err := client.GetCertifiedCheckpoint(res.Height, node, cert)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ var validatorsCmd = &cobra.Command{
|
||||||
|
|
||||||
func runValidators(cmd *cobra.Command, args []string) error {
|
func runValidators(cmd *cobra.Command, args []string) error {
|
||||||
c := commands.GetNode()
|
c := commands.GetNode()
|
||||||
validators, err := c.Validators()
|
validators, err := c.Validators(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,9 @@ import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/tendermint/go-wire/data"
|
"github.com/tendermint/go-wire/data"
|
||||||
certclient "github.com/tendermint/light-client/certifiers/client"
|
rpcclient "github.com/tendermint/tendermint/rpc/client"
|
||||||
"github.com/tendermint/tendermint/rpc/client"
|
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
"github.com/cosmos/cosmos-sdk/client/commands"
|
"github.com/cosmos/cosmos-sdk/client/commands"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -39,15 +39,14 @@ func init() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSecureNode() (client.Client, error) {
|
func getSecureNode() (rpcclient.Client, error) {
|
||||||
// First, connect a client
|
// First, connect a client
|
||||||
c := commands.GetNode()
|
c := commands.GetNode()
|
||||||
cert, err := commands.GetCertifier()
|
cert, err := commands.GetCertifier()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sc := certclient.Wrap(c, cert)
|
return client.SecureClient(c, cert), nil
|
||||||
return sc, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// printResult just writes the struct to the console, returns an error if it can't
|
// printResult just writes the struct to the console, returns an error if it can't
|
||||||
|
|
|
@ -27,7 +27,7 @@ func runBlock(cmd *cobra.Command, args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
h := viper.GetInt(FlagHeight)
|
h := viper.GetInt(FlagHeight)
|
||||||
block, err := c.Block(h)
|
block, err := c.Block(&h)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ func runCommit(cmd *cobra.Command, args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
h := viper.GetInt(FlagHeight)
|
h := viper.GetInt(FlagHeight)
|
||||||
commit, err := c.Commit(h)
|
commit, err := c.Commit(&h)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,11 @@
|
||||||
package seeds
|
package seeds
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client/commands"
|
"github.com/cosmos/cosmos-sdk/client/commands"
|
||||||
"github.com/tendermint/light-client/certifiers"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var exportCmd = &cobra.Command{
|
var exportCmd = &cobra.Command{
|
||||||
|
@ -44,16 +40,5 @@ func exportSeed(cmd *cobra.Command, args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// now get the output file and write it
|
// now get the output file and write it
|
||||||
return writeSeed(seed, path)
|
return seed.WriteJSON(path)
|
||||||
}
|
|
||||||
|
|
||||||
func writeSeed(seed certifiers.Seed, path string) (err error) {
|
|
||||||
f, err := os.Create(path)
|
|
||||||
if err != nil {
|
|
||||||
return errors.WithStack(err)
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
stream := json.NewEncoder(f)
|
|
||||||
err = stream.Encode(seed)
|
|
||||||
return errors.WithStack(err)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ func importSeed(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
// parse the input file
|
// parse the input file
|
||||||
path := args[0]
|
path := args[0]
|
||||||
seed, err := certifiers.LoadSeed(path)
|
seed, err := certifiers.LoadSeedJSON(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ func loadSeed(p certifiers.Provider, h int, hash, file string) (seed certifiers.
|
||||||
seed, err = p.GetByHash(vhash)
|
seed, err = p.GetByHash(vhash)
|
||||||
}
|
}
|
||||||
} else if file != "" {
|
} else if file != "" {
|
||||||
seed, err = certifiers.LoadSeed(file)
|
seed, err = certifiers.LoadSeedJSON(file)
|
||||||
} else {
|
} else {
|
||||||
// default is latest seed
|
// default is latest seed
|
||||||
seed, err = certifiers.LatestSeed(p)
|
seed, err = certifiers.LatestSeed(p)
|
||||||
|
|
|
@ -10,12 +10,11 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/bgentry/speakeasy"
|
"github.com/bgentry/speakeasy"
|
||||||
"github.com/mattn/go-isatty"
|
isatty "github.com/mattn/go-isatty"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
crypto "github.com/tendermint/go-crypto"
|
crypto "github.com/tendermint/go-crypto"
|
||||||
keycmd "github.com/tendermint/go-crypto/cmd"
|
|
||||||
"github.com/tendermint/go-crypto/keys"
|
"github.com/tendermint/go-crypto/keys"
|
||||||
wire "github.com/tendermint/go-wire"
|
wire "github.com/tendermint/go-wire"
|
||||||
"github.com/tendermint/go-wire/data"
|
"github.com/tendermint/go-wire/data"
|
||||||
|
@ -24,6 +23,7 @@ import (
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk"
|
sdk "github.com/cosmos/cosmos-sdk"
|
||||||
"github.com/cosmos/cosmos-sdk/client/commands"
|
"github.com/cosmos/cosmos-sdk/client/commands"
|
||||||
|
keycmd "github.com/cosmos/cosmos-sdk/client/commands/keys"
|
||||||
"github.com/cosmos/cosmos-sdk/modules/auth"
|
"github.com/cosmos/cosmos-sdk/modules/auth"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/tendermint/light-client/certifiers"
|
||||||
|
certclient "github.com/tendermint/light-client/certifiers/client"
|
||||||
|
"github.com/tendermint/light-client/certifiers/files"
|
||||||
|
|
||||||
|
rpcclient "github.com/tendermint/tendermint/rpc/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetNode prepares a simple rpc.Client for the given endpoint
|
||||||
|
func GetNode(url string) rpcclient.Client {
|
||||||
|
return rpcclient.NewHTTP(url, "/websocket")
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetRPCProvider retuns a certifier compatible data source using
|
||||||
|
// tendermint RPC
|
||||||
|
func GetRPCProvider(url string) certifiers.Provider {
|
||||||
|
return certclient.NewHTTP(url)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetLocalProvider returns a reference to a file store of headers
|
||||||
|
// wrapped with an in-memory cache
|
||||||
|
func GetLocalProvider(dir string) certifiers.Provider {
|
||||||
|
return certifiers.NewCacheProvider(
|
||||||
|
certifiers.NewMemStoreProvider(),
|
||||||
|
files.NewProvider(dir),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCertifier initializes an inquiring certifier given a fixed chainID
|
||||||
|
// and a local source of trusted data with at least one seed
|
||||||
|
func GetCertifier(chainID string, trust certifiers.Provider,
|
||||||
|
source certifiers.Provider) (*certifiers.InquiringCertifier, error) {
|
||||||
|
|
||||||
|
// this gets the most recent verified seed
|
||||||
|
seed, err := certifiers.LatestSeed(trust)
|
||||||
|
if certifiers.IsSeedNotFoundErr(err) {
|
||||||
|
return nil, errors.New("Please run init first to establish a root of trust")
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cert := certifiers.NewInquiring(chainID, seed, trust, source)
|
||||||
|
return cert, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecureClient uses a given certifier to wrap an connection to an untrusted
|
||||||
|
// host and return a cryptographically secure rpc client.
|
||||||
|
func SecureClient(c rpcclient.Client, cert *certifiers.InquiringCertifier) rpcclient.Client {
|
||||||
|
return certclient.Wrap(c, cert)
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/tendermint/go-crypto/keys"
|
||||||
|
"github.com/tendermint/go-crypto/keys/cryptostore"
|
||||||
|
"github.com/tendermint/go-crypto/keys/storage/filestorage"
|
||||||
|
)
|
||||||
|
|
||||||
|
// KeySubdir is the directory name under root where we store the keys
|
||||||
|
const KeySubdir = "keys"
|
||||||
|
|
||||||
|
// GetKeyManager initializes a key manager based on the configuration
|
||||||
|
func GetKeyManager(rootDir string) keys.Manager {
|
||||||
|
keyDir := filepath.Join(rootDir, KeySubdir)
|
||||||
|
// TODO: smarter loading??? with language and fallback?
|
||||||
|
codec := keys.MustLoadCodec("english")
|
||||||
|
|
||||||
|
// and construct the key manager
|
||||||
|
manager := cryptostore.New(
|
||||||
|
cryptostore.SecretBox,
|
||||||
|
filestorage.New(keyDir),
|
||||||
|
codec,
|
||||||
|
)
|
||||||
|
return manager
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/tendermint/tmlibs/log"
|
||||||
|
|
||||||
|
rpcclient "github.com/tendermint/tendermint/rpc/client"
|
||||||
|
"github.com/tendermint/tendermint/rpc/core"
|
||||||
|
rpc "github.com/tendermint/tendermint/rpc/lib/server"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
wsEndpoint = "/websocket"
|
||||||
|
)
|
||||||
|
|
||||||
|
// StartProxy will start the websocket manager on the client,
|
||||||
|
// set up the rpc routes to proxy via the given client,
|
||||||
|
// and start up an http/rpc server on the location given by bind (eg. :1234)
|
||||||
|
func StartProxy(c rpcclient.Client, bind string, logger log.Logger) error {
|
||||||
|
c.Start()
|
||||||
|
r := RPCRoutes(c)
|
||||||
|
|
||||||
|
// build the handler...
|
||||||
|
mux := http.NewServeMux()
|
||||||
|
rpc.RegisterRPCFuncs(mux, r, logger)
|
||||||
|
wm := rpc.NewWebsocketManager(r, c)
|
||||||
|
wm.SetLogger(logger)
|
||||||
|
core.SetLogger(logger)
|
||||||
|
mux.HandleFunc(wsEndpoint, wm.WebsocketHandler)
|
||||||
|
|
||||||
|
_, err := rpc.StartHTTPServer(bind, mux, logger)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RPCRoutes just routes everything to the given client, as if it were
|
||||||
|
// a tendermint fullnode.
|
||||||
|
//
|
||||||
|
// if we want security, the client must implement it as a secure client
|
||||||
|
func RPCRoutes(c rpcclient.Client) map[string]*rpc.RPCFunc {
|
||||||
|
|
||||||
|
return map[string]*rpc.RPCFunc{
|
||||||
|
// Subscribe/unsubscribe are reserved for websocket events.
|
||||||
|
// We can just use the core tendermint impl, which uses the
|
||||||
|
// EventSwitch we registered in NewWebsocketManager above
|
||||||
|
"subscribe": rpc.NewWSRPCFunc(core.Subscribe, "event"),
|
||||||
|
"unsubscribe": rpc.NewWSRPCFunc(core.Unsubscribe, "event"),
|
||||||
|
|
||||||
|
// info API
|
||||||
|
"status": rpc.NewRPCFunc(c.Status, ""),
|
||||||
|
"blockchain": rpc.NewRPCFunc(c.BlockchainInfo, "minHeight,maxHeight"),
|
||||||
|
"genesis": rpc.NewRPCFunc(c.Genesis, ""),
|
||||||
|
"block": rpc.NewRPCFunc(c.Block, "height"),
|
||||||
|
"commit": rpc.NewRPCFunc(c.Commit, "height"),
|
||||||
|
"tx": rpc.NewRPCFunc(c.Tx, "hash,prove"),
|
||||||
|
"validators": rpc.NewRPCFunc(c.Validators, ""),
|
||||||
|
|
||||||
|
// broadcast API
|
||||||
|
"broadcast_tx_commit": rpc.NewRPCFunc(c.BroadcastTxCommit, "tx"),
|
||||||
|
"broadcast_tx_sync": rpc.NewRPCFunc(c.BroadcastTxSync, "tx"),
|
||||||
|
"broadcast_tx_async": rpc.NewRPCFunc(c.BroadcastTxAsync, "tx"),
|
||||||
|
|
||||||
|
// abci API
|
||||||
|
"abci_query": rpc.NewRPCFunc(c.ABCIQuery, "path,data,prove"),
|
||||||
|
"abci_info": rpc.NewRPCFunc(c.ABCIInfo, ""),
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
|
"github.com/tendermint/go-wire/data"
|
||||||
|
"github.com/tendermint/iavl"
|
||||||
|
lc "github.com/tendermint/light-client"
|
||||||
|
"github.com/tendermint/light-client/certifiers"
|
||||||
|
|
||||||
|
"github.com/tendermint/tendermint/rpc/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetWithProof will query the key on the given node, and verify it has
|
||||||
|
// a valid proof, as defined by the certifier.
|
||||||
|
//
|
||||||
|
// If there is any error in checking, returns an error.
|
||||||
|
// If val is non-empty, proof should be KeyExistsProof
|
||||||
|
// If val is empty, proof should be KeyMissingProof
|
||||||
|
func GetWithProof(key []byte, node client.Client, cert certifiers.Certifier) (
|
||||||
|
val data.Bytes, height uint64, proof iavl.KeyProof, err error) {
|
||||||
|
|
||||||
|
resp, err := node.ABCIQuery("/key", key, true)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure the proof is the proper height
|
||||||
|
if !resp.Code.IsOK() {
|
||||||
|
err = errors.Errorf("Query error %d: %s", resp.Code, resp.Code.String())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(resp.Key) == 0 || len(resp.Proof) == 0 {
|
||||||
|
err = lc.ErrNoData()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if resp.Height == 0 {
|
||||||
|
err = errors.New("Height returned is zero")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
check, err := GetCertifiedCheckpoint(int(resp.Height), node, cert)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(resp.Value) > 0 {
|
||||||
|
// The key was found, construct a proof of existence.
|
||||||
|
var eproof *iavl.KeyExistsProof
|
||||||
|
eproof, err = iavl.ReadKeyExistsProof(resp.Proof)
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "Error reading proof")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the proof against the certified header to ensure data integrity.
|
||||||
|
err = eproof.Verify(resp.Key, resp.Value, check.Header.AppHash)
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "Couldn't verify proof")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val = data.Bytes(resp.Value)
|
||||||
|
proof = eproof
|
||||||
|
} else {
|
||||||
|
// The key wasn't found, construct a proof of non-existence.
|
||||||
|
var aproof *iavl.KeyAbsentProof
|
||||||
|
aproof, err = iavl.ReadKeyAbsentProof(resp.Proof)
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "Error reading proof")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the proof against the certified header to ensure data integrity.
|
||||||
|
err = aproof.Verify(resp.Key, nil, check.Header.AppHash)
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "Couldn't verify proof")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = lc.ErrNoData()
|
||||||
|
proof = aproof
|
||||||
|
}
|
||||||
|
|
||||||
|
height = resp.Height
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCertifiedCheckpoint gets the signed header for a given height
|
||||||
|
// and certifies it. Returns error if unable to get a proven header.
|
||||||
|
func GetCertifiedCheckpoint(h int, node client.Client,
|
||||||
|
cert certifiers.Certifier) (empty lc.Checkpoint, err error) {
|
||||||
|
|
||||||
|
// FIXME: cannot use cert.GetByHeight for now, as it also requires
|
||||||
|
// Validators and will fail on querying tendermint for non-current height.
|
||||||
|
// When this is supported, we should use it instead...
|
||||||
|
client.WaitForHeight(node, h, nil)
|
||||||
|
commit, err := node.Commit(&h)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
check := lc.Checkpoint{
|
||||||
|
Header: commit.Header,
|
||||||
|
Commit: commit.Commit,
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate downloaded checkpoint with our request and trust store.
|
||||||
|
if check.Height() != h {
|
||||||
|
return empty, lc.ErrHeightMismatch(h, check.Height())
|
||||||
|
}
|
||||||
|
err = cert.Certify(check)
|
||||||
|
return check, nil
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package query
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
@ -69,32 +69,31 @@ func TestAppProofs(t *testing.T) {
|
||||||
// Test existing key.
|
// Test existing key.
|
||||||
var data eyes.Data
|
var data eyes.Data
|
||||||
|
|
||||||
bs, height, proofExists, _, err := getWithProof(k, cl, cert)
|
bs, height, proof, err := GetWithProof(k, cl, cert)
|
||||||
require.NoError(err, "%+v", err)
|
require.NoError(err, "%+v", err)
|
||||||
require.NotNil(proofExists)
|
require.NotNil(proof)
|
||||||
require.True(height >= uint64(latest.Header.Height))
|
require.True(height >= uint64(latest.Header.Height))
|
||||||
|
|
||||||
// Alexis there is a bug here, somehow the above code gives us rootHash = nil
|
// Alexis there is a bug here, somehow the above code gives us rootHash = nil
|
||||||
// and proofExists.Verify doesn't care, while proofNotExists.Verify fails.
|
// and proof.Verify doesn't care, while proofNotExists.Verify fails.
|
||||||
// I am hacking this in to make it pass, but please investigate further.
|
// I am hacking this in to make it pass, but please investigate further.
|
||||||
rootHash = proofExists.RootHash
|
rootHash = proof.Root()
|
||||||
|
|
||||||
err = wire.ReadBinaryBytes(bs, &data)
|
err = wire.ReadBinaryBytes(bs, &data)
|
||||||
require.NoError(err, "%+v", err)
|
require.NoError(err, "%+v", err)
|
||||||
assert.EqualValues(v, data.Value)
|
assert.EqualValues(v, data.Value)
|
||||||
err = proofExists.Verify(k, bs, rootHash)
|
err = proof.Verify(k, bs, rootHash)
|
||||||
assert.NoError(err, "%+v", err)
|
assert.NoError(err, "%+v", err)
|
||||||
|
|
||||||
// Test non-existing key.
|
// Test non-existing key.
|
||||||
missing := []byte("my-missing-key")
|
missing := []byte("my-missing-key")
|
||||||
bs, _, proofExists, proofNotExists, err := getWithProof(missing, cl, cert)
|
bs, _, proof, err = GetWithProof(missing, cl, cert)
|
||||||
require.True(lc.IsNoDataErr(err))
|
require.True(lc.IsNoDataErr(err))
|
||||||
require.Nil(bs)
|
require.Nil(bs)
|
||||||
require.Nil(proofExists)
|
require.NotNil(proof)
|
||||||
require.NotNil(proofNotExists)
|
err = proof.Verify(missing, nil, rootHash)
|
||||||
err = proofNotExists.Verify(missing, rootHash)
|
|
||||||
assert.NoError(err, "%+v", err)
|
assert.NoError(err, "%+v", err)
|
||||||
err = proofNotExists.Verify(k, rootHash)
|
err = proof.Verify(k, nil, rootHash)
|
||||||
assert.Error(err)
|
assert.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,12 +118,11 @@ func TestTxProofs(t *testing.T) {
|
||||||
|
|
||||||
// First let's make sure a bogus transaction hash returns a valid non-existence proof.
|
// First let's make sure a bogus transaction hash returns a valid non-existence proof.
|
||||||
key := types.Tx([]byte("bogus")).Hash()
|
key := types.Tx([]byte("bogus")).Hash()
|
||||||
bs, _, proofExists, proofNotExists, err := getWithProof(key, cl, cert)
|
bs, _, proof, err := GetWithProof(key, cl, cert)
|
||||||
assert.Nil(bs, "value should be nil")
|
assert.Nil(bs, "value should be nil")
|
||||||
require.True(lc.IsNoDataErr(err), "error should signal 'no data'")
|
require.True(lc.IsNoDataErr(err), "error should signal 'no data'")
|
||||||
assert.Nil(proofExists, "existence proof should be nil")
|
require.NotNil(proof, "proof shouldn't be nil")
|
||||||
require.NotNil(proofNotExists, "non-existence proof shouldn't be nil")
|
err = proof.Verify(key, nil, proof.Root())
|
||||||
err = proofNotExists.Verify(key, proofNotExists.RootHash)
|
|
||||||
require.NoError(err, "%+v", err)
|
require.NoError(err, "%+v", err)
|
||||||
|
|
||||||
// Now let's check with the real tx hash.
|
// Now let's check with the real tx hash.
|
|
@ -6,10 +6,11 @@ import (
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk"
|
|
||||||
keysutils "github.com/tendermint/go-crypto/cmd"
|
|
||||||
keys "github.com/tendermint/go-crypto/keys"
|
keys "github.com/tendermint/go-crypto/keys"
|
||||||
"github.com/tendermint/tmlibs/common"
|
"github.com/tendermint/tmlibs/common"
|
||||||
|
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk"
|
||||||
|
keycmd "github.com/cosmos/cosmos-sdk/client/commands/keys"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Keys struct {
|
type Keys struct {
|
||||||
|
@ -18,7 +19,7 @@ type Keys struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func DefaultKeysManager() keys.Manager {
|
func DefaultKeysManager() keys.Manager {
|
||||||
return keysutils.GetKeyManager()
|
return keycmd.GetKeyManager()
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDefaultKeysManager(algo string) *Keys {
|
func NewDefaultKeysManager(algo string) *Keys {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package rest
|
package rest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
keycmd "github.com/tendermint/go-crypto/cmd"
|
|
||||||
"github.com/tendermint/go-crypto/keys"
|
"github.com/tendermint/go-crypto/keys"
|
||||||
wire "github.com/tendermint/go-wire"
|
wire "github.com/tendermint/go-wire"
|
||||||
|
|
||||||
|
@ -9,6 +8,7 @@ import (
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk"
|
sdk "github.com/cosmos/cosmos-sdk"
|
||||||
"github.com/cosmos/cosmos-sdk/client/commands"
|
"github.com/cosmos/cosmos-sdk/client/commands"
|
||||||
|
keycmd "github.com/cosmos/cosmos-sdk/client/commands/keys"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PostTx is same as a tx
|
// PostTx is same as a tx
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
package rest
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/tendermint/tendermint/rpc/client"
|
|
||||||
"github.com/tendermint/tendermint/rpc/core"
|
|
||||||
rpc "github.com/tendermint/tendermint/rpc/lib/server"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Routes(c client.Client) map[string]*rpc.RPCFunc {
|
|
||||||
return map[string]*rpc.RPCFunc{
|
|
||||||
// subscribe/unsubscribe are reserved for websocket events.
|
|
||||||
// We can just the core Tendermint implementation, which uses
|
|
||||||
// the EventSwitch that we registered in NewWebsocketManager above.
|
|
||||||
"subscribe": rpc.NewWSRPCFunc(core.Subscribe, "event"),
|
|
||||||
"unsubscribe": rpc.NewWSRPCFunc(core.Unsubscribe, "event"),
|
|
||||||
|
|
||||||
// info API
|
|
||||||
"status": rpc.NewRPCFunc(c.Status, ""),
|
|
||||||
"blockchain": rpc.NewRPCFunc(c.BlockchainInfo, "minHeight,maxHeight"),
|
|
||||||
"genesis": rpc.NewRPCFunc(c.Genesis, ""),
|
|
||||||
"block": rpc.NewRPCFunc(c.Block, "height"),
|
|
||||||
"commit": rpc.NewRPCFunc(c.Commit, "height"),
|
|
||||||
"tx": rpc.NewRPCFunc(c.Tx, "hash.prove"),
|
|
||||||
"validators": rpc.NewRPCFunc(c.Validators, ""),
|
|
||||||
|
|
||||||
// broadcast API
|
|
||||||
"broadcast_tx_commit": rpc.NewRPCFunc(c.BroadcastTxCommit, "tx"),
|
|
||||||
"broadcast_tx_sync": rpc.NewRPCFunc(c.BroadcastTxSync, "tx"),
|
|
||||||
"broadcast_tx_async": rpc.NewRPCFunc(c.BroadcastTxAsync, "tx"),
|
|
||||||
|
|
||||||
// abci API
|
|
||||||
"abci_query": rpc.NewRPCFunc(c.ABCIQuery, "path,data,prove"),
|
|
||||||
"abci_info": rpc.NewRPCFunc(c.ABCIInfo, ""),
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -12,6 +12,7 @@ test_cli:
|
||||||
./tests/cli/keys.sh
|
./tests/cli/keys.sh
|
||||||
./tests/cli/rpc.sh
|
./tests/cli/rpc.sh
|
||||||
./tests/cli/init.sh
|
./tests/cli/init.sh
|
||||||
|
./tests/cli/init-server.sh
|
||||||
./tests/cli/basictx.sh
|
./tests/cli/basictx.sh
|
||||||
./tests/cli/roles.sh
|
./tests/cli/roles.sh
|
||||||
./tests/cli/restart.sh
|
./tests/cli/restart.sh
|
||||||
|
|
|
@ -5,11 +5,11 @@ import (
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
keycmd "github.com/tendermint/go-crypto/cmd"
|
|
||||||
"github.com/tendermint/tmlibs/cli"
|
"github.com/tendermint/tmlibs/cli"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client/commands"
|
"github.com/cosmos/cosmos-sdk/client/commands"
|
||||||
"github.com/cosmos/cosmos-sdk/client/commands/auto"
|
"github.com/cosmos/cosmos-sdk/client/commands/auto"
|
||||||
|
"github.com/cosmos/cosmos-sdk/client/commands/keys"
|
||||||
"github.com/cosmos/cosmos-sdk/client/commands/proxy"
|
"github.com/cosmos/cosmos-sdk/client/commands/proxy"
|
||||||
"github.com/cosmos/cosmos-sdk/client/commands/query"
|
"github.com/cosmos/cosmos-sdk/client/commands/query"
|
||||||
rpccmd "github.com/cosmos/cosmos-sdk/client/commands/rpc"
|
rpccmd "github.com/cosmos/cosmos-sdk/client/commands/rpc"
|
||||||
|
@ -76,7 +76,7 @@ func main() {
|
||||||
BaseCli.AddCommand(
|
BaseCli.AddCommand(
|
||||||
commands.InitCmd,
|
commands.InitCmd,
|
||||||
commands.ResetCmd,
|
commands.ResetCmd,
|
||||||
keycmd.RootCmd,
|
keys.RootCmd,
|
||||||
seeds.RootCmd,
|
seeds.RootCmd,
|
||||||
rpccmd.RootCmd,
|
rpccmd.RootCmd,
|
||||||
query.RootCmd,
|
query.RootCmd,
|
||||||
|
|
|
@ -38,6 +38,8 @@ oneTimeTearDown() {
|
||||||
}
|
}
|
||||||
|
|
||||||
# load and run these tests with shunit2!
|
# load and run these tests with shunit2!
|
||||||
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" #get this files directory
|
||||||
CLI_DIR=$GOPATH/src/github.com/cosmos/cosmos-sdk/tests/cli
|
CLI_DIR=$GOPATH/src/github.com/cosmos/cosmos-sdk/tests/cli
|
||||||
|
|
||||||
. $CLI_DIR/common.sh
|
. $CLI_DIR/common.sh
|
||||||
. $CLI_DIR/shunit2
|
. $CLI_DIR/shunit2
|
|
@ -1,29 +1,144 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
EXE=basecli
|
||||||
CLIENT_EXE=basecli
|
|
||||||
|
|
||||||
|
|
||||||
oneTimeSetUp() {
|
oneTimeSetUp() {
|
||||||
PASS=qwertyuiop
|
PASS=qwertyuiop
|
||||||
export BCHOME=$HOME/.bc_keys_test
|
export BCHOME=$HOME/.bc_keys_test
|
||||||
${CLIENT_EXE} reset_all
|
${EXE} reset_all
|
||||||
assertTrue "line ${LINENO}" $?
|
assertTrue "line ${LINENO}" $?
|
||||||
}
|
}
|
||||||
|
|
||||||
newKey(){
|
newKey(){
|
||||||
assertNotNull "keyname required" "$1"
|
assertNotNull "keyname required" "$1"
|
||||||
KEYPASS=${2:-qwertyuiop}
|
KEYPASS=${2:-qwertyuiop}
|
||||||
echo $KEYPASS | ${CLIENT_EXE} keys new $1 >/dev/null 2>&1
|
KEY=$(echo $KEYPASS | ${EXE} keys new $1 -o json)
|
||||||
assertTrue "line ${LINENO}, created $1" $?
|
if ! assertTrue "line ${LINENO}: created $1" $?; then return 1; fi
|
||||||
|
assertEquals "$1" $(echo $KEY | jq .key.name | tr -d \")
|
||||||
|
return $?
|
||||||
}
|
}
|
||||||
|
|
||||||
testMakeKeys() {
|
# updateKey <name> <oldkey> <newkey>
|
||||||
USER=demouser
|
updateKey() {
|
||||||
assertFalse "line ${LINENO}, already user $USER" "${CLIENT_EXE} keys get $USER"
|
(echo $2; echo $3) | ${EXE} keys update $1 > /dev/null
|
||||||
newKey $USER
|
return $?
|
||||||
assertTrue "line ${LINENO}, no user $USER" "${CLIENT_EXE} keys get $USER"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test00MakeKeys() {
|
||||||
|
USER=demouser
|
||||||
|
assertFalse "line ${LINENO}: already user $USER" "${EXE} keys get $USER"
|
||||||
|
newKey $USER
|
||||||
|
assertTrue "line ${LINENO}: no user $USER" "${EXE} keys get $USER"
|
||||||
|
# make sure bad password not accepted
|
||||||
|
assertFalse "accepts short password" "echo 123 | ${EXE} keys new badpass"
|
||||||
|
}
|
||||||
|
|
||||||
|
test01ListKeys() {
|
||||||
|
# one line plus the number of keys
|
||||||
|
assertEquals "2" $(${EXE} keys list | wc -l)
|
||||||
|
newKey foobar
|
||||||
|
assertEquals "3" $(${EXE} keys list | wc -l)
|
||||||
|
# we got the proper name here...
|
||||||
|
assertEquals "foobar" $(${EXE} keys list -o json | jq .[1].name | tr -d \" )
|
||||||
|
# we get all names in normal output
|
||||||
|
EXPECTEDNAMES=$(echo demouser; echo foobar)
|
||||||
|
TEXTNAMES=$(${EXE} keys list | tail -n +2 | cut -f1)
|
||||||
|
assertEquals "$EXPECTEDNAMES" "$TEXTNAMES"
|
||||||
|
# let's make sure the addresses match!
|
||||||
|
assertEquals "line ${LINENO}: text and json addresses don't match" $(${EXE} keys list | tail -1 | cut -f3) $(${EXE} keys list -o json | jq .[1].address | tr -d \")
|
||||||
|
}
|
||||||
|
|
||||||
|
test02updateKeys() {
|
||||||
|
USER=changer
|
||||||
|
PASS1=awsedrftgyhu
|
||||||
|
PASS2=S4H.9j.D9S7hso
|
||||||
|
PASS3=h8ybO7GY6d2
|
||||||
|
|
||||||
|
newKey $USER $PASS1
|
||||||
|
assertFalse "line ${LINENO}: accepts invalid pass" "updateKey $USER $PASS2 $PASS2"
|
||||||
|
assertTrue "line ${LINENO}: doesn't update" "updateKey $USER $PASS1 $PASS2"
|
||||||
|
assertTrue "line ${LINENO}: takes new key after update" "updateKey $USER $PASS2 $PASS3"
|
||||||
|
}
|
||||||
|
|
||||||
|
test03recoverKeys() {
|
||||||
|
USER=sleepy
|
||||||
|
PASS1=S4H.9j.D9S7hso
|
||||||
|
|
||||||
|
USER2=easy
|
||||||
|
PASS2=1234567890
|
||||||
|
|
||||||
|
# make a user and check they exist
|
||||||
|
KEY=$(echo $PASS1 | ${EXE} keys new $USER -o json)
|
||||||
|
if ! assertTrue "created $USER" $?; then return 1; fi
|
||||||
|
if [ -n "$DEBUG" ]; then echo $KEY; echo; fi
|
||||||
|
|
||||||
|
SEED=$(echo $KEY | jq .seed | tr -d \")
|
||||||
|
ADDR=$(echo $KEY | jq .key.address | tr -d \")
|
||||||
|
PUBKEY=$(echo $KEY | jq .key.pubkey | tr -d \")
|
||||||
|
assertTrue "line ${LINENO}" "${EXE} keys get $USER > /dev/null"
|
||||||
|
|
||||||
|
# let's delete this key
|
||||||
|
assertFalse "line ${LINENO}" "echo foo | ${EXE} keys delete $USER > /dev/null"
|
||||||
|
assertTrue "line ${LINENO}" "echo $PASS1 | ${EXE} keys delete $USER > /dev/null"
|
||||||
|
assertFalse "line ${LINENO}" "${EXE} keys get $USER > /dev/null"
|
||||||
|
|
||||||
|
# fails on short password
|
||||||
|
assertFalse "line ${LINENO}" "echo foo; echo $SEED | ${EXE} keys recover $USER2 -o json > /dev/null"
|
||||||
|
# fails on bad seed
|
||||||
|
assertFalse "line ${LINENO}" "echo $PASS2; echo \"silly white whale tower bongo\" | ${EXE} keys recover $USER2 -o json > /dev/null"
|
||||||
|
# now we got it
|
||||||
|
KEY2=$((echo $PASS2; echo $SEED) | ${EXE} keys recover $USER2 -o json)
|
||||||
|
if ! assertTrue "recovery failed: $KEY2" $?; then return 1; fi
|
||||||
|
if [ -n "$DEBUG" ]; then echo $KEY2; echo; fi
|
||||||
|
|
||||||
|
# make sure it looks the same
|
||||||
|
NAME2=$(echo $KEY2 | jq .name | tr -d \")
|
||||||
|
ADDR2=$(echo $KEY2 | jq .address | tr -d \")
|
||||||
|
PUBKEY2=$(echo $KEY2 | jq .pubkey | tr -d \")
|
||||||
|
assertEquals "line ${LINENO}: wrong username" "$USER2" "$NAME2"
|
||||||
|
assertEquals "line ${LINENO}: address doesn't match" "$ADDR" "$ADDR2"
|
||||||
|
assertEquals "line ${LINENO}: pubkey doesn't match" "$PUBKEY" "$PUBKEY2"
|
||||||
|
|
||||||
|
# and we can find the info
|
||||||
|
assertTrue "line ${LINENO}" "${EXE} keys get $USER2 > /dev/null"
|
||||||
|
}
|
||||||
|
|
||||||
|
# try recovery with secp256k1 keys
|
||||||
|
test03recoverSecp() {
|
||||||
|
USER=dings
|
||||||
|
PASS1=Sbub-U9byS7hso
|
||||||
|
|
||||||
|
USER2=booms
|
||||||
|
PASS2=1234567890
|
||||||
|
|
||||||
|
KEY=$(echo $PASS1 | ${EXE} keys new $USER -o json -t secp256k1)
|
||||||
|
if ! assertTrue "created $USER" $?; then return 1; fi
|
||||||
|
if [ -n "$DEBUG" ]; then echo $KEY; echo; fi
|
||||||
|
|
||||||
|
SEED=$(echo $KEY | jq .seed | tr -d \")
|
||||||
|
ADDR=$(echo $KEY | jq .key.address | tr -d \")
|
||||||
|
PUBKEY=$(echo $KEY | jq .key.pubkey | tr -d \")
|
||||||
|
assertTrue "line ${LINENO}" "${EXE} keys get $USER > /dev/null"
|
||||||
|
|
||||||
|
# now we got it
|
||||||
|
KEY2=$((echo $PASS2; echo $SEED) | ${EXE} keys recover $USER2 -o json)
|
||||||
|
if ! assertTrue "recovery failed: $KEY2" $?; then return 1; fi
|
||||||
|
if [ -n "$DEBUG" ]; then echo $KEY2; echo; fi
|
||||||
|
|
||||||
|
# make sure it looks the same
|
||||||
|
NAME2=$(echo $KEY2 | jq .name | tr -d \")
|
||||||
|
ADDR2=$(echo $KEY2 | jq .address | tr -d \")
|
||||||
|
PUBKEY2=$(echo $KEY2 | jq .pubkey | tr -d \")
|
||||||
|
assertEquals "line ${LINENO}: wrong username" "$USER2" "$NAME2"
|
||||||
|
assertEquals "line ${LINENO}: address doesn't match" "$ADDR" "$ADDR2"
|
||||||
|
assertEquals "line ${LINENO}: pubkey doesn't match" "$PUBKEY" "$PUBKEY2"
|
||||||
|
|
||||||
|
# and we can find the info
|
||||||
|
assertTrue "line ${LINENO}" "${EXE} keys get $USER2 > /dev/null"
|
||||||
|
}
|
||||||
|
|
||||||
|
# load and run these tests with shunit2!
|
||||||
|
|
||||||
# load and run these tests with shunit2!
|
# load and run these tests with shunit2!
|
||||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" #get this files directory
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" #get this files directory
|
||||||
CLI_DIR=$GOPATH/src/github.com/cosmos/cosmos-sdk/tests/cli
|
CLI_DIR=$GOPATH/src/github.com/cosmos/cosmos-sdk/tests/cli
|
||||||
|
|
|
@ -5,10 +5,10 @@ import (
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
keycmd "github.com/tendermint/go-crypto/cmd"
|
|
||||||
"github.com/tendermint/tmlibs/cli"
|
"github.com/tendermint/tmlibs/cli"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client/commands"
|
"github.com/cosmos/cosmos-sdk/client/commands"
|
||||||
|
"github.com/cosmos/cosmos-sdk/client/commands/keys"
|
||||||
"github.com/cosmos/cosmos-sdk/client/commands/proxy"
|
"github.com/cosmos/cosmos-sdk/client/commands/proxy"
|
||||||
"github.com/cosmos/cosmos-sdk/client/commands/query"
|
"github.com/cosmos/cosmos-sdk/client/commands/query"
|
||||||
"github.com/cosmos/cosmos-sdk/client/commands/seeds"
|
"github.com/cosmos/cosmos-sdk/client/commands/seeds"
|
||||||
|
@ -73,7 +73,7 @@ func main() {
|
||||||
commands.InitCmd,
|
commands.InitCmd,
|
||||||
commands.ResetCmd,
|
commands.ResetCmd,
|
||||||
commands.VersionCmd,
|
commands.VersionCmd,
|
||||||
keycmd.RootCmd,
|
keys.RootCmd,
|
||||||
seeds.RootCmd,
|
seeds.RootCmd,
|
||||||
query.RootCmd,
|
query.RootCmd,
|
||||||
txcmd.RootCmd,
|
txcmd.RootCmd,
|
||||||
|
|
|
@ -5,12 +5,10 @@ import (
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
keycmd "github.com/tendermint/go-crypto/cmd"
|
|
||||||
"github.com/tendermint/tmlibs/cli"
|
"github.com/tendermint/tmlibs/cli"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/client/commands"
|
"github.com/cosmos/cosmos-sdk/client/commands"
|
||||||
"github.com/cosmos/cosmos-sdk/client/commands/auto"
|
"github.com/cosmos/cosmos-sdk/client/commands/auto"
|
||||||
"github.com/cosmos/cosmos-sdk/client/commands/proxy"
|
|
||||||
"github.com/cosmos/cosmos-sdk/client/commands/query"
|
"github.com/cosmos/cosmos-sdk/client/commands/query"
|
||||||
rpccmd "github.com/cosmos/cosmos-sdk/client/commands/rpc"
|
rpccmd "github.com/cosmos/cosmos-sdk/client/commands/rpc"
|
||||||
"github.com/cosmos/cosmos-sdk/client/commands/seeds"
|
"github.com/cosmos/cosmos-sdk/client/commands/seeds"
|
||||||
|
@ -52,12 +50,10 @@ func main() {
|
||||||
// we use out own init command to not require address arg
|
// we use out own init command to not require address arg
|
||||||
commands.InitCmd,
|
commands.InitCmd,
|
||||||
commands.ResetCmd,
|
commands.ResetCmd,
|
||||||
keycmd.RootCmd,
|
|
||||||
seeds.RootCmd,
|
seeds.RootCmd,
|
||||||
rpccmd.RootCmd,
|
rpccmd.RootCmd,
|
||||||
query.RootCmd,
|
query.RootCmd,
|
||||||
txcmd.RootCmd,
|
txcmd.RootCmd,
|
||||||
proxy.RootCmd,
|
|
||||||
commands.VersionCmd,
|
commands.VersionCmd,
|
||||||
auto.AutoCompleteCmd,
|
auto.AutoCompleteCmd,
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,20 +1,22 @@
|
||||||
hash: 7ba2bf40f622c7b95538278cb615b267cf4b53dcda8d47489d250b09bc08d0b4
|
hash: ba9b44c722e57f103b8b6b861aabaeb37ad59c706160b6281817945f95dfbc1e
|
||||||
updated: 2017-08-22T13:09:54.55565241+02:00
|
updated: 2017-09-08T20:43:55.154928875+02:00
|
||||||
imports:
|
imports:
|
||||||
- name: github.com/bgentry/speakeasy
|
- name: github.com/bgentry/speakeasy
|
||||||
version: 4aabc24848ce5fd31929f7d1e4ea74d3709c14cd
|
version: 4aabc24848ce5fd31929f7d1e4ea74d3709c14cd
|
||||||
- name: github.com/btcsuite/btcd
|
- name: github.com/btcsuite/btcd
|
||||||
version: 47885ab8702485be6b6f87a03d4f3be0bc5c982c
|
version: b8df516b4b267acf2de46be593a9d948d1d2c420
|
||||||
subpackages:
|
subpackages:
|
||||||
- btcec
|
- btcec
|
||||||
|
- name: github.com/btcsuite/fastsha256
|
||||||
|
version: 637e656429416087660c84436a2a035d69d54e2e
|
||||||
- name: github.com/BurntSushi/toml
|
- name: github.com/BurntSushi/toml
|
||||||
version: a368813c5e648fee92e5f6c30e3944ff9d5e8895
|
version: b26d9c308763d68093482582cea63d69be07a0f0
|
||||||
- name: github.com/ebuchman/fail-test
|
- name: github.com/ebuchman/fail-test
|
||||||
version: 95f809107225be108efcf10a3509e4ea6ceef3c4
|
version: 95f809107225be108efcf10a3509e4ea6ceef3c4
|
||||||
- name: github.com/fsnotify/fsnotify
|
- name: github.com/fsnotify/fsnotify
|
||||||
version: 4da3e2cfbabc9f751898f250b49f2439785783a1
|
version: 4da3e2cfbabc9f751898f250b49f2439785783a1
|
||||||
- name: github.com/go-kit/kit
|
- name: github.com/go-kit/kit
|
||||||
version: 69950137349e3e6781c1a54e4f7fd3803bd36765
|
version: d67bb4c202e3b91377d1079b110a6c9ce23ab2f8
|
||||||
subpackages:
|
subpackages:
|
||||||
- log
|
- log
|
||||||
- log/level
|
- log/level
|
||||||
|
@ -28,9 +30,9 @@ imports:
|
||||||
- name: github.com/go-playground/universal-translator
|
- name: github.com/go-playground/universal-translator
|
||||||
version: 71201497bace774495daed26a3874fd339e0b538
|
version: 71201497bace774495daed26a3874fd339e0b538
|
||||||
- name: github.com/go-stack/stack
|
- name: github.com/go-stack/stack
|
||||||
version: 54be5f394ed2c3e19dac9134a40a95ba5a017f7b
|
version: 100eb0c0a9c5b306ca2fb4f165df21d80ada4b82
|
||||||
- name: github.com/golang/protobuf
|
- name: github.com/golang/protobuf
|
||||||
version: 0a4f71a498b7c4812f64969510bcb4eca251e33a
|
version: 18c9bb3261723cd5401db4d0c9fbc5c3b6c70fe8
|
||||||
subpackages:
|
subpackages:
|
||||||
- proto
|
- proto
|
||||||
- ptypes/any
|
- ptypes/any
|
||||||
|
@ -38,12 +40,10 @@ imports:
|
||||||
version: 553a641470496b2327abcac10b36396bd98e45c9
|
version: 553a641470496b2327abcac10b36396bd98e45c9
|
||||||
- name: github.com/gorilla/context
|
- name: github.com/gorilla/context
|
||||||
version: 08b5f424b9271eedf6f9f0ce86cb9396ed337a42
|
version: 08b5f424b9271eedf6f9f0ce86cb9396ed337a42
|
||||||
- name: github.com/gorilla/handlers
|
|
||||||
version: a4043c62cc2329bacda331d33fc908ab11ef0ec3
|
|
||||||
- name: github.com/gorilla/mux
|
- name: github.com/gorilla/mux
|
||||||
version: bcd8bc72b08df0f70df986b97f95590779502d31
|
version: bcd8bc72b08df0f70df986b97f95590779502d31
|
||||||
- name: github.com/gorilla/websocket
|
- name: github.com/gorilla/websocket
|
||||||
version: a69d9f6de432e2c6b296a947d8a5ee88f68522cf
|
version: a91eba7f97777409bc2c443f5534d41dd20c5720
|
||||||
- name: github.com/hashicorp/hcl
|
- name: github.com/hashicorp/hcl
|
||||||
version: 392dba7d905ed5d04a5794ba89f558b27e2ba1ca
|
version: 392dba7d905ed5d04a5794ba89f558b27e2ba1ca
|
||||||
subpackages:
|
subpackages:
|
||||||
|
@ -56,7 +56,7 @@ imports:
|
||||||
- json/scanner
|
- json/scanner
|
||||||
- json/token
|
- json/token
|
||||||
- name: github.com/howeyc/crc16
|
- name: github.com/howeyc/crc16
|
||||||
version: 96a97a1abb579c7ff1a8ffa77f2e72d1c314b57f
|
version: 58da63c846043d0bea709c8d47039df06577d6d9
|
||||||
- name: github.com/inconshreveable/mousetrap
|
- name: github.com/inconshreveable/mousetrap
|
||||||
version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
|
version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75
|
||||||
- name: github.com/jmhodges/levigo
|
- name: github.com/jmhodges/levigo
|
||||||
|
@ -64,15 +64,19 @@ imports:
|
||||||
- name: github.com/kr/logfmt
|
- name: github.com/kr/logfmt
|
||||||
version: b84e30acd515aadc4b783ad4ff83aff3299bdfe0
|
version: b84e30acd515aadc4b783ad4ff83aff3299bdfe0
|
||||||
- name: github.com/magiconair/properties
|
- name: github.com/magiconair/properties
|
||||||
version: be5ece7dd465ab0765a9682137865547526d1dfb
|
version: 51463bfca2576e06c62a8504b5c0f06d61312647
|
||||||
- name: github.com/mattn/go-isatty
|
- name: github.com/mattn/go-isatty
|
||||||
version: 57fdcb988a5c543893cc61bce354a6e24ab70022
|
version: 9622e0cc9d8f9be434ca605520ff9a16808fee47
|
||||||
- name: github.com/mitchellh/mapstructure
|
- name: github.com/mitchellh/mapstructure
|
||||||
version: d0303fe809921458f417bcf828397a65db30a7e4
|
version: cc8532a8e9a55ea36402aa21efdf403a60d34096
|
||||||
|
- name: github.com/pelletier/go-buffruneio
|
||||||
|
version: c37440a7cf42ac63b919c752ca73a85067e05992
|
||||||
- name: github.com/pelletier/go-toml
|
- name: github.com/pelletier/go-toml
|
||||||
version: 4692b8f9babfc93db58cc592ba2689d8736781de
|
version: 13d49d4606eb801b8f01ae542b4afc4c6ee3d84a
|
||||||
- name: github.com/pkg/errors
|
- name: github.com/pkg/errors
|
||||||
version: 645ef00459ed84a119197bfb8d8205042c6df63d
|
version: 645ef00459ed84a119197bfb8d8205042c6df63d
|
||||||
|
- name: github.com/rcrowley/go-metrics
|
||||||
|
version: 1f30fe9094a513ce4c700b9a54458bbb0c96996c
|
||||||
- name: github.com/spf13/afero
|
- name: github.com/spf13/afero
|
||||||
version: 9be650865eab0c12963d8753212f4f9c66cdcf12
|
version: 9be650865eab0c12963d8753212f4f9c66cdcf12
|
||||||
subpackages:
|
subpackages:
|
||||||
|
@ -80,13 +84,13 @@ imports:
|
||||||
- name: github.com/spf13/cast
|
- name: github.com/spf13/cast
|
||||||
version: acbeb36b902d72a7a4c18e8f3241075e7ab763e4
|
version: acbeb36b902d72a7a4c18e8f3241075e7ab763e4
|
||||||
- name: github.com/spf13/cobra
|
- name: github.com/spf13/cobra
|
||||||
version: 4a7b7e65864c064d48dce82efbbfed2bdc0bf2aa
|
version: 4cdb38c072b86bf795d2c81de50784d9fdd6eb77
|
||||||
- name: github.com/spf13/jwalterweatherman
|
- name: github.com/spf13/jwalterweatherman
|
||||||
version: 0efa5202c04663c757d84f90f5219c1250baf94f
|
version: 8f07c835e5cc1450c082fe3a439cf87b0cbb2d99
|
||||||
- name: github.com/spf13/pflag
|
- name: github.com/spf13/pflag
|
||||||
version: e57e3eeb33f795204c1ca35f56c44f83227c6e66
|
version: e57e3eeb33f795204c1ca35f56c44f83227c6e66
|
||||||
- name: github.com/spf13/viper
|
- name: github.com/spf13/viper
|
||||||
version: 25b30aa063fc18e48662b86996252eabdcf2f0c7
|
version: 0967fc9aceab2ce9da34061253ac10fb99bba5b2
|
||||||
- name: github.com/syndtr/goleveldb
|
- name: github.com/syndtr/goleveldb
|
||||||
version: 8c81ea47d4c41a385645e133e15510fc6a2a74b4
|
version: 8c81ea47d4c41a385645e133e15510fc6a2a74b4
|
||||||
subpackages:
|
subpackages:
|
||||||
|
@ -103,7 +107,7 @@ imports:
|
||||||
- leveldb/table
|
- leveldb/table
|
||||||
- leveldb/util
|
- leveldb/util
|
||||||
- name: github.com/tendermint/abci
|
- name: github.com/tendermint/abci
|
||||||
version: 7f5f48b6b9ec3964de4b07b6c3cd05d7c91aeee5
|
version: f1094f760b80ed35d709ed446646b716ded7a6f2
|
||||||
subpackages:
|
subpackages:
|
||||||
- client
|
- client
|
||||||
- example/dummy
|
- example/dummy
|
||||||
|
@ -115,13 +119,11 @@ imports:
|
||||||
- edwards25519
|
- edwards25519
|
||||||
- extra25519
|
- extra25519
|
||||||
- name: github.com/tendermint/go-crypto
|
- name: github.com/tendermint/go-crypto
|
||||||
version: 03d2b2446e8587f159e52070b1f1e0def971a2c7
|
version: 1bc8de4caa844f8b64c120e65b047898f22b7f3e
|
||||||
subpackages:
|
subpackages:
|
||||||
- cmd
|
- cmd
|
||||||
- keys
|
- keys
|
||||||
- keys/cryptostore
|
- keys/cryptostore
|
||||||
- keys/server
|
|
||||||
- keys/server/types
|
|
||||||
- keys/storage/filestorage
|
- keys/storage/filestorage
|
||||||
- keys/storage/memstorage
|
- keys/storage/memstorage
|
||||||
- keys/wordlist
|
- keys/wordlist
|
||||||
|
@ -130,20 +132,21 @@ imports:
|
||||||
subpackages:
|
subpackages:
|
||||||
- data
|
- data
|
||||||
- data/base58
|
- data/base58
|
||||||
|
- name: github.com/tendermint/iavl
|
||||||
|
version: a3ec7707c4eacabd33b7c510df364bfce1eb33e6
|
||||||
- name: github.com/tendermint/light-client
|
- name: github.com/tendermint/light-client
|
||||||
version: b2afece9635d11e77dd404019b9cf3885d34f4e5
|
version: ac2e4bf47b31aaf5d3d336691ac786ec751bfc32
|
||||||
subpackages:
|
subpackages:
|
||||||
- certifiers
|
- certifiers
|
||||||
- certifiers/client
|
- certifiers/client
|
||||||
- certifiers/files
|
- certifiers/files
|
||||||
- proofs
|
- proofs
|
||||||
- name: github.com/tendermint/merkleeyes
|
- name: github.com/tendermint/merkleeyes
|
||||||
version: da3842e33b138b387aec3208c3044a936a0aac41
|
version: 2f6e5d31e7a35045d8d0a5895cb1fec33dd4d32b
|
||||||
subpackages:
|
subpackages:
|
||||||
- client
|
|
||||||
- iavl
|
- iavl
|
||||||
- name: github.com/tendermint/tendermint
|
- name: github.com/tendermint/tendermint
|
||||||
version: 2d4c86dfe8f78568abd8e3847ce703d2085ed929
|
version: aa78fc14b5824725f8a14dd2c2ad727a9ab89cc3
|
||||||
subpackages:
|
subpackages:
|
||||||
- blockchain
|
- blockchain
|
||||||
- cmd/tendermint/commands
|
- cmd/tendermint/commands
|
||||||
|
@ -170,7 +173,7 @@ imports:
|
||||||
- types
|
- types
|
||||||
- version
|
- version
|
||||||
- name: github.com/tendermint/tmlibs
|
- name: github.com/tendermint/tmlibs
|
||||||
version: 956966e6587aa6b8dd3a375d35c3744291c38d60
|
version: bfec1ff1cd7fda9f5b2d8b570e3bec163e5f9149
|
||||||
subpackages:
|
subpackages:
|
||||||
- autofile
|
- autofile
|
||||||
- cli
|
- cli
|
||||||
|
@ -184,7 +187,7 @@ imports:
|
||||||
- logger
|
- logger
|
||||||
- merkle
|
- merkle
|
||||||
- name: golang.org/x/crypto
|
- name: golang.org/x/crypto
|
||||||
version: 7f7c0c2d75ebb4e32a21396ce36e87b6dadc91c9
|
version: c7af5bf2638a1164f2eb5467c39c6cffbd13a02e
|
||||||
subpackages:
|
subpackages:
|
||||||
- curve25519
|
- curve25519
|
||||||
- nacl/box
|
- nacl/box
|
||||||
|
@ -195,7 +198,7 @@ imports:
|
||||||
- ripemd160
|
- ripemd160
|
||||||
- salsa20/salsa
|
- salsa20/salsa
|
||||||
- name: golang.org/x/net
|
- name: golang.org/x/net
|
||||||
version: 02ac38e2528ff4adea90f184d71a3faa04b4b1b0
|
version: feeb485667d1fdabe727840fe00adc22431bc86e
|
||||||
subpackages:
|
subpackages:
|
||||||
- context
|
- context
|
||||||
- http2
|
- http2
|
||||||
|
@ -205,22 +208,22 @@ imports:
|
||||||
- lex/httplex
|
- lex/httplex
|
||||||
- trace
|
- trace
|
||||||
- name: golang.org/x/sys
|
- name: golang.org/x/sys
|
||||||
version: cd2c276457edda6df7fb04895d3fd6a6add42926
|
version: e62c3de784db939836898e5c19ffd41bece347da
|
||||||
subpackages:
|
subpackages:
|
||||||
- unix
|
- unix
|
||||||
- name: golang.org/x/text
|
- name: golang.org/x/text
|
||||||
version: 836efe42bb4aa16aaa17b9c155d8813d336ed720
|
version: 470f45bf29f4147d6fbd7dfd0a02a848e49f5bf4
|
||||||
subpackages:
|
subpackages:
|
||||||
- secure/bidirule
|
- secure/bidirule
|
||||||
- transform
|
- transform
|
||||||
- unicode/bidi
|
- unicode/bidi
|
||||||
- unicode/norm
|
- unicode/norm
|
||||||
- name: google.golang.org/genproto
|
- name: google.golang.org/genproto
|
||||||
version: b0a3dcfcd1a9bd48e63634bd8802960804cf8315
|
version: 411e09b969b1170a9f0c467558eb4c4c110d9c77
|
||||||
subpackages:
|
subpackages:
|
||||||
- googleapis/rpc/status
|
- googleapis/rpc/status
|
||||||
- name: google.golang.org/grpc
|
- name: google.golang.org/grpc
|
||||||
version: 71260d21715bff9c2ac999d546349d4f4b77ef1d
|
version: 844f573616520565fdc6fb4db242321b5456fd6d
|
||||||
subpackages:
|
subpackages:
|
||||||
- codes
|
- codes
|
||||||
- credentials
|
- credentials
|
||||||
|
@ -236,12 +239,12 @@ imports:
|
||||||
- tap
|
- tap
|
||||||
- transport
|
- transport
|
||||||
- name: gopkg.in/go-playground/validator.v9
|
- name: gopkg.in/go-playground/validator.v9
|
||||||
version: d529ee1b0f30352444f507cc6cdac96bfd12decc
|
version: 6d8c18553ea1ac493d049edd6f102f52e618f085
|
||||||
- name: gopkg.in/yaml.v2
|
- name: gopkg.in/yaml.v2
|
||||||
version: eb3733d160e74a9c7e442f435eb3bea458e1d19f
|
version: cd8b52f8269e0feb286dfeef29f8fe4d5b397e0b
|
||||||
testImports:
|
testImports:
|
||||||
- name: github.com/davecgh/go-spew
|
- name: github.com/davecgh/go-spew
|
||||||
version: 04cdfd42973bb9c8589fd6a731800cf222fde1a9
|
version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9
|
||||||
subpackages:
|
subpackages:
|
||||||
- spew
|
- spew
|
||||||
- name: github.com/pmezard/go-difflib
|
- name: github.com/pmezard/go-difflib
|
||||||
|
@ -249,7 +252,7 @@ testImports:
|
||||||
subpackages:
|
subpackages:
|
||||||
- difflib
|
- difflib
|
||||||
- name: github.com/stretchr/testify
|
- name: github.com/stretchr/testify
|
||||||
version: 05e8a0eda380579888eb53c394909df027f06991
|
version: 69483b4bd14f5845b5a1e55bca19e954e827f1d0
|
||||||
subpackages:
|
subpackages:
|
||||||
- assert
|
- assert
|
||||||
- require
|
- require
|
||||||
|
|
12
glide.yaml
12
glide.yaml
|
@ -15,26 +15,22 @@ import:
|
||||||
- package: github.com/tendermint/go-crypto
|
- package: github.com/tendermint/go-crypto
|
||||||
version: develop
|
version: develop
|
||||||
subpackages:
|
subpackages:
|
||||||
- cmd
|
|
||||||
- keys
|
- keys
|
||||||
- package: github.com/tendermint/go-wire
|
- package: github.com/tendermint/go-wire
|
||||||
version: develop
|
version: develop
|
||||||
subpackages:
|
subpackages:
|
||||||
- data
|
- data
|
||||||
- package: github.com/tendermint/light-client
|
- package: github.com/tendermint/light-client
|
||||||
version: unstable
|
version: develop
|
||||||
subpackages:
|
subpackages:
|
||||||
- proofs
|
- proofs
|
||||||
- certifiers
|
- certifiers
|
||||||
- certifiers/client
|
- certifiers/client
|
||||||
- certifiers/files
|
- certifiers/files
|
||||||
- package: github.com/tendermint/merkleeyes
|
- package: github.com/tendermint/iavl
|
||||||
version: origin/unstable
|
version: develop
|
||||||
subpackages:
|
|
||||||
- client
|
|
||||||
- iavl
|
|
||||||
- package: github.com/tendermint/tendermint
|
- package: github.com/tendermint/tendermint
|
||||||
version: no-internet
|
version: develop
|
||||||
subpackages:
|
subpackages:
|
||||||
- config
|
- config
|
||||||
- node
|
- node
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/stack"
|
"github.com/cosmos/cosmos-sdk/stack"
|
||||||
wire "github.com/tendermint/go-wire"
|
wire "github.com/tendermint/go-wire"
|
||||||
"github.com/tendermint/go-wire/data"
|
"github.com/tendermint/go-wire/data"
|
||||||
|
"github.com/tendermint/iavl"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: query seeds (register/update)
|
// TODO: query seeds (register/update)
|
||||||
|
@ -197,22 +198,26 @@ func packetQueryCmd(cmd *cobra.Command, args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// output queue, create a post packet
|
// output queue, create a post packet
|
||||||
bs, height, proof, _, err := query.GetWithProof(key)
|
bs, height, proof, err := query.GetWithProof(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if len(bs) == 0 {
|
||||||
|
// TODO: what info here?
|
||||||
|
return errors.New("no such packet")
|
||||||
|
}
|
||||||
|
|
||||||
err = wire.ReadBinaryBytes(bs, &packet)
|
err = wire.ReadBinaryBytes(bs, &packet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// create the post packet here.
|
// create the post packet here.
|
||||||
post := ibc.PostPacketTx{
|
post := ibc.PostPacketTx{
|
||||||
FromChainID: commands.GetChainID(),
|
FromChainID: commands.GetChainID(),
|
||||||
FromChainHeight: height,
|
FromChainHeight: height,
|
||||||
Key: key,
|
Key: key,
|
||||||
Packet: packet,
|
Packet: packet,
|
||||||
Proof: proof,
|
Proof: proof.(*iavl.KeyExistsProof),
|
||||||
}
|
}
|
||||||
|
|
||||||
// print json direct, as we don't need to wrap with the height
|
// print json direct, as we don't need to wrap with the height
|
||||||
|
|
|
@ -3,8 +3,8 @@ package ibc
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/tendermint/iavl"
|
||||||
"github.com/tendermint/light-client/certifiers"
|
"github.com/tendermint/light-client/certifiers"
|
||||||
"github.com/tendermint/merkleeyes/iavl"
|
|
||||||
"github.com/tendermint/tmlibs/log"
|
"github.com/tendermint/tmlibs/log"
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk"
|
sdk "github.com/cosmos/cosmos-sdk"
|
||||||
|
@ -59,7 +59,7 @@ func genEmptySeed(keys certifiers.ValKeys, chain string, h int,
|
||||||
func makePostPacket(tree *iavl.IAVLTree, packet Packet, fromID string, fromHeight int) PostPacketTx {
|
func makePostPacket(tree *iavl.IAVLTree, packet Packet, fromID string, fromHeight int) PostPacketTx {
|
||||||
key := []byte(fmt.Sprintf("some-long-prefix-%06d", packet.Sequence))
|
key := []byte(fmt.Sprintf("some-long-prefix-%06d", packet.Sequence))
|
||||||
tree.Set(key, packet.Bytes())
|
tree.Set(key, packet.Bytes())
|
||||||
_, proof, _, err := tree.GetWithProof(key)
|
_, proof, err := tree.GetWithProof(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ func makePostPacket(tree *iavl.IAVLTree, packet Packet, fromID string, fromHeigh
|
||||||
return PostPacketTx{
|
return PostPacketTx{
|
||||||
FromChainID: fromID,
|
FromChainID: fromID,
|
||||||
FromChainHeight: uint64(fromHeight),
|
FromChainHeight: uint64(fromHeight),
|
||||||
Proof: proof,
|
Proof: proof.(*iavl.KeyExistsProof),
|
||||||
Key: key,
|
Key: key,
|
||||||
Packet: packet,
|
Packet: packet,
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@ package ibc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/tendermint/go-wire/data"
|
"github.com/tendermint/go-wire/data"
|
||||||
|
"github.com/tendermint/iavl"
|
||||||
"github.com/tendermint/light-client/certifiers"
|
"github.com/tendermint/light-client/certifiers"
|
||||||
"github.com/tendermint/merkleeyes/iavl"
|
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk"
|
sdk "github.com/cosmos/cosmos-sdk"
|
||||||
)
|
)
|
||||||
|
@ -86,7 +86,7 @@ func (u UpdateChainTx) Wrap() sdk.Tx {
|
||||||
// If must have the special `AllowIBC` permission from the app
|
// If must have the special `AllowIBC` permission from the app
|
||||||
// that can send this packet (so only coins can request SendTx packet)
|
// that can send this packet (so only coins can request SendTx packet)
|
||||||
type CreatePacketTx struct {
|
type CreatePacketTx struct {
|
||||||
DestChain string `json:"dest_chain"`
|
DestChain string `json:"dest_chain"`
|
||||||
Permissions sdk.Actors `json:"permissions"`
|
Permissions sdk.Actors `json:"permissions"`
|
||||||
Tx sdk.Tx `json:"tx"`
|
Tx sdk.Tx `json:"tx"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ package commands
|
||||||
// // "github.com/tendermint/tmlibs/log"
|
// // "github.com/tendermint/tmlibs/log"
|
||||||
|
|
||||||
// "github.com/tendermint/go-wire"
|
// "github.com/tendermint/go-wire"
|
||||||
// "github.com/tendermint/merkleeyes/iavl"
|
// "github.com/tendermint/iavl"
|
||||||
// cmn "github.com/tendermint/tmlibs/common"
|
// cmn "github.com/tendermint/tmlibs/common"
|
||||||
|
|
||||||
// "github.com/cosmos/cosmos-sdk/plugins/ibc"
|
// "github.com/cosmos/cosmos-sdk/plugins/ibc"
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/tendermint/merkleeyes/iavl"
|
"github.com/tendermint/iavl"
|
||||||
"github.com/tendermint/tmlibs/log"
|
"github.com/tendermint/tmlibs/log"
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk"
|
sdk "github.com/cosmos/cosmos-sdk"
|
||||||
|
|
|
@ -3,7 +3,7 @@ package state
|
||||||
import (
|
import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
|
||||||
"github.com/tendermint/merkleeyes/iavl"
|
"github.com/tendermint/iavl"
|
||||||
)
|
)
|
||||||
|
|
||||||
// store nonce as it's own type so no one can even try to fake it
|
// store nonce as it's own type so no one can even try to fake it
|
||||||
|
@ -50,7 +50,7 @@ func (b *Bonsai) Remove(key []byte) (value []byte) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Bonsai) GetWithProof(key []byte) ([]byte, *iavl.KeyExistsProof, *iavl.KeyNotExistsProof, error) {
|
func (b *Bonsai) GetWithProof(key []byte) ([]byte, iavl.KeyProof, error) {
|
||||||
return b.Tree.GetWithProof(key)
|
return b.Tree.GetWithProof(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package state
|
package state
|
||||||
|
|
||||||
import "github.com/tendermint/merkleeyes/iavl"
|
import "github.com/tendermint/iavl"
|
||||||
|
|
||||||
// State represents the app states, separating the commited state (for queries)
|
// State represents the app states, separating the commited state (for queries)
|
||||||
// from the working state (for CheckTx and AppendTx)
|
// from the working state (for CheckTx and AppendTx)
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/tendermint/merkleeyes/iavl"
|
"github.com/tendermint/iavl"
|
||||||
)
|
)
|
||||||
|
|
||||||
type keyVal struct {
|
type keyVal struct {
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"github.com/tendermint/merkleeyes/iavl"
|
"github.com/tendermint/iavl"
|
||||||
dbm "github.com/tendermint/tmlibs/db"
|
dbm "github.com/tendermint/tmlibs/db"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue