Merge pull request #10 from Kava-Labs/develop

Update to kava-test-3
This commit is contained in:
Ruaridh 2018-10-05 14:47:57 -04:00 committed by GitHub
commit 2a73328a0f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 1763 additions and 288 deletions

106
Gopkg.lock generated
View File

@ -2,7 +2,6 @@
[[projects]] [[projects]]
branch = "master"
digest = "1:09a7f74eb6bb3c0f14d8926610c87f569c5cff68e978d30e9a3540aeb626fdf0" digest = "1:09a7f74eb6bb3c0f14d8926610c87f569c5cff68e978d30e9a3540aeb626fdf0"
name = "github.com/bartekn/go-bip39" name = "github.com/bartekn/go-bip39"
packages = ["."] packages = ["."]
@ -49,7 +48,8 @@
revision = "d4cc87b860166d00d6b5b9e0d3b3d71d6088d4d4" revision = "d4cc87b860166d00d6b5b9e0d3b3d71d6088d4d4"
[[projects]] [[projects]]
digest = "1:bb617355120eed649354b41a20d1745b2feb994e4da1a97591259143ad65375a" branch = "master"
digest = "1:64eb47e3881f808c83f0a3015f626d21ccc4a4eafbc530a6454e97296ededbef"
name = "github.com/cosmos/cosmos-sdk" name = "github.com/cosmos/cosmos-sdk"
packages = [ packages = [
"baseapp", "baseapp",
@ -58,6 +58,7 @@
"client/keys", "client/keys",
"client/rpc", "client/rpc",
"client/tx", "client/tx",
"client/utils",
"crypto", "crypto",
"crypto/keys", "crypto/keys",
"crypto/keys/bcrypt", "crypto/keys/bcrypt",
@ -66,28 +67,33 @@
"server", "server",
"server/config", "server/config",
"store", "store",
"tests",
"types", "types",
"version", "version",
"wire", "wire",
"x/auth", "x/auth",
"x/auth/client/cli", "x/auth/client/cli",
"x/auth/client/context",
"x/auth/client/rest",
"x/bank", "x/bank",
"x/bank/client", "x/bank/client",
"x/bank/client/cli", "x/bank/client/cli",
"x/gov", "x/bank/client/rest",
"x/ibc",
"x/mock", "x/mock",
"x/params",
"x/slashing", "x/slashing",
"x/slashing/client/cli", "x/slashing/client/cli",
"x/slashing/client/rest",
"x/stake", "x/stake",
"x/stake/client/cli", "x/stake/client/cli",
"x/stake/client/rest",
"x/stake/keeper", "x/stake/keeper",
"x/stake/tags", "x/stake/tags",
"x/stake/types", "x/stake/types",
] ]
pruneopts = "UT" pruneopts = "UT"
revision = "23e3d5ac12145c02fcb4b4767d7dfccad782aee5" revision = "4a54b3ddbde412bea07250680a09fa6cbf1c3824"
version = "v0.23.1" source = "github.com/kava-labs/cosmos-sdk"
[[projects]] [[projects]]
digest = "1:a2c1d0e43bd3baaa071d1b9ed72c27d78169b2b269f71c105ac4ba34b1be4a39" digest = "1:a2c1d0e43bd3baaa071d1b9ed72c27d78169b2b269f71c105ac4ba34b1be4a39"
@ -437,14 +443,6 @@
pruneopts = "UT" pruneopts = "UT"
revision = "c4c61651e9e37fa117f53c5a906d3b63090d8445" revision = "c4c61651e9e37fa117f53c5a906d3b63090d8445"
[[projects]]
digest = "1:8b7ca9e3745cb049a65364d3adbbab63e98d3c43c83cb101cb450c8dac3c3492"
name = "github.com/tendermint/abci"
packages = ["types"]
pruneopts = "UT"
revision = "68592f4d8ee34e97db94b7a7976b1309efdb7eb9"
version = "v0.10.0"
[[projects]] [[projects]]
branch = "master" branch = "master"
digest = "1:087aaa7920e5d0bf79586feb57ce01c35c830396ab4392798112e8aae8c47722" digest = "1:087aaa7920e5d0bf79586feb57ce01c35c830396ab4392798112e8aae8c47722"
@ -458,23 +456,12 @@
revision = "d8387025d2b9d158cf4efb07e7ebf814bcce2057" revision = "d8387025d2b9d158cf4efb07e7ebf814bcce2057"
[[projects]] [[projects]]
digest = "1:e9113641c839c21d8eaeb2c907c7276af1eddeed988df8322168c56b7e06e0e1" digest = "1:e0a2a4be1e20c305badc2b0a7a9ab7fef6da500763bec23ab81df3b5f9eec9ee"
name = "github.com/tendermint/go-amino" name = "github.com/tendermint/go-amino"
packages = ["."] packages = ["."]
pruneopts = "UT" pruneopts = "UT"
revision = "2106ca61d91029c931fd54968c2bb02dc96b1412" revision = "a8328986c1608950fa5d3d1c0472cccc4f8fc02c"
version = "0.10.1" version = "v0.12.0-rc0"
[[projects]]
digest = "1:82f70bfe58f1a55601d469b928aec5b10b1d85710e6adde40dfea8d9adba939d"
name = "github.com/tendermint/go-crypto"
packages = [
".",
"tmhash",
]
pruneopts = "UT"
revision = "6a6b591a3d7592a04b46af95451cb5be3b114f76"
version = "v0.9.0"
[[projects]] [[projects]]
digest = "1:d4a15d404afbf591e8be16fcda7f5ac87948d5c7531f9d909fd84cc730ab16e2" digest = "1:d4a15d404afbf591e8be16fcda7f5ac87948d5c7531f9d909fd84cc730ab16e2"
@ -485,7 +472,7 @@
version = "v0.9.2" version = "v0.9.2"
[[projects]] [[projects]]
digest = "1:eb0f8bee357e6c28c9ad5fa074545b5085d0dcf580ba0e7024ab8c3285a5c815" digest = "1:4f15e95fe3888cc75dd34f407d6394cbc7fd3ff24920851b92b295f6a8b556e6"
name = "github.com/tendermint/tendermint" name = "github.com/tendermint/tendermint"
packages = [ packages = [
"abci/client", "abci/client",
@ -548,35 +535,26 @@
"version", "version",
] ]
pruneopts = "UT" pruneopts = "UT"
revision = "d542d2c3945116697f60451e6a407082c41c3cc9" revision = "81df19e68ab1519399fccf0cab81cb75bf9d782e"
version = "v0.22.8" version = "v0.23.1-rc0"
[[projects]] [[projects]]
digest = "1:68921ddf468c0db04496dc49cc67948f1727a74520b1f1f06100bce5c65fa08b" digest = "1:4dcb0dd65feecb068ce23a234d1a07c7868a1e39f52a6defcae0bb371d03abf6"
name = "github.com/tendermint/tmlibs"
packages = [
"common",
"db",
"log",
]
pruneopts = "UT"
revision = "692f1d86a6e2c0efa698fd1e4541b68c74ffaf38"
version = "v0.8.4"
[[projects]]
digest = "1:5bd938386bd1f61a581bf8cd6ff2b7b2f79c542929176db4ceb44965440dae07"
name = "github.com/zondax/ledger-goclient" name = "github.com/zondax/ledger-goclient"
packages = ["."] packages = ["."]
pruneopts = "UT" pruneopts = "UT"
revision = "39ba4728c137c75718a21f9b4b3280fa31b9139b" revision = "4296ee5701e945f9b3a7dbe51f402e0b9be57259"
[[projects]] [[projects]]
branch = "master" branch = "master"
digest = "1:65a21a9e051d54eb6a3f70c659a765f706a998d9287c302269f4ed8054b2a852" digest = "1:7a71fffde456d746c52f9cd09c50b034533a3180fb1f6320abb149f2ccc579e5"
name = "golang.org/x/crypto" name = "golang.org/x/crypto"
packages = [ packages = [
"blowfish", "blowfish",
"chacha20poly1305",
"curve25519", "curve25519",
"hkdf",
"internal/chacha20",
"internal/subtle", "internal/subtle",
"nacl/box", "nacl/box",
"nacl/secretbox", "nacl/secretbox",
@ -608,9 +586,12 @@
[[projects]] [[projects]]
branch = "master" branch = "master"
digest = "1:0316a8ad208917f1d141b077e278980fd5e4594f3a85f835dacbf24d85798252" digest = "1:4bd75b1a219bc590b05c976bbebf47f4e993314ebb5c7cbf2efe05a09a184d54"
name = "golang.org/x/sys" name = "golang.org/x/sys"
packages = ["unix"] packages = [
"cpu",
"unix",
]
pruneopts = "UT" pruneopts = "UT"
revision = "4e1fef5609515ec7a2cee7b5de30ba6d9b438cbf" revision = "4e1fef5609515ec7a2cee7b5de30ba6d9b438cbf"
@ -693,40 +674,57 @@
input-imports = [ input-imports = [
"github.com/cosmos/cosmos-sdk/baseapp", "github.com/cosmos/cosmos-sdk/baseapp",
"github.com/cosmos/cosmos-sdk/client", "github.com/cosmos/cosmos-sdk/client",
"github.com/cosmos/cosmos-sdk/client/context",
"github.com/cosmos/cosmos-sdk/client/keys", "github.com/cosmos/cosmos-sdk/client/keys",
"github.com/cosmos/cosmos-sdk/client/rpc", "github.com/cosmos/cosmos-sdk/client/rpc",
"github.com/cosmos/cosmos-sdk/client/tx", "github.com/cosmos/cosmos-sdk/client/tx",
"github.com/cosmos/cosmos-sdk/client/utils",
"github.com/cosmos/cosmos-sdk/crypto/keys",
"github.com/cosmos/cosmos-sdk/server", "github.com/cosmos/cosmos-sdk/server",
"github.com/cosmos/cosmos-sdk/server/config", "github.com/cosmos/cosmos-sdk/server/config",
"github.com/cosmos/cosmos-sdk/tests",
"github.com/cosmos/cosmos-sdk/types", "github.com/cosmos/cosmos-sdk/types",
"github.com/cosmos/cosmos-sdk/version", "github.com/cosmos/cosmos-sdk/version",
"github.com/cosmos/cosmos-sdk/wire", "github.com/cosmos/cosmos-sdk/wire",
"github.com/cosmos/cosmos-sdk/x/auth", "github.com/cosmos/cosmos-sdk/x/auth",
"github.com/cosmos/cosmos-sdk/x/auth/client/cli", "github.com/cosmos/cosmos-sdk/x/auth/client/cli",
"github.com/cosmos/cosmos-sdk/x/auth/client/context",
"github.com/cosmos/cosmos-sdk/x/auth/client/rest",
"github.com/cosmos/cosmos-sdk/x/bank", "github.com/cosmos/cosmos-sdk/x/bank",
"github.com/cosmos/cosmos-sdk/x/bank/client/cli", "github.com/cosmos/cosmos-sdk/x/bank/client/cli",
"github.com/cosmos/cosmos-sdk/x/gov", "github.com/cosmos/cosmos-sdk/x/bank/client/rest",
"github.com/cosmos/cosmos-sdk/x/ibc", "github.com/cosmos/cosmos-sdk/x/mock",
"github.com/cosmos/cosmos-sdk/x/params",
"github.com/cosmos/cosmos-sdk/x/slashing", "github.com/cosmos/cosmos-sdk/x/slashing",
"github.com/cosmos/cosmos-sdk/x/slashing/client/cli", "github.com/cosmos/cosmos-sdk/x/slashing/client/cli",
"github.com/cosmos/cosmos-sdk/x/slashing/client/rest",
"github.com/cosmos/cosmos-sdk/x/stake", "github.com/cosmos/cosmos-sdk/x/stake",
"github.com/cosmos/cosmos-sdk/x/stake/client/cli", "github.com/cosmos/cosmos-sdk/x/stake/client/cli",
"github.com/cosmos/cosmos-sdk/x/stake/client/rest",
"github.com/gorilla/mux",
"github.com/pkg/errors",
"github.com/spf13/cobra", "github.com/spf13/cobra",
"github.com/spf13/pflag", "github.com/spf13/pflag",
"github.com/spf13/viper", "github.com/spf13/viper",
"github.com/stretchr/testify/assert", "github.com/stretchr/testify/assert",
"github.com/stretchr/testify/require", "github.com/stretchr/testify/require",
"github.com/tendermint/abci/types", "github.com/tendermint/go-amino",
"github.com/tendermint/go-crypto",
"github.com/tendermint/tendermint/abci/types", "github.com/tendermint/tendermint/abci/types",
"github.com/tendermint/tendermint/config",
"github.com/tendermint/tendermint/crypto", "github.com/tendermint/tendermint/crypto",
"github.com/tendermint/tendermint/crypto/ed25519",
"github.com/tendermint/tendermint/libs/bech32",
"github.com/tendermint/tendermint/libs/cli", "github.com/tendermint/tendermint/libs/cli",
"github.com/tendermint/tendermint/libs/common", "github.com/tendermint/tendermint/libs/common",
"github.com/tendermint/tendermint/libs/db", "github.com/tendermint/tendermint/libs/db",
"github.com/tendermint/tendermint/libs/log", "github.com/tendermint/tendermint/libs/log",
"github.com/tendermint/tendermint/node",
"github.com/tendermint/tendermint/p2p",
"github.com/tendermint/tendermint/privval",
"github.com/tendermint/tendermint/proxy",
"github.com/tendermint/tendermint/rpc/core/types",
"github.com/tendermint/tendermint/rpc/lib/server",
"github.com/tendermint/tendermint/types", "github.com/tendermint/tendermint/types",
"github.com/tendermint/tmlibs/db",
"github.com/tendermint/tmlibs/log",
] ]
solver-name = "gps-cdcl" solver-name = "gps-cdcl"
solver-version = 1 solver-version = 1

View File

@ -1,6 +1,7 @@
[[constraint]] [[constraint]]
name = "github.com/cosmos/cosmos-sdk" name = "github.com/cosmos/cosmos-sdk"
version="=0.23.1" branch="master"
source="github.com/kava-labs/cosmos-sdk"
# Copied from cosmos-sdk, constraints switched to overrides # Copied from cosmos-sdk, constraints switched to overrides
@ -35,7 +36,7 @@
[[override]] [[override]]
name = "github.com/tendermint/go-amino" name = "github.com/tendermint/go-amino"
version = "=0.10.1" version = "=v0.12.0-rc0"
[[override]] [[override]]
name = "github.com/tendermint/iavl" name = "github.com/tendermint/iavl"
@ -43,16 +44,17 @@
[[override]] [[override]]
name = "github.com/tendermint/tendermint" name = "github.com/tendermint/tendermint"
version = "=v0.22.8" version = "=v0.23.1-rc0"
[[override]] [[override]]
name = "github.com/bartekn/go-bip39" name = "github.com/bartekn/go-bip39"
branch = "master" revision = "a05967ea095d81c8fe4833776774cfaff8e5036c"
[[override]] [[override]]
name = "github.com/zondax/ledger-goclient" name = "github.com/zondax/ledger-goclient"
revision = "39ba4728c137c75718a21f9b4b3280fa31b9139b" revision = "4296ee5701e945f9b3a7dbe51f402e0b9be57259"
[prune] [prune]
go-tests = true go-tests = true
unused-packages = true unused-packages = true

View File

@ -9,7 +9,7 @@ Providing a base layer currency to settle interoperable payments at high through
Proudly building on the work of [Cosmos](https://github.com/cosmos/cosmos-sdk) and [Interledger](https://github.com/interledger/rfcs). Proudly building on the work of [Cosmos](https://github.com/cosmos/cosmos-sdk) and [Interledger](https://github.com/interledger/rfcs).
# Project Status # Project Status
[![Testnet](https://img.shields.io/badge/testnet-live-brightgreen.svg)](http://validator.connector.kava.io:26657/abci_info) [![Testnet](https://img.shields.io/badge/testnet-live-brightgreen.svg)](http://kava-test-3.node.connector.kava.io:17127/abci_info)
[![Go Report Card](https://goreportcard.com/badge/github.com/kava-labs/kava)](https://goreportcard.com/report/github.com/kava-labs/kava) [![Go Report Card](https://goreportcard.com/badge/github.com/kava-labs/kava)](https://goreportcard.com/report/github.com/kava-labs/kava)
[![GitHub](https://img.shields.io/github/license/kava-labs/kava.svg)](https://github.com/Kava-Labs/kava/blob/master/LICENSE.md) [![GitHub](https://img.shields.io/github/license/kava-labs/kava.svg)](https://github.com/Kava-Labs/kava/blob/master/LICENSE.md)
@ -27,5 +27,7 @@ If you're interested in being a validator join the chat and checkout the setup i
# Find Out More # Find Out More
- [Installation and Setup](docs/setup.md) - [Installation and Setup](docs/setup.md)
- [Upgrading to a New Testnet](docs/upgrade.md)
- [Basic Usage](docs/usage.md) - [Basic Usage](docs/usage.md)
- [Payment Channels](docs/paychans.md) - [Payment Channels](docs/paychans.md)

View File

@ -16,14 +16,13 @@ import (
"github.com/cosmos/cosmos-sdk/version" "github.com/cosmos/cosmos-sdk/version"
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
bankcmd "github.com/cosmos/cosmos-sdk/x/bank/client/cli" bankcmd "github.com/cosmos/cosmos-sdk/x/bank/client/cli"
//govcmd "github.com/cosmos/cosmos-sdk/x/gov/client/cli"
//ibccmd "github.com/cosmos/cosmos-sdk/x/ibc/client/cli"
slashingcmd "github.com/cosmos/cosmos-sdk/x/slashing/client/cli" slashingcmd "github.com/cosmos/cosmos-sdk/x/slashing/client/cli"
stakecmd "github.com/cosmos/cosmos-sdk/x/stake/client/cli" stakecmd "github.com/cosmos/cosmos-sdk/x/stake/client/cli"
paychancmd "github.com/kava-labs/kava/internal/x/paychan/client/cmd" paychancmd "github.com/kava-labs/kava/internal/x/paychan/client/cli"
"github.com/kava-labs/kava/internal/app" "github.com/kava-labs/kava/internal/app"
//"github.com/kava-labs/kava/internal/lcd" "github.com/kava-labs/kava/internal/lcd"
) )
var ( var (
@ -53,17 +52,6 @@ func main() {
) )
tx.AddCommands(tendermintCmd, cdc) tx.AddCommands(tendermintCmd, cdc)
// Add IBC commands
// ibcCmd := &cobra.Command{
// Use: "ibc",
// Short: "Inter-Blockchain Communication subcommands",
// }
// ibcCmd.AddCommand(
// client.PostCommands(
// ibccmd.IBCTransferCmd(cdc),
// ibccmd.IBCRelayCmd(cdc),
// )...)
advancedCmd := &cobra.Command{ advancedCmd := &cobra.Command{
Use: "advanced", Use: "advanced",
Short: "Advanced subcommands", Short: "Advanced subcommands",
@ -71,8 +59,7 @@ func main() {
advancedCmd.AddCommand( advancedCmd.AddCommand(
tendermintCmd, tendermintCmd,
//ibcCmd, lcd.ServeCommand(cdc),
//lcd.ServeCommand(cdc),
) )
rootCmd.AddCommand( rootCmd.AddCommand(
advancedCmd, advancedCmd,
@ -90,6 +77,10 @@ func main() {
stakecmd.GetCmdQueryValidators("stake", cdc), stakecmd.GetCmdQueryValidators("stake", cdc),
stakecmd.GetCmdQueryDelegation("stake", cdc), stakecmd.GetCmdQueryDelegation("stake", cdc),
stakecmd.GetCmdQueryDelegations("stake", cdc), stakecmd.GetCmdQueryDelegations("stake", cdc),
stakecmd.GetCmdQueryUnbondingDelegation("stake", cdc),
stakecmd.GetCmdQueryUnbondingDelegations("stake", cdc),
stakecmd.GetCmdQueryRedelegation("stake", cdc),
stakecmd.GetCmdQueryRedelegations("stake", cdc),
slashingcmd.GetCmdQuerySigningInfo("slashing", cdc), slashingcmd.GetCmdQuerySigningInfo("slashing", cdc),
)...) )...)
stakeCmd.AddCommand( stakeCmd.AddCommand(
@ -105,27 +96,6 @@ func main() {
stakeCmd, stakeCmd,
) )
// Add gov commands
// govCmd := &cobra.Command{
// Use: "gov",
// Short: "Governance and voting subcommands",
// }
// govCmd.AddCommand(
// client.GetCommands(
// govcmd.GetCmdQueryProposal("gov", cdc),
// govcmd.GetCmdQueryVote("gov", cdc),
// govcmd.GetCmdQueryVotes("gov", cdc),
// )...)
// govCmd.AddCommand(
// client.PostCommands(
// govcmd.GetCmdSubmitProposal(cdc),
// govcmd.GetCmdDeposit(cdc),
// govcmd.GetCmdVote(cdc),
// )...)
// rootCmd.AddCommand(
// govCmd,
// )
// Add auth and bank commands // Add auth and bank commands
rootCmd.AddCommand( rootCmd.AddCommand(
client.GetCommands( client.GetCommands(

View File

@ -5,7 +5,12 @@ package main
import ( import (
"encoding/json" "encoding/json"
"fmt"
"io" "io"
"io/ioutil"
"os"
"path/filepath"
"regexp"
"github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/baseapp"
@ -44,6 +49,9 @@ func main() {
server.AddCommands(ctx, cdc, rootCmd, appInit, appCreator, appExporter) server.AddCommands(ctx, cdc, rootCmd, appInit, appCreator, appExporter)
// Add custom init command
rootCmd.AddCommand(initTestnetCmd())
// handle envs and add some flags and stuff // handle envs and add some flags and stuff
executor := cli.PrepareBaseCmd(rootCmd, "KV", app.DefaultNodeHome) executor := cli.PrepareBaseCmd(rootCmd, "KV", app.DefaultNodeHome)
@ -62,3 +70,130 @@ func exportAppStateAndTMValidators(logger log.Logger, db dbm.DB, traceStore io.W
tempApp := app.NewKavaApp(logger, db, traceStore) tempApp := app.NewKavaApp(logger, db, traceStore)
return tempApp.ExportAppStateAndValidators() return tempApp.ExportAppStateAndValidators()
} }
func initTestnetCmd() *cobra.Command {
flagChainID := server.FlagChainID
flagName := server.FlagName
cmd := &cobra.Command{
Use: "init-testnet",
Short: "Setup genesis and config to join testnet.",
Long: "Copy the genesis.json and config.toml files from the testnets folder into the default config directories. Also set the validator moniker.",
RunE: func(cmd *cobra.Command, args []string) error {
// This only works with default config locations
testnetVersion := viper.GetString(flagChainID)
genesisFileName := "genesis.json"
configFileName := "config.toml"
configPath := "config"
testnetsPath := os.ExpandEnv("$GOPATH/src/github.com/kava-labs/kava/testnets/")
// Copy genesis file from testnet folder to config directories
// Copied to .kvcli to enable automatic reading of chain-id
genesis := filepath.Join(testnetsPath, testnetVersion, genesisFileName)
err := copyFile(genesis, filepath.Join(app.DefaultNodeHome, configPath, genesisFileName))
if err != nil {
return err
}
err = copyFile(genesis, filepath.Join(app.DefaultCLIHome, configPath, genesisFileName))
if err != nil {
return err
}
// Copy config file from testnet folder to config directories
// Custom config file specifies seeds and altered ports
// Also add back validator moniker to config file
config := filepath.Join(testnetsPath, testnetVersion, configFileName)
monikerPattern, err := regexp.Compile("moniker = \"[^\n]*\"") // anything that's not a new line
if err != nil {
return err
}
monikerReplaceString := fmt.Sprintf("moniker = \"%v\"", viper.GetString(flagName))
err = copyFile(config, filepath.Join(app.DefaultNodeHome, configPath, configFileName))
if err != nil {
return err
}
err = replaceStringInFile(
filepath.Join(app.DefaultNodeHome, configPath, configFileName),
monikerPattern,
monikerReplaceString)
if err != nil {
return err
}
err = copyFile(config, filepath.Join(app.DefaultCLIHome, configPath, configFileName))
if err != nil {
return err
}
err = replaceStringInFile(
filepath.Join(app.DefaultCLIHome, configPath, configFileName),
monikerPattern,
monikerReplaceString)
if err != nil {
return err
}
return nil
},
}
cmd.Flags().String(flagChainID, "", "testnet chain-id, required")
cmd.Flags().String(flagName, "", "validator moniker, required")
return cmd
}
func copyFile(src string, dst string) error {
// read in source file
in, err := os.Open(src)
if err != nil {
return err
}
defer in.Close()
// create destination file (and any necessary directories)(overwriting if it exists already)
path := filepath.Dir(dst)
err = os.MkdirAll(path, os.ModePerm)
if err != nil {
return err
}
out, err := os.Create(dst)
if err != nil {
return err
}
defer func() {
cerr := out.Close()
if err == nil {
err = cerr
}
}()
// copy file contents
if _, err = io.Copy(out, in); err != nil {
return err
}
// write to disk
err = out.Sync()
return err
}
// replaceStringInFile finds strings matching a regexp in a file and replaces them with a new string, before saving file.
func replaceStringInFile(filePath string, re *regexp.Regexp, replace string) error {
// get permissions of file
fileInfo, err := os.Stat(filePath)
if err != nil {
return err
}
// read in file contents
in, err := ioutil.ReadFile(filePath)
if err != nil {
return err
}
// replace string
newContents := re.ReplaceAll(in, []byte(replace))
// write file
err = ioutil.WriteFile(filePath, newContents, fileInfo.Mode())
if err != nil {
return err
}
return nil
}

View File

@ -4,7 +4,7 @@ services:
image: kava/kava image: kava/kava
command: ["kvd", "start"] command: ["kvd", "start"]
ports: ports:
- 26657:26657 - 17127:17127
volumes: volumes:
- ~/.kvd:/root/.kvd - ~/.kvd:/root/.kvd
- ~/.kvcli:/root/.kvcli - ~/.kvcli:/root/.kvcli

View File

@ -10,12 +10,12 @@ This initial implementation is for unidirectional channels. Channels can be open
## Create a channel ## Create a channel
kvcli paychan create --from <your account name> --to <receivers address> --amount 100KVA --chain-id <your chain ID> kvcli paychan create --from <your account name> --to <receivers address> --amount 100KVA
## Send an off-chain payment ## Send an off-chain payment
Send a payment for 10 KVA. Send a payment for 10 KVA.
kvcli paychan pay --from <your account name> --sen-amt 90KVA --rec-amt 10KVA --chan-id <ID of channel> --filename payment.json --chain-id <your chain ID> kvcli paychan pay --from <your account name> --sen-amt 90KVA --rec-amt 10KVA --chan-id <ID of channel> --filename payment.json
Send the file `payment.json` to your receiver. Then they run the following to verify. Send the file `payment.json` to your receiver. Then they run the following to verify.
@ -24,11 +24,11 @@ Send the file `payment.json` to your receiver. Then they run the following to ve
## Close a channel ## Close a channel
The receiver can close immediately at any time. The receiver can close immediately at any time.
kvcli paychan submit --from <receiver's account name> --payment payment.json --chain-id <your chain ID> kvcli paychan submit --from <receiver's account name> --payment payment.json
The sender can submit a close request, causing the channel will close automatically after a dispute period. During this period a receiver can still close immediately, overruling the sender's request. The sender can submit a close request, causing the channel will close automatically after a dispute period. During this period a receiver can still close immediately, overruling the sender's request.
kvcli paychan submit --from <receiver's account name> --payment payment.json --chain-id <your chain ID> kvcli paychan submit --from <receiver's account name> --payment payment.json
>Note: The dispute period on the testnet is 30 seconds for ease of testing. >Note: The dispute period on the testnet is 30 seconds for ease of testing.

View File

@ -4,7 +4,7 @@
#### Who this guide is for #### Who this guide is for
The code currently consists of a full node daemon (`kvd`) and it's command line interface (`kvcli`). The code currently consists of a full node daemon (`kvd`) and it's command line interface (`kvcli`).
Full nodes are fairly resource intensive and are designed to be run continuously on servers, primarily by people validating the network. While it is possible to run locally it is not recommended unless for development purposes. In the future light clients will enable secure transactions for clients. Full nodes are fairly resource intensive and are designed to be run continuously on servers, primarily by people validating the network. While it is possible to run locally it is not recommended except for development purposes. In the future light clients will enable secure transactions for clients.
A **full node** syncs with the blockchain and processes transactions. A **validator** is a full node that has declared itself to be a "validator" on chain. This obligates it to participate in consensus by proposing and signing blocks and maintaining uptime. By not following the protocol, the validator's stake will be slashed. A **full node** syncs with the blockchain and processes transactions. A **validator** is a full node that has declared itself to be a "validator" on chain. This obligates it to participate in consensus by proposing and signing blocks and maintaining uptime. By not following the protocol, the validator's stake will be slashed.
@ -14,22 +14,22 @@ Use these instructions to set up a full node, and to optionally declare yourself
Requirements: go installed and set up (version 1.10+). Requirements: go installed and set up (version 1.10+).
0. If installing from a new Ubuntu server (16.04 or 18.04), here's how to setup go: >If installing from a new Ubuntu server (16.04 or 18.04), here's how to setup go.
>
sudo apt update > sudo apt update
sudo apt upgrade -y > sudo apt upgrade -y
sudo apt install git gcc make wget -y > sudo apt install git gcc make wget -y
wget https://dl.google.com/go/go1.10.3.linux-amd64.tar.gz > wget https://dl.google.com/go/go1.10.3.linux-amd64.tar.gz
sudo tar -xvf go1.10.3.linux-amd64.tar.gz > sudo tar -xvf go1.10.3.linux-amd64.tar.gz
sudo mv go /usr/local > sudo mv go /usr/local
>
cat >> ~/.profile <<EOF > cat >> ~/.profile <<EOF
export GOROOT=/usr/local/go > export GOROOT=/usr/local/go
export GOPATH=\$HOME/go > export GOPATH=\$HOME/go
export PATH=\$GOPATH/bin:\$GOROOT/bin:\$PATH > export PATH=\$GOPATH/bin:\$GOROOT/bin:\$PATH
EOF > EOF
>
source ~/.profile > source ~/.profile
1. Get the code. 1. Get the code.
@ -37,7 +37,6 @@ Requirements: go installed and set up (version 1.10+).
cd $GOPATH/src/github.com/kava-labs cd $GOPATH/src/github.com/kava-labs
git clone https://github.com/kava-labs/kava git clone https://github.com/kava-labs/kava
cd kava cd kava
git checkout 8c9406c
2. Install the dependencies. 2. Install the dependencies.
@ -45,58 +44,59 @@ Requirements: go installed and set up (version 1.10+).
curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
dep ensure -vendor-only dep ensure -vendor-only
3. Install the code 3. Install the code.
go install ./cmd/kvd go install ./cmd/kvd
go install ./cmd/kvcli go install ./cmd/kvcli
## Run a Full Node ## Run a Full Node
kvd init --name <your-name> --chain-id kava-test-2 kvd init --name <your-name>
This will generate config and keys in `$HOME/.kvd` and `$HOME/.kvcli`. The default password is 'password'. Enter a new password for your validator key. This will generate generic config and private keys in `$HOME/.kvd` and `$HOME/.kvcli`.
> Note: Make sure `GOBIN` is set and added to your path if you want to be able to run installed go programs from any folder. > Note: Make sure `GOBIN` is set and added to your path if you want to be able to run installed go programs from any folder.
Copy the testnet genesis file (from https://raw.githubusercontent.com/Kava-Labs/kava/master/testnets/kava-test-2/genesis.json) into `$HOME/.kvd/config/`, replacing the existing one. Setup the correct config for the current testnet
Add the kava node address, `5c2bc5a95b014e4b2897791565398ee6bfd0a04a@validator.connector.kava.io:26656`, to `seeds` in `$HOME/.kvd/config/config.toml` kvd init-testnet --name <your-name> --chain-id kava-test-3
Start your full node Start your full node
kvd start kvd start
Or, to start in the background and capture output to a log file: > Note: It might take a while to fully sync. Check the latest block height [here](http://validator.connector.kava.io:17127/abci_info).
### Running in the Background
It's often more convenient to start `kvd` in the background and capture output to a log file.
kvd start &> kvd.log & kvd start &> kvd.log &
To see the output of the log: To see the output of the log.
tail -f kvd.log tail -f kvd.log
> Note: It might take a while to fully sync. Check the latest block height [here](http://validator.connector.kava.io:26657/abci_info).
## Become a Validator ## Become a Validator
Join the [validator chat](https://riot.im/app/#/room/#kava-validators:matrix.org). Follow setup for a full node above. Join the [validator chat](https://riot.im/app/#/room/#kava-validators:matrix.org).
Get you address with `kvcli keys list`. Follow the setup for a full node above.
Ask @rhuairahrighairidh in the chat to give you some coins. Get your address with `kvcli keys list` and your validator pubkey with `kvd tendermint show_validator`.
Get your validator pubkey with `kvd tendermint show_validator` Get some testnet coins from [the faucet](http://kava-test-3.faucet.connector.kava.io).
Then, your full running in the background or separate window, run: Then, with your full node running in the background or separate window, run:
kvcli stake create-validator \ kvcli stake create-validator \
--amount 900KVA \ --amount 900KVA \
--pubkey <you validator pubkey from above> \ --pubkey <you validator pubkey from above> \
--address-validator <your address from above> \
--moniker "<your name>" \ --moniker "<your name>" \
--chain-id kava-test-2 \
--from <your name> \ --from <your name> \
--gas 1000000 --gas 1000000
> Note You'll need to type in the default password "password" > Note You'll need to type in your password you set earlier.
Now your full node should be participating in consensus and validating blocks! Now your full node should be participating in consensus and validating blocks!
@ -104,9 +104,7 @@ Running a validator requires that you keep validating blocks. If you stop, your
In order to stop validating, first remove yourself as validator, then you can stop your node. In order to stop validating, first remove yourself as validator, then you can stop your node.
kvcli stake unbond begin \ kvcli stake unbond begin \
--address-delegator <your address> \
--address-validator <your address> \ --address-validator <your address> \
--chain-id kava-test-2 \
--shares-percent 1 \ --shares-percent 1 \
--from <your name> \ --from <your name> \
--gas 1000000 --gas 1000000

27
docs/upgrade.md Normal file
View File

@ -0,0 +1,27 @@
# Validator Upgrade
These are some guidelines to upgrade to a new testnet if you where validating on a previous one.
1. Stop the current validator.
1. Remove the old config.
rm -r $HOME/.kvd
rm -r $HOME/.kvcli
1. Get the latest code.
cd $GOPATH/src/github.com/kava-labs/kava
git pull
1. Get the latest dependencies.
dep ensure -vendor-only
1. Install.
go install ./cmd/kvd
go install ./cmd/kvcli
1. Follow the installation instructions for running a full node and becoming a validator.

View File

@ -1,5 +1,6 @@
# Basic Usage # Basic Usage
>The following commands require communication with a full node. By default they expect one to be running locally (accessible on localhost), but a remote can be provided with the `--node` flag. >The following commands require communication with a full node. By default they expect one to be running locally (accessible on localhost), but a remote can be provided with the `--node` flag.
## View Your Address ## View Your Address
List locally stored account addresses and their names. The name is used in other commands to specify which address to use to sign the transaction. List locally stored account addresses and their names. The name is used in other commands to specify which address to use to sign the transaction.
@ -13,7 +14,6 @@ List locally stored account addresses and their names. The name is used in other
kvcli send --from <your key name> \ kvcli send --from <your key name> \
--to <address> \ --to <address> \
--amount 100KVA \ --amount 100KVA
--chain-id kava-test-<current testnet #>

View File

@ -19,8 +19,7 @@ import (
"github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/wire"
"github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/bank" "github.com/cosmos/cosmos-sdk/x/bank"
//"github.com/cosmos/cosmos-sdk/x/gov" "github.com/cosmos/cosmos-sdk/x/params"
//"github.com/cosmos/cosmos-sdk/x/ibc"
"github.com/cosmos/cosmos-sdk/x/slashing" "github.com/cosmos/cosmos-sdk/x/slashing"
"github.com/cosmos/cosmos-sdk/x/stake" "github.com/cosmos/cosmos-sdk/x/stake"
"github.com/kava-labs/kava/internal/x/paychan" "github.com/kava-labs/kava/internal/x/paychan"
@ -41,25 +40,23 @@ type KavaApp struct {
cdc *wire.Codec cdc *wire.Codec
// keys to access the substores // keys to access the substores
keyMain *sdk.KVStoreKey keyMain *sdk.KVStoreKey
keyAccount *sdk.KVStoreKey keyAccount *sdk.KVStoreKey
keyStake *sdk.KVStoreKey
//keyIBC *sdk.KVStoreKey keySlashing *sdk.KVStoreKey
keyStake *sdk.KVStoreKey
keySlashing *sdk.KVStoreKey
//keyGov *sdk.KVStoreKey
keyFeeCollection *sdk.KVStoreKey keyFeeCollection *sdk.KVStoreKey
keyParams *sdk.KVStoreKey
tkeyParams *sdk.TransientStoreKey
keyPaychan *sdk.KVStoreKey keyPaychan *sdk.KVStoreKey
// keepers // keepers
accountMapper auth.AccountMapper accountMapper auth.AccountMapper
feeCollectionKeeper auth.FeeCollectionKeeper feeCollectionKeeper auth.FeeCollectionKeeper
coinKeeper bank.Keeper coinKeeper bank.Keeper
stakeKeeper stake.Keeper
slashingKeeper slashing.Keeper
paramsKeeper params.Keeper
paychanKeeper paychan.Keeper paychanKeeper paychan.Keeper
//ibcMapper ibc.Mapper
stakeKeeper stake.Keeper
slashingKeeper slashing.Keeper
//govKeeper gov.Keeper
} }
// Creates a new KavaApp. // Creates a new KavaApp.
@ -69,49 +66,46 @@ func NewKavaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, baseAppOptio
cdc := CreateKavaAppCodec() cdc := CreateKavaAppCodec()
// Create a new base app // Create a new base app
bApp := bam.NewBaseApp(appName, cdc, logger, db, baseAppOptions...) bApp := bam.NewBaseApp(appName, logger, db, auth.DefaultTxDecoder(cdc), baseAppOptions...)
bApp.SetCommitMultiStoreTracer(traceStore) bApp.SetCommitMultiStoreTracer(traceStore)
// Create the kava app, extending baseApp // Create the kava app, extending baseApp
var app = &KavaApp{ var app = &KavaApp{
BaseApp: bApp, BaseApp: bApp,
cdc: cdc, cdc: cdc,
keyMain: sdk.NewKVStoreKey("main"), keyMain: sdk.NewKVStoreKey("main"),
keyAccount: sdk.NewKVStoreKey("acc"), keyAccount: sdk.NewKVStoreKey("acc"),
keyPaychan: sdk.NewKVStoreKey("paychan"), keyStake: sdk.NewKVStoreKey("stake"),
//keyIBC: sdk.NewKVStoreKey("ibc"), keySlashing: sdk.NewKVStoreKey("slashing"),
keyStake: sdk.NewKVStoreKey("stake"),
keySlashing: sdk.NewKVStoreKey("slashing"),
//keyGov: sdk.NewKVStoreKey("gov"),
keyFeeCollection: sdk.NewKVStoreKey("fee"), keyFeeCollection: sdk.NewKVStoreKey("fee"),
keyParams: sdk.NewKVStoreKey("params"),
tkeyParams: sdk.NewTransientStoreKey("transient_params"),
keyPaychan: sdk.NewKVStoreKey("paychan"),
} }
// Define the accountMapper and base account // Define the accountMapper and base account
app.accountMapper = auth.NewAccountMapper( app.accountMapper = auth.NewAccountMapper(
cdc, app.cdc,
app.keyAccount, app.keyAccount,
auth.ProtoBaseAccount, auth.ProtoBaseAccount,
) )
// Create the keepers // Create the keepers
app.coinKeeper = bank.NewKeeper(app.accountMapper) app.coinKeeper = bank.NewKeeper(app.accountMapper)
app.paychanKeeper = paychan.NewKeeper(app.cdc, app.keyPaychan, app.coinKeeper) app.paramsKeeper = params.NewKeeper(app.cdc, app.keyParams)
//app.ibcMapper = ibc.NewMapper(app.cdc, app.keyIBC, app.RegisterCodespace(ibc.DefaultCodespace))
app.stakeKeeper = stake.NewKeeper(app.cdc, app.keyStake, app.coinKeeper, app.RegisterCodespace(stake.DefaultCodespace)) app.stakeKeeper = stake.NewKeeper(app.cdc, app.keyStake, app.coinKeeper, app.RegisterCodespace(stake.DefaultCodespace))
app.slashingKeeper = slashing.NewKeeper(app.cdc, app.keySlashing, app.stakeKeeper, app.RegisterCodespace(slashing.DefaultCodespace))
//app.govKeeper = gov.NewKeeper(app.cdc, app.keyGov, app.coinKeeper, app.stakeKeeper, app.RegisterCodespace(gov.DefaultCodespace))
app.feeCollectionKeeper = auth.NewFeeCollectionKeeper(app.cdc, app.keyFeeCollection) app.feeCollectionKeeper = auth.NewFeeCollectionKeeper(app.cdc, app.keyFeeCollection)
app.slashingKeeper = slashing.NewKeeper(app.cdc, app.keySlashing, app.stakeKeeper, app.paramsKeeper.Getter(), app.RegisterCodespace(slashing.DefaultCodespace))
app.paychanKeeper = paychan.NewKeeper(app.cdc, app.keyPaychan, app.coinKeeper)
// Register the message handlers // Register the message handlers
app.Router(). app.Router().
AddRoute("bank", bank.NewHandler(app.coinKeeper)). AddRoute("bank", bank.NewHandler(app.coinKeeper)).
//AddRoute("ibc", ibc.NewHandler(app.ibcMapper, app.coinKeeper)).
AddRoute("stake", stake.NewHandler(app.stakeKeeper)). AddRoute("stake", stake.NewHandler(app.stakeKeeper)).
AddRoute("slashing", slashing.NewHandler(app.slashingKeeper)). AddRoute("slashing", slashing.NewHandler(app.slashingKeeper)).
AddRoute("paychan", paychan.NewHandler(app.paychanKeeper)) AddRoute("paychan", paychan.NewHandler(app.paychanKeeper))
//AddRoute("gov", gov.NewHandler(app.govKeeper))
// Set func to initialze the chain from appState in genesis file // Set func to initialize the chain from appState in genesis file
app.SetInitChainer(app.initChainer) app.SetInitChainer(app.initChainer)
// Set functions that run before and after txs / blocks // Set functions that run before and after txs / blocks
@ -120,7 +114,8 @@ func NewKavaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, baseAppOptio
app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.feeCollectionKeeper)) app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.feeCollectionKeeper))
// Mount stores // Mount stores
app.MountStoresIAVL(app.keyMain, app.keyAccount, app.keyStake, app.keySlashing, app.keyFeeCollection, app.keyPaychan) app.MountStoresIAVL(app.keyMain, app.keyAccount, app.keyStake, app.keySlashing, app.keyFeeCollection, app.keyParams, app.keyPaychan)
app.MountStore(app.tkeyParams, sdk.StoreTypeTransient)
err := app.LoadLatestVersion(app.keyMain) err := app.LoadLatestVersion(app.keyMain)
if err != nil { if err != nil {
cmn.Exit(err.Error()) cmn.Exit(err.Error())
@ -132,11 +127,9 @@ func NewKavaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, baseAppOptio
func CreateKavaAppCodec() *wire.Codec { func CreateKavaAppCodec() *wire.Codec {
cdc := wire.NewCodec() cdc := wire.NewCodec()
paychan.RegisterWire(cdc) paychan.RegisterWire(cdc)
//ibc.RegisterWire(cdc)
bank.RegisterWire(cdc) bank.RegisterWire(cdc)
stake.RegisterWire(cdc) stake.RegisterWire(cdc)
slashing.RegisterWire(cdc) slashing.RegisterWire(cdc)
//gov.RegisterWire(cdc)
auth.RegisterWire(cdc) auth.RegisterWire(cdc)
sdk.RegisterWire(cdc) sdk.RegisterWire(cdc)
wire.RegisterCrypto(cdc) wire.RegisterCrypto(cdc)
@ -154,18 +147,18 @@ func (app *KavaApp) BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock) ab
// The function baseapp runs on receipt of a EndBlock ABCI message // The function baseapp runs on receipt of a EndBlock ABCI message
func (app *KavaApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock { func (app *KavaApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
paychan.EndBlocker(ctx, app.paychanKeeper) tags := paychan.EndBlocker(ctx, app.paychanKeeper)
validatorUpdates := stake.EndBlocker(ctx, app.stakeKeeper)
//tags, _ := gov.EndBlocker(ctx, app.govKeeper) validatorUpdates := stake.EndBlocker(ctx, app.stakeKeeper)
app.slashingKeeper.AddValidators(ctx, validatorUpdates)
return abci.ResponseEndBlock{ return abci.ResponseEndBlock{
ValidatorUpdates: validatorUpdates, ValidatorUpdates: validatorUpdates,
//Tags: tags, Tags: tags,
} }
} }
// Initialzes the app db from the appState in the genesis file. Baseapp runs this on receipt of an InitChain ABCI message // Initializes the app db from the appState in the genesis file. Baseapp runs this on receipt of an InitChain ABCI message
func (app *KavaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain { func (app *KavaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci.ResponseInitChain {
stateJSON := req.AppStateBytes stateJSON := req.AppStateBytes
@ -183,14 +176,16 @@ func (app *KavaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
} }
// load the initial stake information // load the initial stake information
err = stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData) validators, err := stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData)
if err != nil { if err != nil {
panic(err) panic(err)
} }
//gov.InitGenesis(ctx, app.govKeeper, gov.DefaultGenesisState()) slashing.InitGenesis(ctx, app.slashingKeeper, genesisState.StakeData)
return abci.ResponseInitChain{} return abci.ResponseInitChain{
Validators: validators,
}
} }
// //

View File

@ -6,7 +6,10 @@ package app
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
"time"
"github.com/cosmos/cosmos-sdk/client"
"github.com/spf13/pflag" "github.com/spf13/pflag"
"github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto"
tmtypes "github.com/tendermint/tendermint/types" tmtypes "github.com/tendermint/tendermint/types"
@ -19,6 +22,8 @@ import (
"github.com/cosmos/cosmos-sdk/x/stake" "github.com/cosmos/cosmos-sdk/x/stake"
) )
const defaultPassword = "password"
var ( var (
// Tokens given to genesis validators and accounts // Tokens given to genesis validators and accounts
numStartingTokensValidators = int64(1000) numStartingTokensValidators = int64(1000)
@ -61,7 +66,7 @@ func (ga *GenesisAccount) ToAccount() (acc *auth.BaseAccount) {
} }
} }
// Create the appInit stuct for server init command // Create the appInit struct for server init command
func KavaAppInit() server.AppInit { func KavaAppInit() server.AppInit {
fsAppGenState := pflag.NewFlagSet("", pflag.ContinueOnError) fsAppGenState := pflag.NewFlagSet("", pflag.ContinueOnError)
fsAppGenTx := pflag.NewFlagSet("", pflag.ContinueOnError) fsAppGenTx := pflag.NewFlagSet("", pflag.ContinueOnError)
@ -86,22 +91,41 @@ type KavaGenTx struct {
PubKey string `json:"pub_key"` PubKey string `json:"pub_key"`
} }
// Generate a genesis transsction // Generate a genesis transaction
func KavaAppGenTx(cdc *wire.Codec, pk crypto.PubKey, genTxConfig config.GenTx) ( func KavaAppGenTx(cdc *wire.Codec, pk crypto.PubKey, genTxConfig config.GenTx) (
appGenTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error) { appGenTx, cliPrint json.RawMessage, validator tmtypes.GenesisValidator, err error) {
// Generate address and secret key for the validator // check a name for the new validator has been specified
if genTxConfig.Name == "" { if genTxConfig.Name == "" {
return nil, nil, tmtypes.GenesisValidator{}, errors.New("Must specify --name (validator moniker)") return nil, nil, tmtypes.GenesisValidator{}, errors.New("Must specify --name (validator moniker)")
} }
var addr sdk.AccAddress
var secret string // get a new password for the new account
addr, secret, err = server.GenerateSaveCoinKey(genTxConfig.CliRoot, genTxConfig.Name, "password", genTxConfig.Overwrite) buf := client.BufferStdin()
prompt := fmt.Sprintf("Password for account '%s' (default %s):", genTxConfig.Name, defaultPassword)
keyPass, err := client.GetPassword(prompt, buf)
if err != nil && keyPass != "" {
// An error was returned that either failed to read the password from
// STDIN or the given password is not empty but failed to meet minimum
// length requirements.
return appGenTx, cliPrint, validator, err
}
if keyPass == "" {
keyPass = defaultPassword
}
// generate a new address and secret key
addr, secret, err := server.GenerateSaveCoinKey(
genTxConfig.CliRoot,
genTxConfig.Name,
defaultPassword,
genTxConfig.Overwrite,
)
if err != nil { if err != nil {
return return
} }
// Create string to print out // Create message string to print out
mm := map[string]string{"secret": secret} mm := map[string]string{"secret": secret}
var bz []byte var bz []byte
bz, err = cdc.MarshalJSON(mm) bz, err = cdc.MarshalJSON(mm)
@ -154,6 +178,8 @@ func KavaAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (genesisState
stakeData := stake.DefaultGenesisState() stakeData := stake.DefaultGenesisState()
// change denom of staking coin // change denom of staking coin
stakeData.Params.BondDenom = "KVA" stakeData.Params.BondDenom = "KVA"
// drastically shorten unbonding time for test purposes
stakeData.Params.UnbondingTime = time.Second * 60 * 5 // 5 minutes
// get genesis flag account information // get genesis flag account information
genaccs := make([]GenesisAccount, len(appGenTxs)) genaccs := make([]GenesisAccount, len(appGenTxs))

View File

@ -1,27 +1,24 @@
package lcd package lcd
/*
import ( import (
"net/http"
//"encoding/hex"
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"net/http"
"github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/wire"
"github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/auth"
) )
*/
type TxBody struct { type txBody struct {
TxBase64 string `json:"txbase64"` TxBase64 string `json:"txbase64"`
} }
// Decode a tx from base64 into json // Decode a tx from base64 into json
func DecodeTxRequestHandlerFn(ctx context.CoreContext, cdc *wire.Codec) http.HandlerFunc { func DecodeTxRequestHandlerFn(cliCtx context.CLIContext, cdc *wire.Codec) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
// get the input base64 string // get the input base64 string
var m TxBody var m txBody
decoder := json.NewDecoder(r.Body) decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&m) err := decoder.Decode(&m)
if err != nil { if err != nil {

695
internal/lcd/lcd_test.go Normal file
View File

@ -0,0 +1,695 @@
// Copyright 2016 All in Bits, inc
// Modifications copyright 2018 Kava Labs
package lcd
import (
"encoding/hex"
"fmt"
"net/http"
"regexp"
"testing"
"time"
"github.com/cosmos/cosmos-sdk/client/tx"
"github.com/spf13/viper"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
cryptoKeys "github.com/cosmos/cosmos-sdk/crypto/keys"
p2p "github.com/tendermint/tendermint/p2p"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
client "github.com/cosmos/cosmos-sdk/client"
keys "github.com/cosmos/cosmos-sdk/client/keys"
rpc "github.com/cosmos/cosmos-sdk/client/rpc"
tests "github.com/cosmos/cosmos-sdk/tests"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/wire"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/slashing"
"github.com/cosmos/cosmos-sdk/x/stake"
"github.com/cosmos/cosmos-sdk/x/stake/client/rest"
)
func init() {
cryptoKeys.BcryptSecurityParameter = 1
}
func TestKeys(t *testing.T) {
name, password := "test", "1234567890"
addr, seed := CreateAddr(t, "test", password, GetKeyBase(t))
cleanup, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr})
defer cleanup()
// get seed
// TODO Do we really need this endpoint?
res, body := Request(t, port, "GET", "/keys/seed", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
reg, err := regexp.Compile(`([a-z]+ ){12}`)
require.Nil(t, err)
match := reg.MatchString(seed)
require.True(t, match, "Returned seed has wrong format", seed)
newName := "test_newname"
newPassword := "0987654321"
// add key
jsonStr := []byte(fmt.Sprintf(`{"name":"%s", "password":"%s", "seed":"%s"}`, newName, newPassword, seed))
res, body = Request(t, port, "POST", "/keys", jsonStr)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var resp keys.KeyOutput
err = wire.Cdc.UnmarshalJSON([]byte(body), &resp)
require.Nil(t, err, body)
addr2Bech32 := resp.Address.String()
_, err = sdk.AccAddressFromBech32(addr2Bech32)
require.NoError(t, err, "Failed to return a correct bech32 address")
// test if created account is the correct account
expectedInfo, _ := GetKeyBase(t).CreateKey(newName, seed, newPassword)
expectedAccount := sdk.AccAddress(expectedInfo.GetPubKey().Address().Bytes())
assert.Equal(t, expectedAccount.String(), addr2Bech32)
// existing keys
res, body = Request(t, port, "GET", "/keys", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var m [2]keys.KeyOutput
err = cdc.UnmarshalJSON([]byte(body), &m)
require.Nil(t, err)
addrBech32 := addr.String()
require.Equal(t, name, m[0].Name, "Did not serve keys name correctly")
require.Equal(t, addrBech32, m[0].Address.String(), "Did not serve keys Address correctly")
require.Equal(t, newName, m[1].Name, "Did not serve keys name correctly")
require.Equal(t, addr2Bech32, m[1].Address.String(), "Did not serve keys Address correctly")
// select key
keyEndpoint := fmt.Sprintf("/keys/%s", newName)
res, body = Request(t, port, "GET", keyEndpoint, nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var m2 keys.KeyOutput
err = cdc.UnmarshalJSON([]byte(body), &m2)
require.Nil(t, err)
require.Equal(t, newName, m2.Name, "Did not serve keys name correctly")
require.Equal(t, addr2Bech32, m2.Address.String(), "Did not serve keys Address correctly")
// update key
jsonStr = []byte(fmt.Sprintf(`{
"old_password":"%s",
"new_password":"12345678901"
}`, newPassword))
res, body = Request(t, port, "PUT", keyEndpoint, jsonStr)
require.Equal(t, http.StatusOK, res.StatusCode, body)
// here it should say unauthorized as we changed the password before
res, body = Request(t, port, "PUT", keyEndpoint, jsonStr)
require.Equal(t, http.StatusUnauthorized, res.StatusCode, body)
// delete key
jsonStr = []byte(`{"password":"12345678901"}`)
res, body = Request(t, port, "DELETE", keyEndpoint, jsonStr)
require.Equal(t, http.StatusOK, res.StatusCode, body)
}
func TestVersion(t *testing.T) {
cleanup, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{})
defer cleanup()
// node info
res, body := Request(t, port, "GET", "/version", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
reg, err := regexp.Compile(`\d+\.\d+\.\d+(-dev)?`)
require.Nil(t, err)
match := reg.MatchString(body)
require.True(t, match, body)
// node info
res, body = Request(t, port, "GET", "/node_version", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
reg, err = regexp.Compile(`\d+\.\d+\.\d+(-dev)?`)
require.Nil(t, err)
match = reg.MatchString(body)
require.True(t, match, body)
}
func TestNodeStatus(t *testing.T) {
cleanup, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{})
defer cleanup()
// node info
res, body := Request(t, port, "GET", "/node_info", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var nodeInfo p2p.NodeInfo
err := cdc.UnmarshalJSON([]byte(body), &nodeInfo)
require.Nil(t, err, "Couldn't parse node info")
require.NotEqual(t, p2p.NodeInfo{}, nodeInfo, "res: %v", res)
// syncing
res, body = Request(t, port, "GET", "/syncing", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
// we expect that there is no other node running so the syncing state is "false"
require.Equal(t, "false", body)
}
func TestBlock(t *testing.T) {
cleanup, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{})
defer cleanup()
var resultBlock ctypes.ResultBlock
res, body := Request(t, port, "GET", "/blocks/latest", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
err := cdc.UnmarshalJSON([]byte(body), &resultBlock)
require.Nil(t, err, "Couldn't parse block")
require.NotEqual(t, ctypes.ResultBlock{}, resultBlock)
// --
res, body = Request(t, port, "GET", "/blocks/1", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
err = wire.Cdc.UnmarshalJSON([]byte(body), &resultBlock)
require.Nil(t, err, "Couldn't parse block")
require.NotEqual(t, ctypes.ResultBlock{}, resultBlock)
// --
res, body = Request(t, port, "GET", "/blocks/1000000000", nil)
require.Equal(t, http.StatusNotFound, res.StatusCode, body)
}
func TestValidators(t *testing.T) {
cleanup, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{})
defer cleanup()
var resultVals rpc.ResultValidatorsOutput
res, body := Request(t, port, "GET", "/validatorsets/latest", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
err := cdc.UnmarshalJSON([]byte(body), &resultVals)
require.Nil(t, err, "Couldn't parse validatorset")
require.NotEqual(t, rpc.ResultValidatorsOutput{}, resultVals)
require.Contains(t, resultVals.Validators[0].Address.String(), "kvaladdr")
require.Contains(t, resultVals.Validators[0].PubKey, "kvalpub")
// --
res, body = Request(t, port, "GET", "/validatorsets/1", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
err = cdc.UnmarshalJSON([]byte(body), &resultVals)
require.Nil(t, err, "Couldn't parse validatorset")
require.NotEqual(t, rpc.ResultValidatorsOutput{}, resultVals)
// --
res, body = Request(t, port, "GET", "/validatorsets/1000000000", nil)
require.Equal(t, http.StatusNotFound, res.StatusCode, body)
}
func TestCoinSend(t *testing.T) {
name, password := "test", "1234567890"
addr, seed := CreateAddr(t, "test", password, GetKeyBase(t))
cleanup, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr})
defer cleanup()
bz, err := hex.DecodeString("8FA6AB57AD6870F6B5B2E57735F38F2F30E73CB6")
require.NoError(t, err)
someFakeAddr := sdk.AccAddress(bz)
// query empty
res, body := Request(t, port, "GET", fmt.Sprintf("/accounts/%s", someFakeAddr), nil)
require.Equal(t, http.StatusNoContent, res.StatusCode, body)
acc := getAccount(t, port, addr)
initialBalance := acc.GetCoins()
// create TX
receiveAddr, resultTx := doSend(t, port, seed, name, password, addr)
tests.WaitForHeight(resultTx.Height+1, port)
// check if tx was committed
require.Equal(t, uint32(0), resultTx.CheckTx.Code)
require.Equal(t, uint32(0), resultTx.DeliverTx.Code)
// query sender
acc = getAccount(t, port, addr)
coins := acc.GetCoins()
mycoins := coins[0]
require.Equal(t, "KVA", mycoins.Denom)
require.Equal(t, initialBalance[0].Amount.SubRaw(1), mycoins.Amount)
// query receiver
acc = getAccount(t, port, receiveAddr)
coins = acc.GetCoins()
mycoins = coins[0]
require.Equal(t, "KVA", mycoins.Denom)
require.Equal(t, int64(1), mycoins.Amount.Int64())
}
func TestTxs(t *testing.T) {
name, password := "test", "1234567890"
addr, seed := CreateAddr(t, "test", password, GetKeyBase(t))
cleanup, _, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr})
defer cleanup()
// query wrong
res, body := Request(t, port, "GET", "/txs", nil)
require.Equal(t, http.StatusBadRequest, res.StatusCode, body)
// query empty
res, body = Request(t, port, "GET", fmt.Sprintf("/txs?tag=sender_bech32='%s'", "kaccaddr1z2my792ekdthxfkwyks0pwl69jucf9wjq3txwj"), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
require.Equal(t, "[]", body)
// create TX
receiveAddr, resultTx := doSend(t, port, seed, name, password, addr)
tests.WaitForHeight(resultTx.Height+1, port)
// check if tx is findable
res, body = Request(t, port, "GET", fmt.Sprintf("/txs/%s", resultTx.Hash), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var indexedTxs []tx.Info
// check if tx is queryable
res, body = Request(t, port, "GET", fmt.Sprintf("/txs?tag=tx.hash='%s'", resultTx.Hash), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
require.NotEqual(t, "[]", body)
err := cdc.UnmarshalJSON([]byte(body), &indexedTxs)
require.NoError(t, err)
require.Equal(t, 1, len(indexedTxs))
// XXX should this move into some other testfile for txs in general?
// test if created TX hash is the correct hash
require.Equal(t, resultTx.Hash, indexedTxs[0].Hash)
// query sender
// also tests url decoding
res, body = Request(t, port, "GET", fmt.Sprintf("/txs?tag=sender_bech32=%%27%s%%27", addr), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
err = cdc.UnmarshalJSON([]byte(body), &indexedTxs)
require.NoError(t, err)
require.Equal(t, 1, len(indexedTxs), "%v", indexedTxs) // there are 2 txs created with doSend
require.Equal(t, resultTx.Height, indexedTxs[0].Height)
// query recipient
res, body = Request(t, port, "GET", fmt.Sprintf("/txs?tag=recipient_bech32='%s'", receiveAddr), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
err = cdc.UnmarshalJSON([]byte(body), &indexedTxs)
require.NoError(t, err)
require.Equal(t, 1, len(indexedTxs))
require.Equal(t, resultTx.Height, indexedTxs[0].Height)
}
func TestValidatorsQuery(t *testing.T) {
cleanup, pks, port := InitializeTestLCD(t, 1, []sdk.AccAddress{})
defer cleanup()
require.Equal(t, 1, len(pks))
validators := getValidators(t, port)
require.Equal(t, len(validators), 1)
// make sure all the validators were found (order unknown because sorted by owner addr)
foundVal := false
pkBech := sdk.MustBech32ifyValPub(pks[0])
if validators[0].PubKey == pkBech {
foundVal = true
}
require.True(t, foundVal, "pkBech %v, owner %v", pkBech, validators[0].Owner)
}
func TestValidatorQuery(t *testing.T) {
cleanup, pks, port := InitializeTestLCD(t, 1, []sdk.AccAddress{})
defer cleanup()
require.Equal(t, 1, len(pks))
validator1Owner := sdk.AccAddress(pks[0].Address())
validator := getValidator(t, port, validator1Owner)
bech32ValAddress, err := sdk.Bech32ifyValPub(pks[0])
require.NoError(t, err)
assert.Equal(t, validator.PubKey, bech32ValAddress, "The returned validator does not hold the correct data")
}
func TestBonding(t *testing.T) {
name, password, denom := "test", "1234567890", "KVA"
addr, seed := CreateAddr(t, "test", password, GetKeyBase(t))
cleanup, pks, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr})
defer cleanup()
validator1Owner := sdk.AccAddress(pks[0].Address())
// create bond TX
resultTx := doDelegate(t, port, seed, name, password, addr, validator1Owner)
tests.WaitForHeight(resultTx.Height+1, port)
// check if tx was committed
require.Equal(t, uint32(0), resultTx.CheckTx.Code)
require.Equal(t, uint32(0), resultTx.DeliverTx.Code)
// query sender
acc := getAccount(t, port, addr)
coins := acc.GetCoins()
require.Equal(t, int64(40), coins.AmountOf(denom).Int64())
// query validator
bond := getDelegation(t, port, addr, validator1Owner)
require.Equal(t, "60.0000000000", bond.Shares)
//////////////////////
// testing unbonding
// create unbond TX
resultTx = doBeginUnbonding(t, port, seed, name, password, addr, validator1Owner)
tests.WaitForHeight(resultTx.Height+1, port)
// query validator
bond = getDelegation(t, port, addr, validator1Owner)
require.Equal(t, "30.0000000000", bond.Shares)
// check if tx was committed
require.Equal(t, uint32(0), resultTx.CheckTx.Code)
require.Equal(t, uint32(0), resultTx.DeliverTx.Code)
// should the sender should have not received any coins as the unbonding has only just begun
// query sender
acc = getAccount(t, port, addr)
coins = acc.GetCoins()
require.Equal(t, int64(40), coins.AmountOf("KVA").Int64())
// query unbonding delegation
validatorAddr := sdk.AccAddress(pks[0].Address())
unbondings := getUndelegations(t, port, addr, validatorAddr)
assert.Len(t, unbondings, 1, "Unbondings holds all unbonding-delegations")
assert.Equal(t, "30", unbondings[0].Balance.Amount.String())
// query summary
summary := getDelegationSummary(t, port, addr)
assert.Len(t, summary.Delegations, 1, "Delegation summary holds all delegations")
assert.Equal(t, "30.0000000000", summary.Delegations[0].Shares)
assert.Len(t, summary.UnbondingDelegations, 1, "Delegation summary holds all unbonding-delegations")
assert.Equal(t, "30", summary.UnbondingDelegations[0].Balance.Amount.String())
// TODO add redelegation, need more complex capabilities such to mock context and
// TODO check summary for redelegation
// assert.Len(t, summary.Redelegations, 1, "Delegation summary holds all redelegations")
// query txs
txs := getBondingTxs(t, port, addr, "")
assert.Len(t, txs, 2, "All Txs found")
txs = getBondingTxs(t, port, addr, "bond")
assert.Len(t, txs, 1, "All bonding txs found")
txs = getBondingTxs(t, port, addr, "unbond")
assert.Len(t, txs, 1, "All unbonding txs found")
}
func TestUnrevoke(t *testing.T) {
_, password := "test", "1234567890"
addr, _ := CreateAddr(t, "test", password, GetKeyBase(t))
cleanup, pks, port := InitializeTestLCD(t, 1, []sdk.AccAddress{addr})
defer cleanup()
// XXX: any less than this and it fails
tests.WaitForHeight(3, port)
pkString, _ := sdk.Bech32ifyValPub(pks[0])
signingInfo := getSigningInfo(t, port, pkString)
tests.WaitForHeight(4, port)
require.Equal(t, true, signingInfo.IndexOffset > 0)
require.Equal(t, time.Unix(0, 0).UTC(), signingInfo.JailedUntil)
require.Equal(t, true, signingInfo.SignedBlocksCounter > 0)
}
//_____________________________________________________________________________
// get the account to get the sequence
func getAccount(t *testing.T, port string, addr sdk.AccAddress) auth.Account {
res, body := Request(t, port, "GET", fmt.Sprintf("/accounts/%s", addr), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var acc auth.Account
err := cdc.UnmarshalJSON([]byte(body), &acc)
require.Nil(t, err)
return acc
}
func doSend(t *testing.T, port, seed, name, password string, addr sdk.AccAddress) (receiveAddr sdk.AccAddress, resultTx ctypes.ResultBroadcastTxCommit) {
// create receive address
kb := client.MockKeyBase()
receiveInfo, _, err := kb.CreateMnemonic("receive_address", cryptoKeys.English, "1234567890", cryptoKeys.SigningAlgo("secp256k1"))
require.Nil(t, err)
receiveAddr = sdk.AccAddress(receiveInfo.GetPubKey().Address())
acc := getAccount(t, port, addr)
accnum := acc.GetAccountNumber()
sequence := acc.GetSequence()
chainID := viper.GetString(client.FlagChainID)
// send
coinbz, err := cdc.MarshalJSON(sdk.NewInt64Coin("KVA", 1))
if err != nil {
panic(err)
}
jsonStr := []byte(fmt.Sprintf(`{
"name":"%s",
"password":"%s",
"account_number":"%d",
"sequence":"%d",
"gas": "10000",
"amount":[%s],
"chain_id":"%s"
}`, name, password, accnum, sequence, coinbz, chainID))
res, body := Request(t, port, "POST", fmt.Sprintf("/accounts/%s/send", receiveAddr), jsonStr)
require.Equal(t, http.StatusOK, res.StatusCode, body)
err = cdc.UnmarshalJSON([]byte(body), &resultTx)
require.Nil(t, err)
return receiveAddr, resultTx
}
func getSigningInfo(t *testing.T, port string, validatorPubKey string) slashing.ValidatorSigningInfo {
res, body := Request(t, port, "GET", fmt.Sprintf("/slashing/signing_info/%s", validatorPubKey), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var signingInfo slashing.ValidatorSigningInfo
err := cdc.UnmarshalJSON([]byte(body), &signingInfo)
require.Nil(t, err)
return signingInfo
}
// ============= Stake Module ================
func getDelegation(t *testing.T, port string, delegatorAddr, validatorAddr sdk.AccAddress) rest.DelegationWithoutRat {
// get the account to get the sequence
res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/delegations/%s", delegatorAddr, validatorAddr), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var bond rest.DelegationWithoutRat
err := cdc.UnmarshalJSON([]byte(body), &bond)
require.Nil(t, err)
return bond
}
func getUndelegations(t *testing.T, port string, delegatorAddr, validatorAddr sdk.AccAddress) []stake.UnbondingDelegation {
// get the account to get the sequence
res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/unbonding_delegations/%s", delegatorAddr, validatorAddr), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var unbondings []stake.UnbondingDelegation
err := cdc.UnmarshalJSON([]byte(body), &unbondings)
require.Nil(t, err)
return unbondings
}
func getDelegationSummary(t *testing.T, port string, delegatorAddr sdk.AccAddress) rest.DelegationSummary {
// get the account to get the sequence
res, body := Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s", delegatorAddr), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var summary rest.DelegationSummary
err := cdc.UnmarshalJSON([]byte(body), &summary)
require.Nil(t, err)
return summary
}
func getBondingTxs(t *testing.T, port string, delegatorAddr sdk.AccAddress, query string) []tx.Info {
// get the account to get the sequence
var res *http.Response
var body string
if len(query) > 0 {
res, body = Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/txs?type=%s", delegatorAddr, query), nil)
} else {
res, body = Request(t, port, "GET", fmt.Sprintf("/stake/delegators/%s/txs", delegatorAddr), nil)
}
require.Equal(t, http.StatusOK, res.StatusCode, body)
var txs []tx.Info
err := cdc.UnmarshalJSON([]byte(body), &txs)
require.Nil(t, err)
return txs
}
func doDelegate(t *testing.T, port, seed, name, password string, delegatorAddr, validatorAddr sdk.AccAddress) (resultTx ctypes.ResultBroadcastTxCommit) {
// get the account to get the sequence
acc := getAccount(t, port, delegatorAddr)
accnum := acc.GetAccountNumber()
sequence := acc.GetSequence()
chainID := viper.GetString(client.FlagChainID)
// send
jsonStr := []byte(fmt.Sprintf(`{
"name": "%s",
"password": "%s",
"account_number": "%d",
"sequence": "%d",
"gas": "10000",
"chain_id": "%s",
"delegations": [
{
"delegator_addr": "%s",
"validator_addr": "%s",
"delegation": { "denom": "%s", "amount": "60" }
}
],
"begin_unbondings": [],
"complete_unbondings": [],
"begin_redelegates": [],
"complete_redelegates": []
}`, name, password, accnum, sequence, chainID, delegatorAddr, validatorAddr, "KVA"))
res, body := Request(t, port, "POST", fmt.Sprintf("/stake/delegators/%s/delegations", delegatorAddr), jsonStr)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var results []ctypes.ResultBroadcastTxCommit
err := cdc.UnmarshalJSON([]byte(body), &results)
require.Nil(t, err)
return results[0]
}
func doBeginUnbonding(t *testing.T, port, seed, name, password string,
delegatorAddr, validatorAddr sdk.AccAddress) (resultTx ctypes.ResultBroadcastTxCommit) {
// get the account to get the sequence
acc := getAccount(t, port, delegatorAddr)
accnum := acc.GetAccountNumber()
sequence := acc.GetSequence()
chainID := viper.GetString(client.FlagChainID)
// send
jsonStr := []byte(fmt.Sprintf(`{
"name": "%s",
"password": "%s",
"account_number": "%d",
"sequence": "%d",
"gas": "20000",
"chain_id": "%s",
"delegations": [],
"begin_unbondings": [
{
"delegator_addr": "%s",
"validator_addr": "%s",
"shares": "30"
}
],
"complete_unbondings": [],
"begin_redelegates": [],
"complete_redelegates": []
}`, name, password, accnum, sequence, chainID, delegatorAddr, validatorAddr))
res, body := Request(t, port, "POST", fmt.Sprintf("/stake/delegators/%s/delegations", delegatorAddr), jsonStr)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var results []ctypes.ResultBroadcastTxCommit
err := cdc.UnmarshalJSON([]byte(body), &results)
require.Nil(t, err)
return results[0]
}
func doBeginRedelegation(t *testing.T, port, seed, name, password string,
delegatorAddr, validatorSrcAddr, validatorDstAddr sdk.AccAddress) (resultTx ctypes.ResultBroadcastTxCommit) {
// get the account to get the sequence
acc := getAccount(t, port, delegatorAddr)
accnum := acc.GetAccountNumber()
sequence := acc.GetSequence()
chainID := viper.GetString(client.FlagChainID)
// send
jsonStr := []byte(fmt.Sprintf(`{
"name": "%s",
"password": "%s",
"account_number": "%d",
"sequence": "%d",
"gas": "10000",
"chain_id": "%s",
"delegations": [],
"begin_unbondings": [],
"complete_unbondings": [],
"begin_redelegates": [
{
"delegator_addr": "%s",
"validator_src_addr": "%s",
"validator_dst_addr": "%s",
"shares": "30"
}
],
"complete_redelegates": []
}`, name, password, accnum, sequence, chainID, delegatorAddr, validatorSrcAddr, validatorDstAddr))
res, body := Request(t, port, "POST", fmt.Sprintf("/stake/delegators/%s/delegations", delegatorAddr), jsonStr)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var results []ctypes.ResultBroadcastTxCommit
err := cdc.UnmarshalJSON([]byte(body), &results)
require.Nil(t, err)
return results[0]
}
func getValidators(t *testing.T, port string) []stake.BechValidator {
// get the account to get the sequence
res, body := Request(t, port, "GET", "/stake/validators", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var validators []stake.BechValidator
err := cdc.UnmarshalJSON([]byte(body), &validators)
require.Nil(t, err)
return validators
}
func getValidator(t *testing.T, port string, validatorAddr sdk.AccAddress) stake.BechValidator {
// get the account to get the sequence
res, body := Request(t, port, "GET", fmt.Sprintf("/stake/validators/%s", validatorAddr.String()), nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var validator stake.BechValidator
err := cdc.UnmarshalJSON([]byte(body), &validator)
require.Nil(t, err)
return validator
}

View File

@ -3,32 +3,27 @@
package lcd package lcd
/*
import ( import (
"net/http" "net/http"
"os" "os"
"github.com/gorilla/mux"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/tendermint/tmlibs/log"
tmserver "github.com/tendermint/tendermint/rpc/lib/server"
cmn "github.com/tendermint/tmlibs/common"
client "github.com/cosmos/cosmos-sdk/client" client "github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/context"
keys "github.com/cosmos/cosmos-sdk/client/keys" keys "github.com/cosmos/cosmos-sdk/client/keys"
rpc "github.com/cosmos/cosmos-sdk/client/rpc" rpc "github.com/cosmos/cosmos-sdk/client/rpc"
tx "github.com/cosmos/cosmos-sdk/client/tx" tx "github.com/cosmos/cosmos-sdk/client/tx"
version "github.com/cosmos/cosmos-sdk/version"
"github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/wire"
auth "github.com/cosmos/cosmos-sdk/x/auth/client/rest" auth "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
bank "github.com/cosmos/cosmos-sdk/x/bank/client/rest" bank "github.com/cosmos/cosmos-sdk/x/bank/client/rest"
//ibc "github.com/cosmos/cosmos-sdk/x/ibc/client/rest" slashing "github.com/cosmos/cosmos-sdk/x/slashing/client/rest"
//stake "github.com/cosmos/cosmos-sdk/x/stake/client/rest" stake "github.com/cosmos/cosmos-sdk/x/stake/client/rest"
"github.com/gorilla/mux"
"github.com/spf13/cobra"
"github.com/spf13/viper"
cmn "github.com/tendermint/tendermint/libs/common"
"github.com/tendermint/tendermint/libs/log"
tmserver "github.com/tendermint/tendermint/rpc/lib/server"
) )
*/
// ServeCommand will generate a long-running rest server // ServeCommand will generate a long-running rest server
// (aka Light Client Daemon) that exposes functionality similar // (aka Light Client Daemon) that exposes functionality similar
@ -36,6 +31,7 @@ import (
func ServeCommand(cdc *wire.Codec) *cobra.Command { func ServeCommand(cdc *wire.Codec) *cobra.Command {
flagListenAddr := "laddr" flagListenAddr := "laddr"
flagCORS := "cors" flagCORS := "cors"
flagMaxOpenConnections := "max-open"
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "rest-server", Use: "rest-server",
@ -43,48 +39,59 @@ func ServeCommand(cdc *wire.Codec) *cobra.Command {
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
listenAddr := viper.GetString(flagListenAddr) listenAddr := viper.GetString(flagListenAddr)
handler := createHandler(cdc) handler := createHandler(cdc)
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)). logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "rest-server")
With("module", "rest-server") maxOpen := viper.GetInt(flagMaxOpenConnections)
listener, err := tmserver.StartHTTPServer(listenAddr, handler, logger)
listener, err := tmserver.StartHTTPServer(
listenAddr, handler, logger,
tmserver.Config{MaxOpenConnections: maxOpen},
)
if err != nil { if err != nil {
return err return err
} }
logger.Info("REST server started") logger.Info("REST server started")
// Wait forever and cleanup // wait forever and cleanup
cmn.TrapSignal(func() { cmn.TrapSignal(func() {
err := listener.Close() err := listener.Close()
logger.Error("Error closing listener", "err", err) logger.Error("error closing listener", "err", err)
}) })
return nil return nil
}, },
} }
cmd.Flags().StringP(flagListenAddr, "a", "tcp://localhost:1317", "Address for server to listen on")
cmd.Flags().String(flagCORS, "", "Set to domains that can make CORS requests (* for all)") cmd.Flags().String(flagListenAddr, "tcp://localhost:1317", "The address for the server to listen on")
cmd.Flags().StringP(client.FlagChainID, "c", "", "ID of chain we connect to") cmd.Flags().String(flagCORS, "", "Set the domains that can make CORS requests (* for all)")
cmd.Flags().StringP(client.FlagNode, "n", "tcp://localhost:46657", "Node to connect to") cmd.Flags().String(client.FlagChainID, "", "The chain ID to connect to")
cmd.Flags().String(client.FlagNode, "tcp://localhost:17127", "Address of the node to connect to")
cmd.Flags().Int(flagMaxOpenConnections, 1000, "The number of maximum open connections")
return cmd return cmd
} }
func createHandler(cdc *wire.Codec) http.Handler { func createHandler(cdc *wire.Codec) http.Handler {
r := mux.NewRouter() r := mux.NewRouter()
r.HandleFunc("/version", version.RequestHandler).Methods("GET")
kb, err := keys.GetKeyBase() //XXX kb, err := keys.GetKeyBase() //XXX
if err != nil { if err != nil {
panic(err) panic(err)
} }
ctx := context.NewCoreContextFromViper() cliCtx := context.NewCLIContext().WithCodec(cdc).WithLogger(os.Stdout)
r.HandleFunc("/version", CLIVersionRequestHandler).Methods("GET")
r.HandleFunc("/node_version", NodeVersionRequestHandler(cliCtx)).Methods("GET")
r.HandleFunc("/decode_tx", DecodeTxRequestHandlerFn(cliCtx, cdc)).Methods("POST")
// TODO make more functional? aka r = keys.RegisterRoutes(r)
keys.RegisterRoutes(r) keys.RegisterRoutes(r)
rpc.RegisterRoutes(ctx, r) rpc.RegisterRoutes(cliCtx, r)
tx.RegisterRoutes(ctx, r, cdc) tx.RegisterRoutes(cliCtx, r, cdc)
auth.RegisterRoutes(ctx, r, cdc, "acc") auth.RegisterRoutes(cliCtx, r, cdc, "acc")
bank.RegisterRoutes(ctx, r, cdc, kb) bank.RegisterRoutes(cliCtx, r, cdc, kb)
//ibc.RegisterRoutes(ctx, r, cdc, kb) stake.RegisterRoutes(cliCtx, r, cdc, kb)
//stake.RegisterRoutes(ctx, r, cdc, kb) slashing.RegisterRoutes(cliCtx, r, cdc, kb)
r.HandleFunc("/decode_tx", DecodeTxRequestHandlerFn(ctx, cdc)).Methods("POST")
return r return r
} }

View File

@ -0,0 +1,275 @@
// Copyright 2016 All in Bits, inc
// Modifications copyright 2018 Kava Labs
package lcd
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net"
"net/http"
"os"
"path/filepath"
"strings"
"testing"
"github.com/cosmos/cosmos-sdk/client"
keys "github.com/cosmos/cosmos-sdk/client/keys"
crkeys "github.com/cosmos/cosmos-sdk/crypto/keys"
"github.com/cosmos/cosmos-sdk/server"
"github.com/cosmos/cosmos-sdk/tests"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/wire"
"github.com/cosmos/cosmos-sdk/x/auth"
kapp "github.com/kava-labs/kava/internal/app"
"github.com/spf13/viper"
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
tmcfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519"
"github.com/tendermint/tendermint/libs/cli"
dbm "github.com/tendermint/tendermint/libs/db"
"github.com/tendermint/tendermint/libs/log"
nm "github.com/tendermint/tendermint/node"
pvm "github.com/tendermint/tendermint/privval"
"github.com/tendermint/tendermint/proxy"
tmrpc "github.com/tendermint/tendermint/rpc/lib/server"
tmtypes "github.com/tendermint/tendermint/types"
)
// makePathname creates a unique pathname for each test. It will panic if it
// cannot get the current working directory.
func makePathname() string {
p, err := os.Getwd()
if err != nil {
panic(err)
}
sep := string(filepath.Separator)
return strings.Replace(p, sep, "_", -1)
}
// GetConfig returns a Tendermint config for the test cases.
func GetConfig() *tmcfg.Config {
pathname := makePathname()
config := tmcfg.ResetTestRoot(pathname)
tmAddr, _, err := server.FreeTCPAddr()
if err != nil {
panic(err)
}
rcpAddr, _, err := server.FreeTCPAddr()
if err != nil {
panic(err)
}
grpcAddr, _, err := server.FreeTCPAddr()
if err != nil {
panic(err)
}
config.P2P.ListenAddress = tmAddr
config.RPC.ListenAddress = rcpAddr
config.RPC.GRPCListenAddress = grpcAddr
return config
}
// GetKeyBase returns the LCD test keybase. It also requires that a directory
// could be made and a keybase could be fetched.
//
// NOTE: memDB cannot be used because the request is expecting to interact with
// the default location.
func GetKeyBase(t *testing.T) crkeys.Keybase {
dir, err := ioutil.TempDir("", "lcd_test")
require.NoError(t, err)
viper.Set(cli.HomeFlag, dir)
keybase, err := keys.GetKeyBase()
require.NoError(t, err)
return keybase
}
// CreateAddr adds an address to the key store and returns an address and seed.
// It also requires that the key could be created.
func CreateAddr(t *testing.T, name, password string, kb crkeys.Keybase) (sdk.AccAddress, string) {
var (
err error
info crkeys.Info
seed string
)
info, seed, err = kb.CreateMnemonic(name, crkeys.English, password, crkeys.Secp256k1)
require.NoError(t, err)
return sdk.AccAddress(info.GetPubKey().Address()), seed
}
// InitializeTestLCD starts Tendermint and the LCD in process, listening on
// their respective sockets where nValidators is the total number of validators
// and initAddrs are the accounts to initialize with some KVA tokens. It
// returns a cleanup function, a set of validator public keys, and a port.
func InitializeTestLCD(t *testing.T, nValidators int, initAddrs []sdk.AccAddress) (func(), []crypto.PubKey, string) {
config := GetConfig()
config.Consensus.TimeoutCommit = 100
config.Consensus.SkipTimeoutCommit = false
config.TxIndex.IndexAllTags = true
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
logger = log.NewFilter(logger, log.AllowError())
privValidatorFile := config.PrivValidatorFile()
privVal := pvm.LoadOrGenFilePV(privValidatorFile)
privVal.Reset()
db := dbm.NewMemDB()
app := kapp.NewKavaApp(logger, db, nil)
cdc = kapp.CreateKavaAppCodec()
genesisFile := config.GenesisFile()
genDoc, err := tmtypes.GenesisDocFromFile(genesisFile)
require.NoError(t, err)
if nValidators < 1 {
panic("InitializeTestLCD must use at least one validator")
}
for i := 1; i < nValidators; i++ {
genDoc.Validators = append(genDoc.Validators,
tmtypes.GenesisValidator{
PubKey: ed25519.GenPrivKey().PubKey(),
Power: 1,
Name: "val",
},
)
}
var validatorsPKs []crypto.PubKey
// NOTE: It's bad practice to reuse public key address for the owner
// address but doing in the test for simplicity.
var appGenTxs []json.RawMessage
for _, gdValidator := range genDoc.Validators {
pk := gdValidator.PubKey
validatorsPKs = append(validatorsPKs, pk)
appGenTx, _, _, err := kapp.KavaAppGenTxNF(cdc, pk, sdk.AccAddress(pk.Address()), "test_val1")
require.NoError(t, err)
appGenTxs = append(appGenTxs, appGenTx)
}
genesisState, err := kapp.KavaAppGenState(cdc, appGenTxs[:])
require.NoError(t, err)
// add some tokens to init accounts
for _, addr := range initAddrs {
accAuth := auth.NewBaseAccountWithAddress(addr)
accAuth.Coins = sdk.Coins{sdk.NewInt64Coin("KVA", 100)}
acc := kapp.NewGenesisAccount(&accAuth)
genesisState.Accounts = append(genesisState.Accounts, acc)
genesisState.StakeData.Pool.LooseTokens = genesisState.StakeData.Pool.LooseTokens.Add(sdk.NewRat(100))
}
appState, err := wire.MarshalJSONIndent(cdc, genesisState)
require.NoError(t, err)
genDoc.AppState = appState
listenAddr, port, err := server.FreeTCPAddr()
require.NoError(t, err)
// XXX: Need to set this so LCD knows the tendermint node address!
viper.Set(client.FlagNode, config.RPC.ListenAddress)
viper.Set(client.FlagChainID, genDoc.ChainID)
node, err := startTM(config, logger, genDoc, privVal, app)
require.NoError(t, err)
lcd, err := startLCD(logger, listenAddr, cdc)
require.NoError(t, err)
tests.WaitForLCDStart(port)
tests.WaitForHeight(1, port)
cleanup := func() {
logger.Debug("cleaning up LCD initialization")
node.Stop()
node.Wait()
lcd.Close()
}
return cleanup, validatorsPKs, port
}
// startTM creates and starts an in-process Tendermint node with memDB and
// in-process ABCI application. It returns the new node or any error that
// occurred.
//
// TODO: Clean up the WAL dir or enable it to be not persistent!
func startTM(
tmcfg *tmcfg.Config, logger log.Logger, genDoc *tmtypes.GenesisDoc,
privVal tmtypes.PrivValidator, app abci.Application,
) (*nm.Node, error) {
genDocProvider := func() (*tmtypes.GenesisDoc, error) { return genDoc, nil }
dbProvider := func(*nm.DBContext) (dbm.DB, error) { return dbm.NewMemDB(), nil }
node, err := nm.NewNode(
tmcfg,
privVal,
proxy.NewLocalClientCreator(app),
genDocProvider,
dbProvider,
nm.DefaultMetricsProvider(tmcfg.Instrumentation),
logger.With("module", "node"),
)
if err != nil {
return nil, err
}
err = node.Start()
if err != nil {
return nil, err
}
tests.WaitForRPC(tmcfg.RPC.ListenAddress)
logger.Info("Tendermint running!")
return node, err
}
// startLCD starts the LCD.
//
// NOTE: This causes the thread to block.
func startLCD(logger log.Logger, listenAddr string, cdc *wire.Codec) (net.Listener, error) {
return tmrpc.StartHTTPServer(listenAddr, createHandler(cdc), logger, tmrpc.Config{})
}
// Request makes a test LCD test request. It returns a response object and a
// stringified response body.
func Request(t *testing.T, port, method, path string, payload []byte) (*http.Response, string) {
var (
err error
res *http.Response
)
url := fmt.Sprintf("http://localhost:%v%v", port, path)
fmt.Println("REQUEST " + method + " " + url)
req, err := http.NewRequest(method, url, bytes.NewBuffer(payload))
require.Nil(t, err)
res, err = http.DefaultClient.Do(req)
require.Nil(t, err)
output, err := ioutil.ReadAll(res.Body)
res.Body.Close()
require.Nil(t, err)
return res, string(output)
}

32
internal/lcd/version.go Normal file
View File

@ -0,0 +1,32 @@
// Copyright 2016 All in Bits, inc
// Modifications copyright 2018 Kava Labs
package lcd
import (
"fmt"
"net/http"
"github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/version"
)
// cli version REST handler endpoint
func CLIVersionRequestHandler(w http.ResponseWriter, r *http.Request) {
v := version.GetVersion()
w.Write([]byte(v))
}
// connected node version REST handler endpoint
func NodeVersionRequestHandler(cliCtx context.CLIContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
version, err := cliCtx.Query("/app/version")
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(fmt.Sprintf("Could't query version. Error: %s", err.Error())))
return
}
w.Write(version)
}
}

View File

@ -1,11 +1,12 @@
// Copyright 2016 All in Bits, inc
// Modifications copyright 2018 Kava Labs
package lcd package lcd
/*
import ( import (
amino "github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
ctypes "github.com/tendermint/tendermint/rpc/core/types" ctypes "github.com/tendermint/tendermint/rpc/core/types"
) )
*/
var cdc = amino.NewCodec() var cdc = amino.NewCodec()

View File

@ -3,6 +3,7 @@ package cli
import ( import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"os"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -10,9 +11,11 @@ import (
"github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/client/keys" "github.com/cosmos/cosmos-sdk/client/keys"
"github.com/cosmos/cosmos-sdk/client/utils"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/wire" "github.com/cosmos/cosmos-sdk/wire"
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli" authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
authctx "github.com/cosmos/cosmos-sdk/x/auth/client/context"
"github.com/kava-labs/kava/internal/x/paychan" "github.com/kava-labs/kava/internal/x/paychan"
) )
@ -31,13 +34,15 @@ func CreateChannelCmd(cdc *wire.Codec) *cobra.Command {
Args: cobra.NoArgs, Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
// Create a "client context" stuct populated with info from common flags // Create a tx and cli "contexts": structs populated with info from common flags.
ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) txCtx := authctx.NewTxContextFromCLI().WithCodec(cdc)
// TODO is this needed for channelID cliCtx := context.NewCLIContext().
// ctx.PrintResponse = true WithCodec(cdc).
WithLogger(os.Stdout).
WithAccountDecoder(authcmd.GetAccountDecoder(cdc))
// Get sender adress // Get sender address
sender, err := ctx.GetFromAddress() sender, err := cliCtx.GetFromAddress()
if err != nil { if err != nil {
return err return err
} }
@ -67,11 +72,7 @@ func CreateChannelCmd(cdc *wire.Codec) *cobra.Command {
} }
// Build and sign the transaction, then broadcast to the blockchain // Build and sign the transaction, then broadcast to the blockchain
err = ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, []sdk.Msg{msg}, cdc) return utils.SendTx(txCtx, cliCtx, []sdk.Msg{msg})
if err != nil {
return err
}
return nil
}, },
} }
cmd.Flags().String(flagTo, "", "Recipient address of the payment channel.") cmd.Flags().String(flagTo, "", "Recipient address of the payment channel.")
@ -92,8 +93,11 @@ func GeneratePaymentCmd(cdc *wire.Codec) *cobra.Command {
Args: cobra.NoArgs, Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
// Create a "client context" stuct populated with info from common flags // Create a cli "context": struct populated with info from common flags.
ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) cliCtx := context.NewCLIContext().
WithCodec(cdc).
WithLogger(os.Stdout).
WithAccountDecoder(authcmd.GetAccountDecoder(cdc))
// Get the paychan id // Get the paychan id
id := paychan.ChannelID(viper.GetInt64(flagId)) // TODO make this default to pulling id from chain id := paychan.ChannelID(viper.GetInt64(flagId)) // TODO make this default to pulling id from chain
@ -121,8 +125,8 @@ func GeneratePaymentCmd(cdc *wire.Codec) *cobra.Command {
if err != nil { if err != nil {
return err return err
} }
name := ctx.FromAddressName name := cliCtx.FromAddressName
passphrase, err := ctx.GetPassphraseFromStdin(name) passphrase, err := keys.GetPassphrase(cliCtx.FromAddressName)
if err != nil { if err != nil {
return err return err
} }
@ -169,8 +173,11 @@ func VerifyPaymentCmd(cdc *wire.Codec, paychanStoreName string) *cobra.Command {
Args: cobra.NoArgs, Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
// Create a "client context" stuct populated with info from common flags // Create a cli "context": struct populated with info from common flags.
ctx := context.NewCoreContextFromViper() cliCtx := context.NewCLIContext().
WithCodec(cdc).
WithLogger(os.Stdout).
WithAccountDecoder(authcmd.GetAccountDecoder(cdc))
// read in update // read in update
bz, err := ioutil.ReadFile(viper.GetString(flagPaymentFile)) bz, err := ioutil.ReadFile(viper.GetString(flagPaymentFile))
@ -183,7 +190,7 @@ func VerifyPaymentCmd(cdc *wire.Codec, paychanStoreName string) *cobra.Command {
cdc.UnmarshalJSON(bz, &update) cdc.UnmarshalJSON(bz, &update)
// get the channel from the node // get the channel from the node
res, err := ctx.QueryStore(paychan.GetChannelKey(update.ChannelID), paychanStoreName) res, err := cliCtx.QueryStore(paychan.GetChannelKey(update.ChannelID), paychanStoreName)
if len(res) == 0 || err != nil { if len(res) == 0 || err != nil {
return errors.Errorf("channel with ID '%d' does not exist", update.ChannelID) return errors.Errorf("channel with ID '%d' does not exist", update.ChannelID)
} }
@ -218,12 +225,15 @@ func SubmitPaymentCmd(cdc *wire.Codec) *cobra.Command {
Args: cobra.NoArgs, Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
// Create a "client context" stuct populated with info from common flags // Create a tx and cli "contexts": structs populated with info from common flags.
ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc)) txCtx := authctx.NewTxContextFromCLI().WithCodec(cdc)
// ctx.PrintResponse = true TODO is this needed for channelID cliCtx := context.NewCLIContext().
WithCodec(cdc).
WithLogger(os.Stdout).
WithAccountDecoder(authcmd.GetAccountDecoder(cdc))
// Get sender adress // Get sender address
submitter, err := ctx.GetFromAddress() submitter, err := cliCtx.GetFromAddress()
if err != nil { if err != nil {
return err return err
} }
@ -248,11 +258,7 @@ func SubmitPaymentCmd(cdc *wire.Codec) *cobra.Command {
} }
// Build and sign the transaction, then broadcast to the blockchain // Build and sign the transaction, then broadcast to the blockchain
err = ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, []sdk.Msg{msg}, cdc) return utils.SendTx(txCtx, cliCtx, []sdk.Msg{msg})
if err != nil {
return err
}
return nil
}, },
} }
cmd.Flags().String(flagPaymentFile, "payment.json", "File to read the payment from.") cmd.Flags().String(flagPaymentFile, "payment.json", "File to read the payment from.")
@ -268,14 +274,17 @@ func GetChannelCmd(cdc *wire.Codec, paychanStoreName string) *cobra.Command {
Args: cobra.NoArgs, Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
// Create a "client context" stuct populated with info from common flags // Create a cli "context": struct populated with info from common flags.
ctx := context.NewCoreContextFromViper() cliCtx := context.NewCLIContext().
WithCodec(cdc).
WithLogger(os.Stdout).
WithAccountDecoder(authcmd.GetAccountDecoder(cdc))
// Get channel ID // Get channel ID
id := paychan.ChannelID(viper.GetInt64(flagId)) id := paychan.ChannelID(viper.GetInt64(flagId))
// Get the channel from the node // Get the channel from the node
res, err := ctx.QueryStore(paychan.GetChannelKey(id), paychanStoreName) res, err := cliCtx.QueryStore(paychan.GetChannelKey(id), paychanStoreName)
if len(res) == 0 || err != nil { if len(res) == 0 || err != nil {
return errors.Errorf("channel with ID '%d' does not exist", id) return errors.Errorf("channel with ID '%d' does not exist", id)
} }
@ -291,11 +300,11 @@ func GetChannelCmd(cdc *wire.Codec, paychanStoreName string) *cobra.Command {
fmt.Println(string(jsonChannel)) fmt.Println(string(jsonChannel))
// Get any submitted updates from the node // Get any submitted updates from the node
res, err = ctx.QueryStore(paychan.GetSubmittedUpdateKey(id), paychanStoreName) res, err = cliCtx.QueryStore(paychan.GetSubmittedUpdateKey(id), paychanStoreName)
if err != nil { if err != nil {
return err return err
} }
// Print out the submited update if it exsits // Print out the submitted update if it exists
if len(res) != 0 { if len(res) != 0 {
var submittedUpdate paychan.SubmittedUpdate var submittedUpdate paychan.SubmittedUpdate
cdc.MustUnmarshalBinary(res, &submittedUpdate) cdc.MustUnmarshalBinary(res, &submittedUpdate)

View File

@ -1,9 +1,10 @@
package paychan package paychan
import ( import (
"testing"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"testing"
) )
func TestEndBlocker(t *testing.T) { func TestEndBlocker(t *testing.T) {
@ -14,7 +15,7 @@ func TestEndBlocker(t *testing.T) {
ctx, _, channelKeeper, addrs, _, _, _ := createMockApp(accountSeeds) ctx, _, channelKeeper, addrs, _, _, _ := createMockApp(accountSeeds)
sender := addrs[0] sender := addrs[0]
receiver := addrs[1] receiver := addrs[1]
coins := sdk.Coins{sdk.NewCoin("KVA", 10)} coins := sdk.Coins{sdk.NewInt64Coin("KVA", 10)}
// create new channel // create new channel
channelID := ChannelID(0) // should be 0 as first channel channelID := ChannelID(0) // should be 0 as first channel
@ -26,11 +27,10 @@ func TestEndBlocker(t *testing.T) {
channelKeeper.setChannel(ctx, channel) channelKeeper.setChannel(ctx, channel)
// create closing update and submittedUpdate // create closing update and submittedUpdate
payout := Payout{sdk.Coins{sdk.NewCoin("KVA", 3)}, sdk.Coins{sdk.NewCoin("KVA", 7)}} payout := Payout{sdk.Coins{sdk.NewInt64Coin("KVA", 3)}, sdk.Coins{sdk.NewInt64Coin("KVA", 7)}}
update := Update{ update := Update{
ChannelID: channelID, ChannelID: channelID,
Payout: payout, Payout: payout,
//Sigs: [1]crypto.Signature{},
} }
sUpdate := SubmittedUpdate{ sUpdate := SubmittedUpdate{
Update: update, Update: update,

View File

@ -30,7 +30,7 @@ func TestKeeper(t *testing.T) {
"HappyPath", "HappyPath",
addrs[senderAccountIndex], addrs[senderAccountIndex],
addrs[receiverAccountIndex], addrs[receiverAccountIndex],
sdk.Coins{sdk.NewCoin("KVA", 10)}, sdk.Coins{sdk.NewInt64Coin("KVA", 10)},
true, true,
false, false,
}, },
@ -38,7 +38,7 @@ func TestKeeper(t *testing.T) {
"NilAddress", "NilAddress",
sdk.AccAddress{}, sdk.AccAddress{},
sdk.AccAddress{}, sdk.AccAddress{},
sdk.Coins{sdk.NewCoin("KVA", 10)}, sdk.Coins{sdk.NewInt64Coin("KVA", 10)},
false, false,
true, true,
}, },
@ -54,7 +54,7 @@ func TestKeeper(t *testing.T) {
"NegativeCoins", "NegativeCoins",
addrs[senderAccountIndex], addrs[senderAccountIndex],
addrs[receiverAccountIndex], addrs[receiverAccountIndex],
sdk.Coins{sdk.NewCoin("KVA", -57)}, sdk.Coins{sdk.NewInt64Coin("KVA", -57)},
false, false,
true, true,
}, },
@ -126,7 +126,7 @@ func TestKeeper(t *testing.T) {
) )
ctx, coinKeeper, channelKeeper, addrs, pubKeys, privKeys, genAccFunding := createMockApp(accountSeeds) ctx, coinKeeper, channelKeeper, addrs, pubKeys, privKeys, genAccFunding := createMockApp(accountSeeds)
coins := sdk.Coins{sdk.NewCoin("KVA", 10)} coins := sdk.Coins{sdk.NewInt64Coin("KVA", 10)}
// create new channel // create new channel
channelID := ChannelID(0) // should be 0 as first channel channelID := ChannelID(0) // should be 0 as first channel
@ -138,7 +138,7 @@ func TestKeeper(t *testing.T) {
channelKeeper.setChannel(ctx, channel) channelKeeper.setChannel(ctx, channel)
// create closing update // create closing update
payout := Payout{sdk.Coins{sdk.NewCoin("KVA", 3)}, sdk.Coins{sdk.NewCoin("KVA", 7)}} payout := Payout{sdk.Coins{sdk.NewInt64Coin("KVA", 3)}, sdk.Coins{sdk.NewInt64Coin("KVA", 7)}}
update := Update{ update := Update{
ChannelID: channelID, ChannelID: channelID,
Payout: payout, Payout: payout,
@ -200,14 +200,14 @@ func TestKeeper(t *testing.T) {
{ {
"HappyPath", "HappyPath",
true, true,
testUpdate{chanID, Payout{sdk.Coins{sdk.NewCoin("KVA", 3)}, sdk.Coins{sdk.NewCoin("KVA", 7)}}, senderAccountIndex, senderAccountIndex}, testUpdate{chanID, Payout{sdk.Coins{sdk.NewInt64Coin("KVA", 3)}, sdk.Coins{sdk.NewInt64Coin("KVA", 7)}}, senderAccountIndex, senderAccountIndex},
"sameAsSubmited", "sameAsSubmited",
false, false,
}, },
{ {
"NoChannel", "NoChannel",
false, false,
testUpdate{chanID, Payout{sdk.Coins{sdk.NewCoin("KVA", 3)}, sdk.Coins{sdk.NewCoin("KVA", 7)}}, senderAccountIndex, senderAccountIndex}, testUpdate{chanID, Payout{sdk.Coins{sdk.NewInt64Coin("KVA", 3)}, sdk.Coins{sdk.NewInt64Coin("KVA", 7)}}, senderAccountIndex, senderAccountIndex},
"empty", "empty",
true, true,
}, },
@ -221,35 +221,35 @@ func TestKeeper(t *testing.T) {
{ {
"NegativeCoins", "NegativeCoins",
true, true,
testUpdate{chanID, Payout{sdk.Coins{sdk.NewCoin("KVA", -5)}, sdk.Coins{sdk.NewCoin("KVA", 15)}}, senderAccountIndex, senderAccountIndex}, testUpdate{chanID, Payout{sdk.Coins{sdk.NewInt64Coin("KVA", -5)}, sdk.Coins{sdk.NewInt64Coin("KVA", 15)}}, senderAccountIndex, senderAccountIndex},
"empty", "empty",
true, true,
}, },
{ {
"TooManyCoins", "TooManyCoins",
true, true,
testUpdate{chanID, Payout{sdk.Coins{sdk.NewCoin("KVA", 100)}, sdk.Coins{sdk.NewCoin("KVA", 7)}}, senderAccountIndex, senderAccountIndex}, testUpdate{chanID, Payout{sdk.Coins{sdk.NewInt64Coin("KVA", 100)}, sdk.Coins{sdk.NewInt64Coin("KVA", 7)}}, senderAccountIndex, senderAccountIndex},
"empty", "empty",
true, true,
}, },
{ {
"WrongSignature", "WrongSignature",
true, true,
testUpdate{chanID, Payout{sdk.Coins{sdk.NewCoin("KVA", 3)}, sdk.Coins{sdk.NewCoin("KVA", 7)}}, senderAccountIndex, otherAccountIndex}, testUpdate{chanID, Payout{sdk.Coins{sdk.NewInt64Coin("KVA", 3)}, sdk.Coins{sdk.NewInt64Coin("KVA", 7)}}, senderAccountIndex, otherAccountIndex},
"empty", "empty",
true, true,
}, },
{ {
"WrongPubKey", "WrongPubKey",
true, true,
testUpdate{chanID, Payout{sdk.Coins{sdk.NewCoin("KVA", 3)}, sdk.Coins{sdk.NewCoin("KVA", 7)}}, otherAccountIndex, senderAccountIndex}, testUpdate{chanID, Payout{sdk.Coins{sdk.NewInt64Coin("KVA", 3)}, sdk.Coins{sdk.NewInt64Coin("KVA", 7)}}, otherAccountIndex, senderAccountIndex},
"empty", "empty",
true, true,
}, },
{ {
"ReceiverSigned", "ReceiverSigned",
true, true,
testUpdate{chanID, Payout{sdk.Coins{sdk.NewCoin("KVA", 3)}, sdk.Coins{sdk.NewCoin("KVA", 7)}}, receiverAccountIndex, receiverAccountIndex}, testUpdate{chanID, Payout{sdk.Coins{sdk.NewInt64Coin("KVA", 3)}, sdk.Coins{sdk.NewInt64Coin("KVA", 7)}}, receiverAccountIndex, receiverAccountIndex},
"empty", "empty",
true, true,
}, },
@ -266,7 +266,7 @@ func TestKeeper(t *testing.T) {
channel := Channel{ channel := Channel{
ID: chanID, // should be 0 as first channel ID: chanID, // should be 0 as first channel
Participants: [2]sdk.AccAddress{addrs[senderAccountIndex], addrs[receiverAccountIndex]}, Participants: [2]sdk.AccAddress{addrs[senderAccountIndex], addrs[receiverAccountIndex]},
Coins: sdk.Coins{sdk.NewCoin("KVA", 10)}, Coins: sdk.Coins{sdk.NewInt64Coin("KVA", 10)},
} }
channelKeeper.setChannel(ctx, channel) channelKeeper.setChannel(ctx, channel)
} }

View File

@ -27,7 +27,7 @@ func createMockApp(accountSeeds []string) (sdk.Context, bank.Keeper, Keeper, []s
mApp.CompleteSetup([]*sdk.KVStoreKey{keyChannel}) mApp.CompleteSetup([]*sdk.KVStoreKey{keyChannel})
// create some accounts // create some accounts
genAccFunding := sdk.Coins{sdk.NewCoin("KVA", 1000)} genAccFunding := sdk.Coins{sdk.NewInt64Coin("KVA", 1000)}
genAccs, addrs, pubKeys, privKeys := createTestGenAccounts(accountSeeds, genAccFunding) genAccs, addrs, pubKeys, privKeys := createTestGenAccounts(accountSeeds, genAccFunding)
// initialize the app with these accounts // initialize the app with these accounts

View File

@ -61,7 +61,7 @@ func (p Payout) Sum() sdk.Coins {
type UpdateSignature struct { type UpdateSignature struct {
PubKey crypto.PubKey PubKey crypto.PubKey
CryptoSignature crypto.Signature CryptoSignature []byte
} }
// An update that has been submitted to the blockchain, but not yet acted on. // An update that has been submitted to the blockchain, but not yet acted on.

View File

@ -28,18 +28,18 @@ func TestSubmittedUpdatesQueue(t *testing.T) {
func TestPayout(t *testing.T) { func TestPayout(t *testing.T) {
t.Run("IsNotNegative", func(t *testing.T) { t.Run("IsNotNegative", func(t *testing.T) {
p := Payout{sdk.Coins{sdk.NewCoin("USD", 4), sdk.NewCoin("GBP", 0)}, sdk.Coins{sdk.NewCoin("USD", 129879234), sdk.NewCoin("GBP", 1)}} p := Payout{sdk.Coins{sdk.NewInt64Coin("USD", 4), sdk.NewInt64Coin("GBP", 0)}, sdk.Coins{sdk.NewInt64Coin("USD", 129879234), sdk.NewInt64Coin("GBP", 1)}}
assert.True(t, p.IsNotNegative()) assert.True(t, p.IsNotNegative())
p = Payout{sdk.Coins{sdk.NewCoin("USD", -4), sdk.NewCoin("GBP", 0)}, sdk.Coins{sdk.NewCoin("USD", 129879234), sdk.NewCoin("GBP", 1)}} p = Payout{sdk.Coins{sdk.NewInt64Coin("USD", -4), sdk.NewInt64Coin("GBP", 0)}, sdk.Coins{sdk.NewInt64Coin("USD", 129879234), sdk.NewInt64Coin("GBP", 1)}}
assert.False(t, p.IsNotNegative()) assert.False(t, p.IsNotNegative())
}) })
t.Run("Sum", func(t *testing.T) { t.Run("Sum", func(t *testing.T) {
p := Payout{ p := Payout{
sdk.Coins{sdk.NewCoin("EUR", 1), sdk.NewCoin("USD", -5)}, sdk.Coins{sdk.NewInt64Coin("EUR", 1), sdk.NewInt64Coin("USD", -5)},
sdk.Coins{sdk.NewCoin("EUR", 1), sdk.NewCoin("USD", 100), sdk.NewCoin("GBP", 1)}, sdk.Coins{sdk.NewInt64Coin("EUR", 1), sdk.NewInt64Coin("USD", 100), sdk.NewInt64Coin("GBP", 1)},
} }
expected := sdk.Coins{sdk.NewCoin("EUR", 2), sdk.NewCoin("GBP", 1), sdk.NewCoin("USD", 95)} expected := sdk.Coins{sdk.NewInt64Coin("EUR", 2), sdk.NewInt64Coin("GBP", 1), sdk.NewInt64Coin("USD", 95)}
assert.Equal(t, expected, p.Sum()) assert.Equal(t, expected, p.Sum())
}) })
} }

View File

@ -0,0 +1,207 @@
# This is a TOML config file.
# For more information, see https://github.com/toml-lang/toml
##### main base config options #####
# TCP or UNIX socket address of the ABCI application,
# or the name of an ABCI application compiled in with the Tendermint binary
proxy_app = "tcp://127.0.0.1:17128"
# A custom human readable name for this node
moniker = ""
# If this node is many blocks behind the tip of the chain, FastSync
# allows them to catchup quickly by downloading blocks in parallel
# and verifying their commits
fast_sync = true
# Database backend: leveldb | memdb
db_backend = "leveldb"
# Database directory
db_path = "data"
# Output level for logging, including package level options
log_level = "main:info,state:info,*:error"
##### additional base config options #####
# Path to the JSON file containing the initial validator set and other meta data
genesis_file = "config/genesis.json"
# Path to the JSON file containing the private key to use as a validator in the consensus protocol
priv_validator_file = "config/priv_validator.json"
# Path to the JSON file containing the private key to use for node authentication in the p2p protocol
node_key_file = "config/node_key.json"
# Mechanism to connect to the ABCI application: socket | grpc
abci = "socket"
# TCP or UNIX socket address for the profiling server to listen on
prof_laddr = "localhost:6060"
# If true, query the ABCI app on connecting to a new peer
# so the app can decide if we should keep the connection or not
filter_peers = false
##### advanced configuration options #####
##### rpc server configuration options #####
[rpc]
# TCP or UNIX socket address for the RPC server to listen on
laddr = "tcp://0.0.0.0:17127"
# TCP or UNIX socket address for the gRPC server to listen on
# NOTE: This server only supports /broadcast_tx_commit
grpc_laddr = ""
# Maximum number of simultaneous connections.
# Does not include RPC (HTTP&WebSocket) connections. See max_open_connections
# If you want to accept more significant number than the default, make sure
# you increase your OS limits.
# 0 - unlimited.
grpc_max_open_connections = 900
# Activate unsafe RPC commands like /dial_seeds and /unsafe_flush_mempool
unsafe = false
# Maximum number of simultaneous connections (including WebSocket).
# Does not include gRPC connections. See grpc_max_open_connections
# If you want to accept more significant number than the default, make sure
# you increase your OS limits.
# 0 - unlimited.
max_open_connections = 900
##### peer to peer configuration options #####
[p2p]
# Address to listen for incoming connections
laddr = "tcp://0.0.0.0:17126"
# Address to advertise to peers for them to dial
# If empty, will use the same port as the laddr,
# and will introspect on the listener or use UPnP
# to figure out the address.
external_address = ""
# Comma separated list of seed nodes to connect to
seeds = "6b1f509f5152ca08606c299c01ae284389671d8d@kava-test-3.node.connector.kava.io:17126"
# Comma separated list of nodes to keep persistent connections to
persistent_peers = ""
# UPNP port forwarding
upnp = false
# Path to address book
addr_book_file = "config/addrbook.json"
# Set true for strict address routability rules
addr_book_strict = true
# Time to wait before flushing messages out on the connection, in ms
flush_throttle_timeout = 100
# Maximum number of peers to connect to
max_num_peers = 50
# Maximum size of a message packet payload, in bytes
max_packet_msg_payload_size = 1024
# Rate at which packets can be sent, in bytes/second
send_rate = 5120000
# Rate at which packets can be received, in bytes/second
recv_rate = 5120000
# Set true to enable the peer-exchange reactor
pex = true
# Seed mode, in which node constantly crawls the network and looks for
# peers. If another node asks it for addresses, it responds and disconnects.
#
# Does not work if the peer-exchange reactor is disabled.
seed_mode = false
# Comma separated list of peer IDs to keep private (will not be gossiped to other peers)
private_peer_ids = ""
##### mempool configuration options #####
[mempool]
recheck = true
recheck_empty = true
broadcast = true
wal_dir = "data/mempool.wal"
# size of the mempool
size = 100000
# size of the cache (used to filter transactions we saw earlier)
cache_size = 100000
##### consensus configuration options #####
[consensus]
wal_file = "data/cs.wal/wal"
# All timeouts are in milliseconds
timeout_propose = 3000
timeout_propose_delta = 500
timeout_prevote = 1000
timeout_prevote_delta = 500
timeout_precommit = 1000
timeout_precommit_delta = 500
timeout_commit = 5000
# Make progress as soon as we have all the precommits (as if TimeoutCommit = 0)
skip_timeout_commit = false
# EmptyBlocks mode and possible interval between empty blocks in seconds
create_empty_blocks = true
create_empty_blocks_interval = 0
# Reactor sleep duration parameters are in milliseconds
peer_gossip_sleep_duration = 100
peer_query_maj23_sleep_duration = 2000
##### transactions indexer configuration options #####
[tx_index]
# What indexer to use for transactions
#
# Options:
# 1) "null" (default)
# 2) "kv" - the simplest possible indexer, backed by key-value storage (defaults to levelDB; see DBBackend).
indexer = "kv"
# Comma-separated list of tags to index (by default the only tag is tx hash)
#
# It's recommended to index only a subset of tags due to possible memory
# bloat. This is, of course, depends on the indexer's DB and the volume of
# transactions.
index_tags = ""
# When set to true, tells indexer to index all tags. Note this may be not
# desirable (see the comment above). IndexTags has a precedence over
# IndexAllTags (i.e. when given both, IndexTags will be indexed).
index_all_tags = true
##### instrumentation configuration options #####
[instrumentation]
# When true, Prometheus metrics are served under /metrics on
# PrometheusListenAddr.
# Check out the documentation for the list of available metrics.
prometheus = false
# Address to listen for Prometheus collector(s) connections
prometheus_listen_addr = ":26660"
# Maximum number of simultaneous connections.
# If you want to accept more significant number than the default, make sure
# you increase your OS limits.
# 0 - unlimited.
max_open_connections = 3

View File

@ -0,0 +1,99 @@
{
"genesis_time": "2018-10-03T18:25:12.233785395Z",
"chain_id": "kava-test-3",
"consensus_params": {
"block_size_params": {
"max_bytes": "22020096",
"max_txs": "10000",
"max_gas": "-1"
},
"tx_size_params": {
"max_bytes": "10240",
"max_gas": "-1"
},
"block_gossip_params": {
"block_part_size_bytes": "65536"
},
"evidence_params": {
"max_age": "100000"
}
},
"validators": [
{
"pub_key": {
"type": "tendermint/PubKeyEd25519",
"value": "n+XBgHtHEJOQa9ufM1sj7Sacxo/W8lB3dJFmzlmmSrU="
},
"power": "1000",
"name": ""
}
],
"app_hash": "",
"app_state": {
"accounts": [
{
"address": "kaccaddr125e8mv0zyf0jflw4jfrz85skt7ren5terqpe8j",
"coins": [
{
"denom": "KVA",
"amount": "99000"
}
]
}
],
"stake": {
"pool": {
"loose_tokens": "100000",
"bonded_tokens": "0",
"inflation_last_time": "1970-01-01T00:00:00Z",
"inflation": "7/100",
"date_last_commission_reset": "0",
"prev_bonded_shares": "0"
},
"params": {
"inflation_rate_change": "13/100",
"inflation_max": "1/5",
"inflation_min": "7/100",
"goal_bonded": "67/100",
"unbonding_time": "300000000000",
"max_validators": 100,
"bond_denom": "KVA"
},
"validators": [
{
"owner": "kaccaddr125e8mv0zyf0jflw4jfrz85skt7ren5terqpe8j",
"pub_key": {
"type": "tendermint/PubKeyEd25519",
"value": "n+XBgHtHEJOQa9ufM1sj7Sacxo/W8lB3dJFmzlmmSrU="
},
"revoked": false,
"status": 0,
"tokens": "1000",
"delegator_shares": "1000",
"description": {
"moniker": "kava-validator",
"identity": "",
"website": "",
"details": ""
},
"bond_height": "0",
"bond_intra_tx_counter": 0,
"proposer_reward_pool": [],
"commission": "0",
"commission_max": "0",
"commission_change_rate": "0",
"commission_change_today": "0",
"prev_bonded_tokens": "0"
}
],
"bonds": [
{
"delegator_addr": "kaccaddr125e8mv0zyf0jflw4jfrz85skt7ren5terqpe8j",
"validator_addr": "kaccaddr125e8mv0zyf0jflw4jfrz85skt7ren5terqpe8j",
"shares": "1000",
"height": "0"
}
]
}
}
}