mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-26 00:05:18 +00:00
commit
2a73328a0f
106
Gopkg.lock
generated
106
Gopkg.lock
generated
@ -2,7 +2,6 @@
|
||||
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:09a7f74eb6bb3c0f14d8926610c87f569c5cff68e978d30e9a3540aeb626fdf0"
|
||||
name = "github.com/bartekn/go-bip39"
|
||||
packages = ["."]
|
||||
@ -49,7 +48,8 @@
|
||||
revision = "d4cc87b860166d00d6b5b9e0d3b3d71d6088d4d4"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:bb617355120eed649354b41a20d1745b2feb994e4da1a97591259143ad65375a"
|
||||
branch = "master"
|
||||
digest = "1:64eb47e3881f808c83f0a3015f626d21ccc4a4eafbc530a6454e97296ededbef"
|
||||
name = "github.com/cosmos/cosmos-sdk"
|
||||
packages = [
|
||||
"baseapp",
|
||||
@ -58,6 +58,7 @@
|
||||
"client/keys",
|
||||
"client/rpc",
|
||||
"client/tx",
|
||||
"client/utils",
|
||||
"crypto",
|
||||
"crypto/keys",
|
||||
"crypto/keys/bcrypt",
|
||||
@ -66,28 +67,33 @@
|
||||
"server",
|
||||
"server/config",
|
||||
"store",
|
||||
"tests",
|
||||
"types",
|
||||
"version",
|
||||
"wire",
|
||||
"x/auth",
|
||||
"x/auth/client/cli",
|
||||
"x/auth/client/context",
|
||||
"x/auth/client/rest",
|
||||
"x/bank",
|
||||
"x/bank/client",
|
||||
"x/bank/client/cli",
|
||||
"x/gov",
|
||||
"x/ibc",
|
||||
"x/bank/client/rest",
|
||||
"x/mock",
|
||||
"x/params",
|
||||
"x/slashing",
|
||||
"x/slashing/client/cli",
|
||||
"x/slashing/client/rest",
|
||||
"x/stake",
|
||||
"x/stake/client/cli",
|
||||
"x/stake/client/rest",
|
||||
"x/stake/keeper",
|
||||
"x/stake/tags",
|
||||
"x/stake/types",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "23e3d5ac12145c02fcb4b4767d7dfccad782aee5"
|
||||
version = "v0.23.1"
|
||||
revision = "4a54b3ddbde412bea07250680a09fa6cbf1c3824"
|
||||
source = "github.com/kava-labs/cosmos-sdk"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:a2c1d0e43bd3baaa071d1b9ed72c27d78169b2b269f71c105ac4ba34b1be4a39"
|
||||
@ -437,14 +443,6 @@
|
||||
pruneopts = "UT"
|
||||
revision = "c4c61651e9e37fa117f53c5a906d3b63090d8445"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:8b7ca9e3745cb049a65364d3adbbab63e98d3c43c83cb101cb450c8dac3c3492"
|
||||
name = "github.com/tendermint/abci"
|
||||
packages = ["types"]
|
||||
pruneopts = "UT"
|
||||
revision = "68592f4d8ee34e97db94b7a7976b1309efdb7eb9"
|
||||
version = "v0.10.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:087aaa7920e5d0bf79586feb57ce01c35c830396ab4392798112e8aae8c47722"
|
||||
@ -458,23 +456,12 @@
|
||||
revision = "d8387025d2b9d158cf4efb07e7ebf814bcce2057"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:e9113641c839c21d8eaeb2c907c7276af1eddeed988df8322168c56b7e06e0e1"
|
||||
digest = "1:e0a2a4be1e20c305badc2b0a7a9ab7fef6da500763bec23ab81df3b5f9eec9ee"
|
||||
name = "github.com/tendermint/go-amino"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "2106ca61d91029c931fd54968c2bb02dc96b1412"
|
||||
version = "0.10.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:82f70bfe58f1a55601d469b928aec5b10b1d85710e6adde40dfea8d9adba939d"
|
||||
name = "github.com/tendermint/go-crypto"
|
||||
packages = [
|
||||
".",
|
||||
"tmhash",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "6a6b591a3d7592a04b46af95451cb5be3b114f76"
|
||||
version = "v0.9.0"
|
||||
revision = "a8328986c1608950fa5d3d1c0472cccc4f8fc02c"
|
||||
version = "v0.12.0-rc0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:d4a15d404afbf591e8be16fcda7f5ac87948d5c7531f9d909fd84cc730ab16e2"
|
||||
@ -485,7 +472,7 @@
|
||||
version = "v0.9.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:eb0f8bee357e6c28c9ad5fa074545b5085d0dcf580ba0e7024ab8c3285a5c815"
|
||||
digest = "1:4f15e95fe3888cc75dd34f407d6394cbc7fd3ff24920851b92b295f6a8b556e6"
|
||||
name = "github.com/tendermint/tendermint"
|
||||
packages = [
|
||||
"abci/client",
|
||||
@ -548,35 +535,26 @@
|
||||
"version",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "d542d2c3945116697f60451e6a407082c41c3cc9"
|
||||
version = "v0.22.8"
|
||||
revision = "81df19e68ab1519399fccf0cab81cb75bf9d782e"
|
||||
version = "v0.23.1-rc0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:68921ddf468c0db04496dc49cc67948f1727a74520b1f1f06100bce5c65fa08b"
|
||||
name = "github.com/tendermint/tmlibs"
|
||||
packages = [
|
||||
"common",
|
||||
"db",
|
||||
"log",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "692f1d86a6e2c0efa698fd1e4541b68c74ffaf38"
|
||||
version = "v0.8.4"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:5bd938386bd1f61a581bf8cd6ff2b7b2f79c542929176db4ceb44965440dae07"
|
||||
digest = "1:4dcb0dd65feecb068ce23a234d1a07c7868a1e39f52a6defcae0bb371d03abf6"
|
||||
name = "github.com/zondax/ledger-goclient"
|
||||
packages = ["."]
|
||||
pruneopts = "UT"
|
||||
revision = "39ba4728c137c75718a21f9b4b3280fa31b9139b"
|
||||
revision = "4296ee5701e945f9b3a7dbe51f402e0b9be57259"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:65a21a9e051d54eb6a3f70c659a765f706a998d9287c302269f4ed8054b2a852"
|
||||
digest = "1:7a71fffde456d746c52f9cd09c50b034533a3180fb1f6320abb149f2ccc579e5"
|
||||
name = "golang.org/x/crypto"
|
||||
packages = [
|
||||
"blowfish",
|
||||
"chacha20poly1305",
|
||||
"curve25519",
|
||||
"hkdf",
|
||||
"internal/chacha20",
|
||||
"internal/subtle",
|
||||
"nacl/box",
|
||||
"nacl/secretbox",
|
||||
@ -608,9 +586,12 @@
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:0316a8ad208917f1d141b077e278980fd5e4594f3a85f835dacbf24d85798252"
|
||||
digest = "1:4bd75b1a219bc590b05c976bbebf47f4e993314ebb5c7cbf2efe05a09a184d54"
|
||||
name = "golang.org/x/sys"
|
||||
packages = ["unix"]
|
||||
packages = [
|
||||
"cpu",
|
||||
"unix",
|
||||
]
|
||||
pruneopts = "UT"
|
||||
revision = "4e1fef5609515ec7a2cee7b5de30ba6d9b438cbf"
|
||||
|
||||
@ -693,40 +674,57 @@
|
||||
input-imports = [
|
||||
"github.com/cosmos/cosmos-sdk/baseapp",
|
||||
"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/rpc",
|
||||
"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/config",
|
||||
"github.com/cosmos/cosmos-sdk/tests",
|
||||
"github.com/cosmos/cosmos-sdk/types",
|
||||
"github.com/cosmos/cosmos-sdk/version",
|
||||
"github.com/cosmos/cosmos-sdk/wire",
|
||||
"github.com/cosmos/cosmos-sdk/x/auth",
|
||||
"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/client/cli",
|
||||
"github.com/cosmos/cosmos-sdk/x/gov",
|
||||
"github.com/cosmos/cosmos-sdk/x/ibc",
|
||||
"github.com/cosmos/cosmos-sdk/x/bank/client/rest",
|
||||
"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/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/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/pflag",
|
||||
"github.com/spf13/viper",
|
||||
"github.com/stretchr/testify/assert",
|
||||
"github.com/stretchr/testify/require",
|
||||
"github.com/tendermint/abci/types",
|
||||
"github.com/tendermint/go-crypto",
|
||||
"github.com/tendermint/go-amino",
|
||||
"github.com/tendermint/tendermint/abci/types",
|
||||
"github.com/tendermint/tendermint/config",
|
||||
"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/common",
|
||||
"github.com/tendermint/tendermint/libs/db",
|
||||
"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/tmlibs/db",
|
||||
"github.com/tendermint/tmlibs/log",
|
||||
]
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
|
12
Gopkg.toml
12
Gopkg.toml
@ -1,6 +1,7 @@
|
||||
[[constraint]]
|
||||
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
|
||||
@ -35,7 +36,7 @@
|
||||
|
||||
[[override]]
|
||||
name = "github.com/tendermint/go-amino"
|
||||
version = "=0.10.1"
|
||||
version = "=v0.12.0-rc0"
|
||||
|
||||
[[override]]
|
||||
name = "github.com/tendermint/iavl"
|
||||
@ -43,16 +44,17 @@
|
||||
|
||||
[[override]]
|
||||
name = "github.com/tendermint/tendermint"
|
||||
version = "=v0.22.8"
|
||||
version = "=v0.23.1-rc0"
|
||||
|
||||
[[override]]
|
||||
name = "github.com/bartekn/go-bip39"
|
||||
branch = "master"
|
||||
revision = "a05967ea095d81c8fe4833776774cfaff8e5036c"
|
||||
|
||||
[[override]]
|
||||
name = "github.com/zondax/ledger-goclient"
|
||||
revision = "39ba4728c137c75718a21f9b4b3280fa31b9139b"
|
||||
revision = "4296ee5701e945f9b3a7dbe51f402e0b9be57259"
|
||||
|
||||
[prune]
|
||||
go-tests = true
|
||||
unused-packages = true
|
||||
|
@ -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).
|
||||
|
||||
# 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)
|
||||
[![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
|
||||
|
||||
- [Installation and Setup](docs/setup.md)
|
||||
- [Upgrading to a New Testnet](docs/upgrade.md)
|
||||
- [Basic Usage](docs/usage.md)
|
||||
- [Payment Channels](docs/paychans.md)
|
||||
|
||||
|
@ -16,14 +16,13 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/version"
|
||||
authcmd "github.com/cosmos/cosmos-sdk/x/auth/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"
|
||||
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/lcd"
|
||||
"github.com/kava-labs/kava/internal/lcd"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -53,17 +52,6 @@ func main() {
|
||||
)
|
||||
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{
|
||||
Use: "advanced",
|
||||
Short: "Advanced subcommands",
|
||||
@ -71,8 +59,7 @@ func main() {
|
||||
|
||||
advancedCmd.AddCommand(
|
||||
tendermintCmd,
|
||||
//ibcCmd,
|
||||
//lcd.ServeCommand(cdc),
|
||||
lcd.ServeCommand(cdc),
|
||||
)
|
||||
rootCmd.AddCommand(
|
||||
advancedCmd,
|
||||
@ -90,6 +77,10 @@ func main() {
|
||||
stakecmd.GetCmdQueryValidators("stake", cdc),
|
||||
stakecmd.GetCmdQueryDelegation("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),
|
||||
)...)
|
||||
stakeCmd.AddCommand(
|
||||
@ -105,27 +96,6 @@ func main() {
|
||||
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
|
||||
rootCmd.AddCommand(
|
||||
client.GetCommands(
|
||||
|
135
cmd/kvd/main.go
135
cmd/kvd/main.go
@ -5,7 +5,12 @@ package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
|
||||
@ -44,6 +49,9 @@ func main() {
|
||||
|
||||
server.AddCommands(ctx, cdc, rootCmd, appInit, appCreator, appExporter)
|
||||
|
||||
// Add custom init command
|
||||
rootCmd.AddCommand(initTestnetCmd())
|
||||
|
||||
// handle envs and add some flags and stuff
|
||||
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)
|
||||
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
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ services:
|
||||
image: kava/kava
|
||||
command: ["kvd", "start"]
|
||||
ports:
|
||||
- 26657:26657
|
||||
- 17127:17127
|
||||
volumes:
|
||||
- ~/.kvd:/root/.kvd
|
||||
- ~/.kvcli:/root/.kvcli
|
||||
|
@ -10,12 +10,12 @@ This initial implementation is for unidirectional channels. Channels can be open
|
||||
|
||||
## 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 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.
|
||||
|
||||
@ -24,11 +24,11 @@ Send the file `payment.json` to your receiver. Then they run the following to ve
|
||||
## Close a channel
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
#### Who this guide is for
|
||||
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.
|
||||
|
||||
@ -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+).
|
||||
|
||||
0. If installing from a new Ubuntu server (16.04 or 18.04), here's how to setup go:
|
||||
|
||||
sudo apt update
|
||||
sudo apt upgrade -y
|
||||
sudo apt install git gcc make wget -y
|
||||
wget https://dl.google.com/go/go1.10.3.linux-amd64.tar.gz
|
||||
sudo tar -xvf go1.10.3.linux-amd64.tar.gz
|
||||
sudo mv go /usr/local
|
||||
|
||||
cat >> ~/.profile <<EOF
|
||||
export GOROOT=/usr/local/go
|
||||
export GOPATH=\$HOME/go
|
||||
export PATH=\$GOPATH/bin:\$GOROOT/bin:\$PATH
|
||||
EOF
|
||||
|
||||
source ~/.profile
|
||||
>If installing from a new Ubuntu server (16.04 or 18.04), here's how to setup go.
|
||||
>
|
||||
> sudo apt update
|
||||
> sudo apt upgrade -y
|
||||
> sudo apt install git gcc make wget -y
|
||||
> wget https://dl.google.com/go/go1.10.3.linux-amd64.tar.gz
|
||||
> sudo tar -xvf go1.10.3.linux-amd64.tar.gz
|
||||
> sudo mv go /usr/local
|
||||
>
|
||||
> cat >> ~/.profile <<EOF
|
||||
> export GOROOT=/usr/local/go
|
||||
> export GOPATH=\$HOME/go
|
||||
> export PATH=\$GOPATH/bin:\$GOROOT/bin:\$PATH
|
||||
> EOF
|
||||
>
|
||||
> source ~/.profile
|
||||
|
||||
1. Get the code.
|
||||
|
||||
@ -37,7 +37,6 @@ Requirements: go installed and set up (version 1.10+).
|
||||
cd $GOPATH/src/github.com/kava-labs
|
||||
git clone https://github.com/kava-labs/kava
|
||||
cd kava
|
||||
git checkout 8c9406c
|
||||
|
||||
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
|
||||
dep ensure -vendor-only
|
||||
|
||||
3. Install the code
|
||||
3. Install the code.
|
||||
|
||||
go install ./cmd/kvd
|
||||
go install ./cmd/kvcli
|
||||
|
||||
## 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.
|
||||
|
||||
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
|
||||
|
||||
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 &
|
||||
|
||||
To see the output of the log:
|
||||
To see the output of the 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
|
||||
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 \
|
||||
--amount 900KVA \
|
||||
--pubkey <you validator pubkey from above> \
|
||||
--address-validator <your address from above> \
|
||||
--moniker "<your name>" \
|
||||
--chain-id kava-test-2 \
|
||||
--from <your name> \
|
||||
--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!
|
||||
|
||||
@ -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.
|
||||
|
||||
kvcli stake unbond begin \
|
||||
--address-delegator <your address> \
|
||||
--address-validator <your address> \
|
||||
--chain-id kava-test-2 \
|
||||
--shares-percent 1 \
|
||||
--from <your name> \
|
||||
--gas 1000000
|
||||
|
27
docs/upgrade.md
Normal file
27
docs/upgrade.md
Normal 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.
|
@ -1,5 +1,6 @@
|
||||
# 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.
|
||||
|
||||
## 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.
|
||||
|
||||
@ -13,7 +14,6 @@ List locally stored account addresses and their names. The name is used in other
|
||||
|
||||
kvcli send --from <your key name> \
|
||||
--to <address> \
|
||||
--amount 100KVA \
|
||||
--chain-id kava-test-<current testnet #>
|
||||
--amount 100KVA
|
||||
|
||||
|
||||
|
@ -19,8 +19,7 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/bank"
|
||||
//"github.com/cosmos/cosmos-sdk/x/gov"
|
||||
//"github.com/cosmos/cosmos-sdk/x/ibc"
|
||||
"github.com/cosmos/cosmos-sdk/x/params"
|
||||
"github.com/cosmos/cosmos-sdk/x/slashing"
|
||||
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||
"github.com/kava-labs/kava/internal/x/paychan"
|
||||
@ -41,25 +40,23 @@ type KavaApp struct {
|
||||
cdc *wire.Codec
|
||||
|
||||
// keys to access the substores
|
||||
keyMain *sdk.KVStoreKey
|
||||
keyAccount *sdk.KVStoreKey
|
||||
|
||||
//keyIBC *sdk.KVStoreKey
|
||||
keyStake *sdk.KVStoreKey
|
||||
keySlashing *sdk.KVStoreKey
|
||||
//keyGov *sdk.KVStoreKey
|
||||
keyMain *sdk.KVStoreKey
|
||||
keyAccount *sdk.KVStoreKey
|
||||
keyStake *sdk.KVStoreKey
|
||||
keySlashing *sdk.KVStoreKey
|
||||
keyFeeCollection *sdk.KVStoreKey
|
||||
keyParams *sdk.KVStoreKey
|
||||
tkeyParams *sdk.TransientStoreKey
|
||||
keyPaychan *sdk.KVStoreKey
|
||||
|
||||
// keepers
|
||||
accountMapper auth.AccountMapper
|
||||
feeCollectionKeeper auth.FeeCollectionKeeper
|
||||
coinKeeper bank.Keeper
|
||||
stakeKeeper stake.Keeper
|
||||
slashingKeeper slashing.Keeper
|
||||
paramsKeeper params.Keeper
|
||||
paychanKeeper paychan.Keeper
|
||||
//ibcMapper ibc.Mapper
|
||||
stakeKeeper stake.Keeper
|
||||
slashingKeeper slashing.Keeper
|
||||
//govKeeper gov.Keeper
|
||||
}
|
||||
|
||||
// Creates a new KavaApp.
|
||||
@ -69,49 +66,46 @@ func NewKavaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, baseAppOptio
|
||||
cdc := CreateKavaAppCodec()
|
||||
|
||||
// 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)
|
||||
|
||||
// Create the kava app, extending baseApp
|
||||
var app = &KavaApp{
|
||||
BaseApp: bApp,
|
||||
cdc: cdc,
|
||||
keyMain: sdk.NewKVStoreKey("main"),
|
||||
keyAccount: sdk.NewKVStoreKey("acc"),
|
||||
keyPaychan: sdk.NewKVStoreKey("paychan"),
|
||||
//keyIBC: sdk.NewKVStoreKey("ibc"),
|
||||
keyStake: sdk.NewKVStoreKey("stake"),
|
||||
keySlashing: sdk.NewKVStoreKey("slashing"),
|
||||
//keyGov: sdk.NewKVStoreKey("gov"),
|
||||
BaseApp: bApp,
|
||||
cdc: cdc,
|
||||
keyMain: sdk.NewKVStoreKey("main"),
|
||||
keyAccount: sdk.NewKVStoreKey("acc"),
|
||||
keyStake: sdk.NewKVStoreKey("stake"),
|
||||
keySlashing: sdk.NewKVStoreKey("slashing"),
|
||||
keyFeeCollection: sdk.NewKVStoreKey("fee"),
|
||||
keyParams: sdk.NewKVStoreKey("params"),
|
||||
tkeyParams: sdk.NewTransientStoreKey("transient_params"),
|
||||
keyPaychan: sdk.NewKVStoreKey("paychan"),
|
||||
}
|
||||
|
||||
// Define the accountMapper and base account
|
||||
app.accountMapper = auth.NewAccountMapper(
|
||||
cdc,
|
||||
app.cdc,
|
||||
app.keyAccount,
|
||||
auth.ProtoBaseAccount,
|
||||
)
|
||||
|
||||
// Create the keepers
|
||||
app.coinKeeper = bank.NewKeeper(app.accountMapper)
|
||||
app.paychanKeeper = paychan.NewKeeper(app.cdc, app.keyPaychan, app.coinKeeper)
|
||||
//app.ibcMapper = ibc.NewMapper(app.cdc, app.keyIBC, app.RegisterCodespace(ibc.DefaultCodespace))
|
||||
app.paramsKeeper = params.NewKeeper(app.cdc, app.keyParams)
|
||||
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.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
|
||||
app.Router().
|
||||
AddRoute("bank", bank.NewHandler(app.coinKeeper)).
|
||||
//AddRoute("ibc", ibc.NewHandler(app.ibcMapper, app.coinKeeper)).
|
||||
AddRoute("stake", stake.NewHandler(app.stakeKeeper)).
|
||||
AddRoute("slashing", slashing.NewHandler(app.slashingKeeper)).
|
||||
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)
|
||||
|
||||
// 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))
|
||||
|
||||
// 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)
|
||||
if err != nil {
|
||||
cmn.Exit(err.Error())
|
||||
@ -132,11 +127,9 @@ func NewKavaApp(logger log.Logger, db dbm.DB, traceStore io.Writer, baseAppOptio
|
||||
func CreateKavaAppCodec() *wire.Codec {
|
||||
cdc := wire.NewCodec()
|
||||
paychan.RegisterWire(cdc)
|
||||
//ibc.RegisterWire(cdc)
|
||||
bank.RegisterWire(cdc)
|
||||
stake.RegisterWire(cdc)
|
||||
slashing.RegisterWire(cdc)
|
||||
//gov.RegisterWire(cdc)
|
||||
auth.RegisterWire(cdc)
|
||||
sdk.RegisterWire(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
|
||||
func (app *KavaApp) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) abci.ResponseEndBlock {
|
||||
paychan.EndBlocker(ctx, app.paychanKeeper)
|
||||
validatorUpdates := stake.EndBlocker(ctx, app.stakeKeeper)
|
||||
tags := paychan.EndBlocker(ctx, app.paychanKeeper)
|
||||
|
||||
//tags, _ := gov.EndBlocker(ctx, app.govKeeper)
|
||||
validatorUpdates := stake.EndBlocker(ctx, app.stakeKeeper)
|
||||
app.slashingKeeper.AddValidators(ctx, validatorUpdates)
|
||||
|
||||
return abci.ResponseEndBlock{
|
||||
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 {
|
||||
stateJSON := req.AppStateBytes
|
||||
|
||||
@ -183,14 +176,16 @@ func (app *KavaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
|
||||
}
|
||||
|
||||
// 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 {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
//gov.InitGenesis(ctx, app.govKeeper, gov.DefaultGenesisState())
|
||||
slashing.InitGenesis(ctx, app.slashingKeeper, genesisState.StakeData)
|
||||
|
||||
return abci.ResponseInitChain{}
|
||||
return abci.ResponseInitChain{
|
||||
Validators: validators,
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -6,7 +6,10 @@ package app
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/spf13/pflag"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
@ -19,6 +22,8 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||
)
|
||||
|
||||
const defaultPassword = "password"
|
||||
|
||||
var (
|
||||
// Tokens given to genesis validators and accounts
|
||||
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 {
|
||||
fsAppGenState := pflag.NewFlagSet("", pflag.ContinueOnError)
|
||||
fsAppGenTx := pflag.NewFlagSet("", pflag.ContinueOnError)
|
||||
@ -86,22 +91,41 @@ type KavaGenTx struct {
|
||||
PubKey string `json:"pub_key"`
|
||||
}
|
||||
|
||||
// Generate a genesis transsction
|
||||
// Generate a genesis transaction
|
||||
func KavaAppGenTx(cdc *wire.Codec, pk crypto.PubKey, genTxConfig config.GenTx) (
|
||||
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 == "" {
|
||||
return nil, nil, tmtypes.GenesisValidator{}, errors.New("Must specify --name (validator moniker)")
|
||||
}
|
||||
var addr sdk.AccAddress
|
||||
var secret string
|
||||
addr, secret, err = server.GenerateSaveCoinKey(genTxConfig.CliRoot, genTxConfig.Name, "password", genTxConfig.Overwrite)
|
||||
|
||||
// get a new password for the new account
|
||||
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 {
|
||||
return
|
||||
}
|
||||
|
||||
// Create string to print out
|
||||
// Create message string to print out
|
||||
mm := map[string]string{"secret": secret}
|
||||
var bz []byte
|
||||
bz, err = cdc.MarshalJSON(mm)
|
||||
@ -154,6 +178,8 @@ func KavaAppGenState(cdc *wire.Codec, appGenTxs []json.RawMessage) (genesisState
|
||||
stakeData := stake.DefaultGenesisState()
|
||||
// change denom of staking coin
|
||||
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
|
||||
genaccs := make([]GenesisAccount, len(appGenTxs))
|
||||
|
@ -1,27 +1,24 @@
|
||||
package lcd
|
||||
|
||||
/*
|
||||
import (
|
||||
"net/http"
|
||||
//"encoding/hex"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
)
|
||||
*/
|
||||
|
||||
type TxBody struct {
|
||||
type txBody struct {
|
||||
TxBase64 string `json:"txbase64"`
|
||||
}
|
||||
|
||||
// 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) {
|
||||
// get the input base64 string
|
||||
var m TxBody
|
||||
var m txBody
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
err := decoder.Decode(&m)
|
||||
if err != nil {
|
||||
|
695
internal/lcd/lcd_test.go
Normal file
695
internal/lcd/lcd_test.go
Normal 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
|
||||
}
|
@ -3,32 +3,27 @@
|
||||
|
||||
package lcd
|
||||
|
||||
/*
|
||||
import (
|
||||
"net/http"
|
||||
"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"
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
keys "github.com/cosmos/cosmos-sdk/client/keys"
|
||||
rpc "github.com/cosmos/cosmos-sdk/client/rpc"
|
||||
tx "github.com/cosmos/cosmos-sdk/client/tx"
|
||||
version "github.com/cosmos/cosmos-sdk/version"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
auth "github.com/cosmos/cosmos-sdk/x/auth/client/rest"
|
||||
bank "github.com/cosmos/cosmos-sdk/x/bank/client/rest"
|
||||
//ibc "github.com/cosmos/cosmos-sdk/x/ibc/client/rest"
|
||||
//stake "github.com/cosmos/cosmos-sdk/x/stake/client/rest"
|
||||
slashing "github.com/cosmos/cosmos-sdk/x/slashing/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
|
||||
// (aka Light Client Daemon) that exposes functionality similar
|
||||
@ -36,6 +31,7 @@ import (
|
||||
func ServeCommand(cdc *wire.Codec) *cobra.Command {
|
||||
flagListenAddr := "laddr"
|
||||
flagCORS := "cors"
|
||||
flagMaxOpenConnections := "max-open"
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "rest-server",
|
||||
@ -43,48 +39,59 @@ func ServeCommand(cdc *wire.Codec) *cobra.Command {
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
listenAddr := viper.GetString(flagListenAddr)
|
||||
handler := createHandler(cdc)
|
||||
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).
|
||||
With("module", "rest-server")
|
||||
listener, err := tmserver.StartHTTPServer(listenAddr, handler, logger)
|
||||
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "rest-server")
|
||||
maxOpen := viper.GetInt(flagMaxOpenConnections)
|
||||
|
||||
listener, err := tmserver.StartHTTPServer(
|
||||
listenAddr, handler, logger,
|
||||
tmserver.Config{MaxOpenConnections: maxOpen},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Info("REST server started")
|
||||
|
||||
// Wait forever and cleanup
|
||||
// wait forever and cleanup
|
||||
cmn.TrapSignal(func() {
|
||||
err := listener.Close()
|
||||
logger.Error("Error closing listener", "err", err)
|
||||
logger.Error("error closing listener", "err", err)
|
||||
})
|
||||
|
||||
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().StringP(client.FlagChainID, "c", "", "ID of chain we connect to")
|
||||
cmd.Flags().StringP(client.FlagNode, "n", "tcp://localhost:46657", "Node to connect to")
|
||||
|
||||
cmd.Flags().String(flagListenAddr, "tcp://localhost:1317", "The address for the server to listen on")
|
||||
cmd.Flags().String(flagCORS, "", "Set the domains that can make CORS requests (* for all)")
|
||||
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
|
||||
}
|
||||
|
||||
func createHandler(cdc *wire.Codec) http.Handler {
|
||||
r := mux.NewRouter()
|
||||
r.HandleFunc("/version", version.RequestHandler).Methods("GET")
|
||||
|
||||
kb, err := keys.GetKeyBase() //XXX
|
||||
if err != nil {
|
||||
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)
|
||||
rpc.RegisterRoutes(ctx, r)
|
||||
tx.RegisterRoutes(ctx, r, cdc)
|
||||
auth.RegisterRoutes(ctx, r, cdc, "acc")
|
||||
bank.RegisterRoutes(ctx, r, cdc, kb)
|
||||
//ibc.RegisterRoutes(ctx, r, cdc, kb)
|
||||
//stake.RegisterRoutes(ctx, r, cdc, kb)
|
||||
r.HandleFunc("/decode_tx", DecodeTxRequestHandlerFn(ctx, cdc)).Methods("POST")
|
||||
rpc.RegisterRoutes(cliCtx, r)
|
||||
tx.RegisterRoutes(cliCtx, r, cdc)
|
||||
auth.RegisterRoutes(cliCtx, r, cdc, "acc")
|
||||
bank.RegisterRoutes(cliCtx, r, cdc, kb)
|
||||
stake.RegisterRoutes(cliCtx, r, cdc, kb)
|
||||
slashing.RegisterRoutes(cliCtx, r, cdc, kb)
|
||||
|
||||
return r
|
||||
}
|
||||
|
275
internal/lcd/test_helpers.go
Normal file
275
internal/lcd/test_helpers.go
Normal 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
32
internal/lcd/version.go
Normal 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)
|
||||
}
|
||||
}
|
@ -1,11 +1,12 @@
|
||||
// Copyright 2016 All in Bits, inc
|
||||
// Modifications copyright 2018 Kava Labs
|
||||
|
||||
package lcd
|
||||
|
||||
/*
|
||||
import (
|
||||
amino "github.com/tendermint/go-amino"
|
||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||
)
|
||||
*/
|
||||
|
||||
var cdc = amino.NewCodec()
|
||||
|
||||
|
@ -3,6 +3,7 @@ package cli
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
@ -10,9 +11,11 @@ import (
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
"github.com/cosmos/cosmos-sdk/client/keys"
|
||||
"github.com/cosmos/cosmos-sdk/client/utils"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
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"
|
||||
)
|
||||
@ -31,13 +34,15 @@ func CreateChannelCmd(cdc *wire.Codec) *cobra.Command {
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
// Create a "client context" stuct populated with info from common flags
|
||||
ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc))
|
||||
// TODO is this needed for channelID
|
||||
// ctx.PrintResponse = true
|
||||
// Create a tx and cli "contexts": structs populated with info from common flags.
|
||||
txCtx := authctx.NewTxContextFromCLI().WithCodec(cdc)
|
||||
cliCtx := context.NewCLIContext().
|
||||
WithCodec(cdc).
|
||||
WithLogger(os.Stdout).
|
||||
WithAccountDecoder(authcmd.GetAccountDecoder(cdc))
|
||||
|
||||
// Get sender adress
|
||||
sender, err := ctx.GetFromAddress()
|
||||
// Get sender address
|
||||
sender, err := cliCtx.GetFromAddress()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -67,11 +72,7 @@ func CreateChannelCmd(cdc *wire.Codec) *cobra.Command {
|
||||
}
|
||||
|
||||
// Build and sign the transaction, then broadcast to the blockchain
|
||||
err = ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, []sdk.Msg{msg}, cdc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return utils.SendTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
},
|
||||
}
|
||||
cmd.Flags().String(flagTo, "", "Recipient address of the payment channel.")
|
||||
@ -92,8 +93,11 @@ func GeneratePaymentCmd(cdc *wire.Codec) *cobra.Command {
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
// Create a "client context" stuct populated with info from common flags
|
||||
ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc))
|
||||
// Create a cli "context": struct populated with info from common flags.
|
||||
cliCtx := context.NewCLIContext().
|
||||
WithCodec(cdc).
|
||||
WithLogger(os.Stdout).
|
||||
WithAccountDecoder(authcmd.GetAccountDecoder(cdc))
|
||||
|
||||
// Get the paychan id
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
name := ctx.FromAddressName
|
||||
passphrase, err := ctx.GetPassphraseFromStdin(name)
|
||||
name := cliCtx.FromAddressName
|
||||
passphrase, err := keys.GetPassphrase(cliCtx.FromAddressName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -169,8 +173,11 @@ func VerifyPaymentCmd(cdc *wire.Codec, paychanStoreName string) *cobra.Command {
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
// Create a "client context" stuct populated with info from common flags
|
||||
ctx := context.NewCoreContextFromViper()
|
||||
// Create a cli "context": struct populated with info from common flags.
|
||||
cliCtx := context.NewCLIContext().
|
||||
WithCodec(cdc).
|
||||
WithLogger(os.Stdout).
|
||||
WithAccountDecoder(authcmd.GetAccountDecoder(cdc))
|
||||
|
||||
// read in update
|
||||
bz, err := ioutil.ReadFile(viper.GetString(flagPaymentFile))
|
||||
@ -183,7 +190,7 @@ func VerifyPaymentCmd(cdc *wire.Codec, paychanStoreName string) *cobra.Command {
|
||||
cdc.UnmarshalJSON(bz, &update)
|
||||
|
||||
// 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 {
|
||||
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,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
// Create a "client context" stuct populated with info from common flags
|
||||
ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc))
|
||||
// ctx.PrintResponse = true TODO is this needed for channelID
|
||||
// Create a tx and cli "contexts": structs populated with info from common flags.
|
||||
txCtx := authctx.NewTxContextFromCLI().WithCodec(cdc)
|
||||
cliCtx := context.NewCLIContext().
|
||||
WithCodec(cdc).
|
||||
WithLogger(os.Stdout).
|
||||
WithAccountDecoder(authcmd.GetAccountDecoder(cdc))
|
||||
|
||||
// Get sender adress
|
||||
submitter, err := ctx.GetFromAddress()
|
||||
// Get sender address
|
||||
submitter, err := cliCtx.GetFromAddress()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -248,11 +258,7 @@ func SubmitPaymentCmd(cdc *wire.Codec) *cobra.Command {
|
||||
}
|
||||
|
||||
// Build and sign the transaction, then broadcast to the blockchain
|
||||
err = ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, []sdk.Msg{msg}, cdc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return utils.SendTx(txCtx, cliCtx, []sdk.Msg{msg})
|
||||
},
|
||||
}
|
||||
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,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
// Create a "client context" stuct populated with info from common flags
|
||||
ctx := context.NewCoreContextFromViper()
|
||||
// Create a cli "context": struct populated with info from common flags.
|
||||
cliCtx := context.NewCLIContext().
|
||||
WithCodec(cdc).
|
||||
WithLogger(os.Stdout).
|
||||
WithAccountDecoder(authcmd.GetAccountDecoder(cdc))
|
||||
|
||||
// Get channel ID
|
||||
id := paychan.ChannelID(viper.GetInt64(flagId))
|
||||
|
||||
// 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 {
|
||||
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))
|
||||
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
// Print out the submited update if it exsits
|
||||
// Print out the submitted update if it exists
|
||||
if len(res) != 0 {
|
||||
var submittedUpdate paychan.SubmittedUpdate
|
||||
cdc.MustUnmarshalBinary(res, &submittedUpdate)
|
@ -1,9 +1,10 @@
|
||||
package paychan
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestEndBlocker(t *testing.T) {
|
||||
@ -14,7 +15,7 @@ func TestEndBlocker(t *testing.T) {
|
||||
ctx, _, channelKeeper, addrs, _, _, _ := createMockApp(accountSeeds)
|
||||
sender := addrs[0]
|
||||
receiver := addrs[1]
|
||||
coins := sdk.Coins{sdk.NewCoin("KVA", 10)}
|
||||
coins := sdk.Coins{sdk.NewInt64Coin("KVA", 10)}
|
||||
|
||||
// create new channel
|
||||
channelID := ChannelID(0) // should be 0 as first channel
|
||||
@ -26,11 +27,10 @@ func TestEndBlocker(t *testing.T) {
|
||||
channelKeeper.setChannel(ctx, channel)
|
||||
|
||||
// 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{
|
||||
ChannelID: channelID,
|
||||
Payout: payout,
|
||||
//Sigs: [1]crypto.Signature{},
|
||||
}
|
||||
sUpdate := SubmittedUpdate{
|
||||
Update: update,
|
||||
|
@ -30,7 +30,7 @@ func TestKeeper(t *testing.T) {
|
||||
"HappyPath",
|
||||
addrs[senderAccountIndex],
|
||||
addrs[receiverAccountIndex],
|
||||
sdk.Coins{sdk.NewCoin("KVA", 10)},
|
||||
sdk.Coins{sdk.NewInt64Coin("KVA", 10)},
|
||||
true,
|
||||
false,
|
||||
},
|
||||
@ -38,7 +38,7 @@ func TestKeeper(t *testing.T) {
|
||||
"NilAddress",
|
||||
sdk.AccAddress{},
|
||||
sdk.AccAddress{},
|
||||
sdk.Coins{sdk.NewCoin("KVA", 10)},
|
||||
sdk.Coins{sdk.NewInt64Coin("KVA", 10)},
|
||||
false,
|
||||
true,
|
||||
},
|
||||
@ -54,7 +54,7 @@ func TestKeeper(t *testing.T) {
|
||||
"NegativeCoins",
|
||||
addrs[senderAccountIndex],
|
||||
addrs[receiverAccountIndex],
|
||||
sdk.Coins{sdk.NewCoin("KVA", -57)},
|
||||
sdk.Coins{sdk.NewInt64Coin("KVA", -57)},
|
||||
false,
|
||||
true,
|
||||
},
|
||||
@ -126,7 +126,7 @@ func TestKeeper(t *testing.T) {
|
||||
)
|
||||
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
|
||||
channelID := ChannelID(0) // should be 0 as first channel
|
||||
@ -138,7 +138,7 @@ func TestKeeper(t *testing.T) {
|
||||
channelKeeper.setChannel(ctx, channel)
|
||||
|
||||
// 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{
|
||||
ChannelID: channelID,
|
||||
Payout: payout,
|
||||
@ -200,14 +200,14 @@ func TestKeeper(t *testing.T) {
|
||||
{
|
||||
"HappyPath",
|
||||
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",
|
||||
false,
|
||||
},
|
||||
{
|
||||
"NoChannel",
|
||||
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",
|
||||
true,
|
||||
},
|
||||
@ -221,35 +221,35 @@ func TestKeeper(t *testing.T) {
|
||||
{
|
||||
"NegativeCoins",
|
||||
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",
|
||||
true,
|
||||
},
|
||||
{
|
||||
"TooManyCoins",
|
||||
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",
|
||||
true,
|
||||
},
|
||||
{
|
||||
"WrongSignature",
|
||||
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",
|
||||
true,
|
||||
},
|
||||
{
|
||||
"WrongPubKey",
|
||||
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",
|
||||
true,
|
||||
},
|
||||
{
|
||||
"ReceiverSigned",
|
||||
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",
|
||||
true,
|
||||
},
|
||||
@ -266,7 +266,7 @@ func TestKeeper(t *testing.T) {
|
||||
channel := Channel{
|
||||
ID: chanID, // should be 0 as first channel
|
||||
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)
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ func createMockApp(accountSeeds []string) (sdk.Context, bank.Keeper, Keeper, []s
|
||||
mApp.CompleteSetup([]*sdk.KVStoreKey{keyChannel})
|
||||
|
||||
// create some accounts
|
||||
genAccFunding := sdk.Coins{sdk.NewCoin("KVA", 1000)}
|
||||
genAccFunding := sdk.Coins{sdk.NewInt64Coin("KVA", 1000)}
|
||||
genAccs, addrs, pubKeys, privKeys := createTestGenAccounts(accountSeeds, genAccFunding)
|
||||
|
||||
// initialize the app with these accounts
|
||||
|
@ -61,7 +61,7 @@ func (p Payout) Sum() sdk.Coins {
|
||||
|
||||
type UpdateSignature struct {
|
||||
PubKey crypto.PubKey
|
||||
CryptoSignature crypto.Signature
|
||||
CryptoSignature []byte
|
||||
}
|
||||
|
||||
// An update that has been submitted to the blockchain, but not yet acted on.
|
||||
|
@ -28,18 +28,18 @@ func TestSubmittedUpdatesQueue(t *testing.T) {
|
||||
|
||||
func TestPayout(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())
|
||||
|
||||
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())
|
||||
})
|
||||
t.Run("Sum", func(t *testing.T) {
|
||||
p := Payout{
|
||||
sdk.Coins{sdk.NewCoin("EUR", 1), sdk.NewCoin("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", -5)},
|
||||
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())
|
||||
})
|
||||
}
|
||||
|
207
testnets/kava-test-3/config.toml
Normal file
207
testnets/kava-test-3/config.toml
Normal 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
|
99
testnets/kava-test-3/genesis.json
Normal file
99
testnets/kava-test-3/genesis.json
Normal 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"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user