Merge pull request #1101 from cosmos/rigel/gobash2
fix go-bash, add to ci
This commit is contained in:
commit
9f8c5adb6d
@ -85,6 +85,22 @@ jobs:
|
||||
export PATH="$GOBIN:$PATH"
|
||||
make test_unit
|
||||
|
||||
test_cli:
|
||||
<<: *defaults
|
||||
parallelism: 1
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: /tmp/workspace
|
||||
- restore_cache:
|
||||
key: v1-pkg-cache
|
||||
- restore_cache:
|
||||
key: v1-tree-{{ .Environment.CIRCLE_SHA1 }}
|
||||
- run:
|
||||
name: Test cli
|
||||
command: |
|
||||
export PATH="$GOBIN:$PATH"
|
||||
make test_cli
|
||||
|
||||
test_cover:
|
||||
<<: *defaults
|
||||
parallelism: 4
|
||||
@ -138,6 +154,9 @@ workflows:
|
||||
- lint:
|
||||
requires:
|
||||
- setup_dependencies
|
||||
- test_cli:
|
||||
requires:
|
||||
- setup_dependencies
|
||||
- test_unit:
|
||||
requires:
|
||||
- setup_dependencies
|
||||
|
||||
@ -11,6 +11,8 @@ IMPROVEMENTS
|
||||
* auth module uses go-wire codec instead of 'encoding/json'
|
||||
|
||||
FIXES
|
||||
* [cli] fixed cli-bash tests
|
||||
* [ci] added cli-bash tests
|
||||
|
||||
## 0.18.1
|
||||
|
||||
@ -100,7 +102,7 @@ FEATURES
|
||||
* [gaiacli] Support queries for candidates, delegator-bonds
|
||||
* [gaiad] Added `gaiad export` command to export current state to JSON
|
||||
* [x/bank] Tx tags with sender/recipient for indexing & later retrieval
|
||||
* [x/stake] Tx tags with delegator/candidate for delegation & unbonding, and candidate info for declare candidate / edit candidacy
|
||||
* [x/stake] Tx tags with delegator/candidate for delegation & unbonding, and candidate info for declare candidate / edit validator
|
||||
|
||||
IMPROVEMENTS
|
||||
|
||||
@ -134,7 +136,7 @@ BREAKING CHANGES
|
||||
|
||||
FEATURES:
|
||||
|
||||
* Gaia stake commands include, DeclareCandidacy, EditCandidacy, Delegate, Unbond
|
||||
* Gaia stake commands include, CreateValidator, EditValidator, Delegate, Unbond
|
||||
* MountStoreWithDB without providing a custom store works.
|
||||
* Repo is now lint compliant / GoMetaLinter with tendermint-lint integrated into CI
|
||||
* Better key output, pubkey go-amino hex bytes now output by default
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package keys
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
@ -76,7 +75,7 @@ func printInfo(info keys.Info) {
|
||||
fmt.Printf("NAME:\tADDRESS:\t\t\t\t\t\tPUBKEY:\n")
|
||||
printKeyOutput(ko)
|
||||
case "json":
|
||||
out, err := json.MarshalIndent(ko, "", "\t")
|
||||
out, err := MarshalJSON(ko)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -93,7 +92,7 @@ func printInfos(infos []keys.Info) {
|
||||
printKeyOutput(ko)
|
||||
}
|
||||
case "json":
|
||||
out, err := json.MarshalIndent(kos, "", "\t")
|
||||
out, err := MarshalJSON(kos)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@ -34,6 +34,7 @@ import (
|
||||
client "github.com/cosmos/cosmos-sdk/client"
|
||||
keys "github.com/cosmos/cosmos-sdk/client/keys"
|
||||
gapp "github.com/cosmos/cosmos-sdk/cmd/gaia/app"
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
tests "github.com/cosmos/cosmos-sdk/tests"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
@ -51,7 +52,7 @@ var (
|
||||
// XXX bad globals
|
||||
name = "test"
|
||||
password = "0123456789"
|
||||
port string // XXX: but it's the int ...
|
||||
port string
|
||||
seed string
|
||||
sendAddr string
|
||||
)
|
||||
@ -456,8 +457,11 @@ func startTMAndLCD() (*nm.Node, net.Listener, error) {
|
||||
genDoc.AppStateJSON = appState
|
||||
|
||||
// LCD listen address
|
||||
port = fmt.Sprintf("%d", 17377) // XXX
|
||||
listenAddr := fmt.Sprintf("tcp://localhost:%s", port) // XXX
|
||||
var listenAddr string
|
||||
listenAddr, port, err = server.FreeTCPAddr()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// XXX: need to set this so LCD knows the tendermint node address!
|
||||
viper.Set(client.FlagNode, config.RPC.ListenAddress)
|
||||
|
||||
@ -394,13 +394,13 @@ func TestStakeMsgs(t *testing.T) {
|
||||
require.Equal(t, acc1, res1)
|
||||
require.Equal(t, acc2, res2)
|
||||
|
||||
// Declare Candidacy
|
||||
// Create Validator
|
||||
|
||||
description := stake.NewDescription("foo_moniker", "", "", "")
|
||||
declareCandidacyMsg := stake.NewMsgDeclareCandidacy(
|
||||
createValidatorMsg := stake.NewMsgCreateValidator(
|
||||
addr1, priv1.PubKey(), bondCoin, description,
|
||||
)
|
||||
SignCheckDeliver(t, gapp, declareCandidacyMsg, []int64{0}, true, priv1)
|
||||
SignCheckDeliver(t, gapp, createValidatorMsg, []int64{0}, true, priv1)
|
||||
|
||||
ctxDeliver := gapp.BaseApp.NewContext(false, abci.Header{})
|
||||
res1 = gapp.accountMapper.GetAccount(ctxDeliver, addr1)
|
||||
@ -415,13 +415,13 @@ func TestStakeMsgs(t *testing.T) {
|
||||
bond, found := gapp.stakeKeeper.GetDelegation(ctxDeliver, addr1, addr1)
|
||||
require.True(sdk.RatEq(t, sdk.NewRat(10), bond.Shares))
|
||||
|
||||
// Edit Candidacy
|
||||
// Edit Validator
|
||||
|
||||
description = stake.NewDescription("bar_moniker", "", "", "")
|
||||
editCandidacyMsg := stake.NewMsgEditCandidacy(
|
||||
editValidatorMsg := stake.NewMsgEditValidator(
|
||||
addr1, description,
|
||||
)
|
||||
SignDeliver(t, gapp, editCandidacyMsg, []int64{1}, true, priv1)
|
||||
SignDeliver(t, gapp, editValidatorMsg, []int64{1}, true, priv1)
|
||||
|
||||
validator, found = gapp.stakeKeeper.GetValidator(ctxDeliver, addr1)
|
||||
require.True(t, found)
|
||||
|
||||
@ -30,46 +30,44 @@ func TestGaiaCLISend(t *testing.T) {
|
||||
executeWrite(t, "gaiacli keys add bar", pass)
|
||||
|
||||
// get a free port, also setup some common flags
|
||||
servAddr := server.FreeTCPAddr(t)
|
||||
servAddr, port, err := server.FreeTCPAddr()
|
||||
require.NoError(t, err)
|
||||
flags := fmt.Sprintf("--node=%v --chain-id=%v", servAddr, chainID)
|
||||
|
||||
// start gaiad server
|
||||
cmd, _, _ := tests.GoExecuteT(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr))
|
||||
defer cmd.Process.Kill()
|
||||
proc := tests.GoExecuteT(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr))
|
||||
defer proc.Stop(false)
|
||||
tests.WaitForStart(port)
|
||||
|
||||
fooAddr, _ := executeGetAddrPK(t, "gaiacli keys show foo --output=json")
|
||||
fooCech, err := sdk.Bech32CosmosifyAcc(fooAddr)
|
||||
require.NoError(t, err)
|
||||
barAddr, _ := executeGetAddrPK(t, "gaiacli keys show bar --output=json")
|
||||
barCech, err := sdk.Bech32CosmosifyAcc(barAddr)
|
||||
require.NoError(t, err)
|
||||
|
||||
fooBech, err := sdk.Bech32CosmosifyAcc(fooAddr)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
barBech, err := sdk.Bech32CosmosifyAcc(barAddr)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooBech, flags))
|
||||
fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooCech, flags))
|
||||
assert.Equal(t, int64(50), fooAcc.GetCoins().AmountOf("steak"))
|
||||
|
||||
executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10steak --to=%v --name=foo", flags, barAddr), pass)
|
||||
time.Sleep(time.Second * 3) // waiting for some blocks to pass
|
||||
executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10steak --to=%v --name=foo", flags, barCech), pass)
|
||||
time.Sleep(time.Second * 2) // waiting for some blocks to pass
|
||||
|
||||
barAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barBech, flags))
|
||||
barAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barCech, flags))
|
||||
assert.Equal(t, int64(10), barAcc.GetCoins().AmountOf("steak"))
|
||||
fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooBech, flags))
|
||||
fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooCech, flags))
|
||||
assert.Equal(t, int64(40), fooAcc.GetCoins().AmountOf("steak"))
|
||||
|
||||
// test autosequencing
|
||||
executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10steak --to=%v --name=foo", flags, barAddr), pass)
|
||||
time.Sleep(time.Second * 3) // waiting for some blocks to pass
|
||||
executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10steak --to=%v --name=foo", flags, barCech), pass)
|
||||
time.Sleep(time.Second * 2) // waiting for some blocks to pass
|
||||
|
||||
barAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barBech, flags))
|
||||
barAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barCech, flags))
|
||||
assert.Equal(t, int64(20), barAcc.GetCoins().AmountOf("steak"))
|
||||
fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooBech, flags))
|
||||
fooAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooCech, flags))
|
||||
assert.Equal(t, int64(30), fooAcc.GetCoins().AmountOf("steak"))
|
||||
}
|
||||
|
||||
func TestGaiaCLIDeclareCandidacy(t *testing.T) {
|
||||
func TestGaiaCLICreateValidator(t *testing.T) {
|
||||
|
||||
tests.ExecuteT(t, "gaiad unsafe_reset_all")
|
||||
pass := "1234567890"
|
||||
@ -79,95 +77,79 @@ func TestGaiaCLIDeclareCandidacy(t *testing.T) {
|
||||
executeWrite(t, "gaiacli keys add bar", pass)
|
||||
|
||||
// get a free port, also setup some common flags
|
||||
servAddr := server.FreeTCPAddr(t)
|
||||
servAddr, port, err := server.FreeTCPAddr()
|
||||
require.NoError(t, err)
|
||||
flags := fmt.Sprintf("--node=%v --chain-id=%v", servAddr, chainID)
|
||||
|
||||
// start gaiad server
|
||||
cmd, _, _ := tests.GoExecuteT(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr))
|
||||
defer cmd.Process.Kill()
|
||||
proc := tests.GoExecuteT(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr))
|
||||
defer proc.Stop(false)
|
||||
tests.WaitForStart(port)
|
||||
|
||||
fooAddr, _ := executeGetAddrPK(t, "gaiacli keys show foo --output=json")
|
||||
barAddr, _ := executeGetAddrPK(t, "gaiacli keys show bar --output=json")
|
||||
fooCech, err := sdk.Bech32CosmosifyAcc(fooAddr)
|
||||
require.NoError(t, err)
|
||||
barAddr, barPubKey := executeGetAddrPK(t, "gaiacli keys show bar --output=json")
|
||||
barCech, err := sdk.Bech32CosmosifyAcc(barAddr)
|
||||
require.NoError(t, err)
|
||||
barCeshPubKey, err := sdk.Bech32CosmosifyValPub(barPubKey)
|
||||
require.NoError(t, err)
|
||||
|
||||
fooBech, err := sdk.Bech32CosmosifyAcc(fooAddr)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
barBech, err := sdk.Bech32CosmosifyAcc(barAddr)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
valPrivkey := crypto.GenPrivKeyEd25519()
|
||||
valAddr := sdk.Address((valPrivkey.PubKey().Address()))
|
||||
bechVal, err := sdk.Bech32CosmosifyVal(valAddr)
|
||||
executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10steak --to=%v --name=foo", flags, barCech), pass)
|
||||
time.Sleep(time.Second * 2) // waiting for some blocks to pass
|
||||
|
||||
executeWrite(t, fmt.Sprintf("gaiacli send %v --amount=10steak --to=%v --name=foo", flags, barBech), pass)
|
||||
barAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barCech, flags))
|
||||
assert.Equal(t, int64(10), barAcc.GetCoins().AmountOf("steak"))
|
||||
fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooCech, flags))
|
||||
assert.Equal(t, int64(40), fooAcc.GetCoins().AmountOf("steak"))
|
||||
|
||||
// create validator
|
||||
cvStr := fmt.Sprintf("gaiacli create-validator %v", flags)
|
||||
cvStr += fmt.Sprintf(" --name=%v", "bar")
|
||||
cvStr += fmt.Sprintf(" --address-validator=%v", barCech)
|
||||
cvStr += fmt.Sprintf(" --pubkey=%v", barCeshPubKey)
|
||||
cvStr += fmt.Sprintf(" --amount=%v", "2steak")
|
||||
cvStr += fmt.Sprintf(" --moniker=%v", "bar-vally")
|
||||
|
||||
executeWrite(t, cvStr, pass)
|
||||
time.Sleep(time.Second * 3) // waiting for some blocks to pass
|
||||
|
||||
fooAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", fooBech, flags))
|
||||
assert.Equal(t, int64(40), fooAcc.GetCoins().AmountOf("steak"))
|
||||
barAcc := executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barBech, flags))
|
||||
assert.Equal(t, int64(10), barAcc.GetCoins().AmountOf("steak"))
|
||||
barAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barCech, flags))
|
||||
require.Equal(t, int64(8), barAcc.GetCoins().AmountOf("steak"), "%v", barAcc)
|
||||
|
||||
// declare candidacy
|
||||
declStr := fmt.Sprintf("gaiacli create-validator %v", flags)
|
||||
declStr += fmt.Sprintf(" --name=%v", "bar")
|
||||
declStr += fmt.Sprintf(" --validator-address=%v", bechVal)
|
||||
declStr += fmt.Sprintf(" --amount=%v", "3steak")
|
||||
declStr += fmt.Sprintf(" --moniker=%v", "bar-vally")
|
||||
fmt.Printf("debug declStr: %v\n", declStr)
|
||||
executeWrite(t, declStr, pass)
|
||||
time.Sleep(time.Second) // waiting for some blocks to pass
|
||||
barAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags))
|
||||
assert.Equal(t, int64(7), barAcc.GetCoins().AmountOf("steak"))
|
||||
candidate := executeGetCandidate(t, fmt.Sprintf("gaiacli candidate %v --address-candidate=%v", flags, barAddr))
|
||||
assert.Equal(t, candidate.Owner.String(), barAddr)
|
||||
assert.Equal(t, int64(3), candidate.PoolShares)
|
||||
validator := executeGetValidator(t, fmt.Sprintf("gaiacli validator %v --output=json %v", barCech, flags))
|
||||
assert.Equal(t, validator.Owner, barAddr)
|
||||
assert.Equal(t, "2/1", validator.PoolShares.Amount.String())
|
||||
|
||||
// TODO timeout issues if not connected to the internet
|
||||
// unbond a single share
|
||||
//unbondStr := fmt.Sprintf("gaiacli unbond %v", flags)
|
||||
//unbondStr += fmt.Sprintf(" --name=%v", "bar")
|
||||
//unbondStr += fmt.Sprintf(" --address-candidate=%v", barAddr)
|
||||
//unbondStr += fmt.Sprintf(" --address-delegator=%v", barAddr)
|
||||
//unbondStr += fmt.Sprintf(" --shares=%v", "1")
|
||||
//unbondStr += fmt.Sprintf(" --sequence=%v", "1")
|
||||
//fmt.Printf("debug unbondStr: %v\n", unbondStr)
|
||||
//executeWrite(t, unbondStr, pass)
|
||||
//time.Sleep(time.Second * 3) // waiting for some blocks to pass
|
||||
//barAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barAddr, flags))
|
||||
//assert.Equal(t, int64(99998), barAcc.GetCoins().AmountOf("steak"))
|
||||
//candidate = executeGetCandidate(t, fmt.Sprintf("gaiacli candidate %v --address-candidate=%v", flags, barAddr))
|
||||
//assert.Equal(t, int64(2), candidate.BondedShares.Evaluate())
|
||||
unbondStr := fmt.Sprintf("gaiacli unbond %v", flags)
|
||||
unbondStr += fmt.Sprintf(" --name=%v", "bar")
|
||||
unbondStr += fmt.Sprintf(" --address-validator=%v", barCech)
|
||||
unbondStr += fmt.Sprintf(" --address-delegator=%v", barCech)
|
||||
unbondStr += fmt.Sprintf(" --shares=%v", "1")
|
||||
unbondStr += fmt.Sprintf(" --sequence=%v", "1")
|
||||
t.Log(fmt.Sprintf("debug unbondStr: %v\n", unbondStr))
|
||||
|
||||
executeWrite(t, unbondStr, pass)
|
||||
time.Sleep(time.Second * 3) // waiting for some blocks to pass
|
||||
|
||||
barAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barCech, flags))
|
||||
require.Equal(t, int64(9), barAcc.GetCoins().AmountOf("steak"), "%v", barAcc)
|
||||
validator = executeGetValidator(t, fmt.Sprintf("gaiacli validator %v --output=json %v", barCech, flags))
|
||||
assert.Equal(t, "1/1", validator.PoolShares.Amount.String())
|
||||
}
|
||||
|
||||
//___________________________________________________________________________________
|
||||
// executors
|
||||
|
||||
func executeWrite(t *testing.T, cmdStr string, writes ...string) {
|
||||
cmd, wc, _ := tests.GoExecuteT(t, cmdStr)
|
||||
proc := tests.GoExecuteT(t, cmdStr)
|
||||
|
||||
for _, write := range writes {
|
||||
_, err := wc.Write([]byte(write + "\n"))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
_, err := proc.StdinPipe.Write([]byte(write + "\n"))
|
||||
require.NoError(t, err)
|
||||
}
|
||||
fmt.Printf("debug waiting cmdStr: %v\n", cmdStr)
|
||||
cmd.Wait()
|
||||
}
|
||||
|
||||
func executeWritePrint(t *testing.T, cmdStr string, writes ...string) {
|
||||
cmd, wc, rc := tests.GoExecuteT(t, cmdStr)
|
||||
|
||||
for _, write := range writes {
|
||||
_, err := wc.Write([]byte(write + "\n"))
|
||||
require.NoError(t, err)
|
||||
}
|
||||
fmt.Printf("debug waiting cmdStr: %v\n", cmdStr)
|
||||
cmd.Wait()
|
||||
|
||||
bz := make([]byte, 100000)
|
||||
rc.Read(bz)
|
||||
fmt.Printf("debug read: %v\n", string(bz))
|
||||
proc.Wait()
|
||||
}
|
||||
|
||||
func executeInit(t *testing.T, cmdStr string) (chainID string) {
|
||||
@ -187,6 +169,7 @@ func executeGetAddrPK(t *testing.T, cmdStr string) (sdk.Address, crypto.PubKey)
|
||||
out := tests.ExecuteT(t, cmdStr)
|
||||
var ko keys.KeyOutput
|
||||
keys.UnmarshalJSON([]byte(out), &ko)
|
||||
|
||||
return ko.Address, ko.PubKey
|
||||
}
|
||||
|
||||
@ -204,11 +187,11 @@ func executeGetAccount(t *testing.T, cmdStr string) auth.BaseAccount {
|
||||
return acc
|
||||
}
|
||||
|
||||
func executeGetCandidate(t *testing.T, cmdStr string) stake.Validator {
|
||||
func executeGetValidator(t *testing.T, cmdStr string) stake.Validator {
|
||||
out := tests.ExecuteT(t, cmdStr)
|
||||
var candidate stake.Validator
|
||||
var validator stake.Validator
|
||||
cdc := app.MakeCodec()
|
||||
err := cdc.UnmarshalJSON([]byte(out), &candidate)
|
||||
require.NoError(t, err, "out %v, err %v", out, err)
|
||||
return candidate
|
||||
err := cdc.UnmarshalJSON([]byte(out), &validator)
|
||||
require.NoError(t, err, "out %v\n, err %v", out, err)
|
||||
return validator
|
||||
}
|
||||
|
||||
@ -55,8 +55,8 @@ func main() {
|
||||
bankcmd.SendTxCmd(cdc),
|
||||
ibccmd.IBCTransferCmd(cdc),
|
||||
ibccmd.IBCRelayCmd(cdc),
|
||||
stakecmd.GetCmdDeclareCandidacy(cdc),
|
||||
stakecmd.GetCmdEditCandidacy(cdc),
|
||||
stakecmd.GetCmdCreateValidator(cdc),
|
||||
stakecmd.GetCmdEditValidator(cdc),
|
||||
stakecmd.GetCmdDelegate(cdc),
|
||||
stakecmd.GetCmdUnbond(cdc),
|
||||
)...)
|
||||
|
||||
@ -59,8 +59,8 @@ func main() {
|
||||
bankcmd.SendTxCmd(cdc),
|
||||
ibccmd.IBCTransferCmd(cdc),
|
||||
ibccmd.IBCRelayCmd(cdc),
|
||||
stakecmd.GetCmdDeclareCandidacy(cdc),
|
||||
stakecmd.GetCmdEditCandidacy(cdc),
|
||||
stakecmd.GetCmdCreateValidator(cdc),
|
||||
stakecmd.GetCmdEditValidator(cdc),
|
||||
stakecmd.GetCmdDelegate(cdc),
|
||||
stakecmd.GetCmdUnbond(cdc),
|
||||
)...)
|
||||
|
||||
@ -26,7 +26,7 @@ func NewMsgBond(addr sdk.Address, stake sdk.Coin, pubKey crypto.PubKey) MsgBond
|
||||
}
|
||||
|
||||
//nolint
|
||||
func (msg MsgBond) Type() string { return moduleName } //TODO update "stake/declarecandidacy"
|
||||
func (msg MsgBond) Type() string { return moduleName } //TODO update "stake/createvalidator"
|
||||
func (msg MsgBond) GetSigners() []sdk.Address { return []sdk.Address{msg.Address} }
|
||||
|
||||
// basic validation of the bond message
|
||||
@ -65,7 +65,7 @@ func NewMsgUnbond(addr sdk.Address) MsgUnbond {
|
||||
}
|
||||
|
||||
//nolint
|
||||
func (msg MsgUnbond) Type() string { return moduleName } //TODO update "stake/declarecandidacy"
|
||||
func (msg MsgUnbond) Type() string { return moduleName } //TODO update "stake/createvalidator"
|
||||
func (msg MsgUnbond) GetSigners() []sdk.Address { return []sdk.Address{msg.Address} }
|
||||
func (msg MsgUnbond) ValidateBasic() sdk.Error { return nil }
|
||||
|
||||
|
||||
@ -37,7 +37,9 @@ func TestStartStandAlone(t *testing.T) {
|
||||
|
||||
app, err := mock.NewApp(home, logger)
|
||||
require.Nil(t, err)
|
||||
svr, err := server.NewServer(FreeTCPAddr(t), "socket", app)
|
||||
svrAddr, _, err := FreeTCPAddr()
|
||||
require.Nil(t, err)
|
||||
svr, err := server.NewServer(svrAddr, "socket", app)
|
||||
require.Nil(t, err, "Error creating listener")
|
||||
svr.SetLogger(logger.With("module", "abci-server"))
|
||||
svr.Start()
|
||||
@ -69,7 +71,9 @@ func TestStartWithTendermint(t *testing.T) {
|
||||
// set up app and start up
|
||||
viper.Set(flagWithTendermint, true)
|
||||
startCmd := StartCmd(ctx, mock.NewApp)
|
||||
startCmd.Flags().Set(flagAddress, FreeTCPAddr(t)) // set to a new free address
|
||||
svrAddr, _, err := FreeTCPAddr()
|
||||
require.NoError(t, err)
|
||||
startCmd.Flags().Set(flagAddress, svrAddr) // set to a new free address
|
||||
timeout := time.Duration(5) * time.Second
|
||||
|
||||
close(RunOrTimeout(startCmd, timeout, t))
|
||||
|
||||
@ -16,14 +16,17 @@ import (
|
||||
|
||||
// Get a free address for a test tendermint server
|
||||
// protocol is either tcp, http, etc
|
||||
func FreeTCPAddr(t *testing.T) string {
|
||||
func FreeTCPAddr() (addr, port string, err error) {
|
||||
l, err := net.Listen("tcp", "0.0.0.0:0")
|
||||
defer l.Close()
|
||||
require.Nil(t, err)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
|
||||
port := l.Addr().(*net.TCPAddr).Port
|
||||
addr := fmt.Sprintf("tcp://0.0.0.0:%d", port)
|
||||
return addr
|
||||
portI := l.Addr().(*net.TCPAddr).Port
|
||||
port = fmt.Sprintf("%d", portI)
|
||||
addr = fmt.Sprintf("tcp://0.0.0.0:%s", port)
|
||||
return
|
||||
}
|
||||
|
||||
// setupViper creates a homedir to run inside,
|
||||
|
||||
104
tests/gobash.go
104
tests/gobash.go
@ -1,51 +1,91 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
func getCmd(t *testing.T, command string) *exec.Cmd {
|
||||
// Execute the command, return stdout, logging stdout/err to t.
|
||||
func ExecuteT(t *testing.T, cmd string) (out string) {
|
||||
t.Log("Running", cmn.Cyan(cmd))
|
||||
|
||||
//split command into command and args
|
||||
split := strings.Split(command, " ")
|
||||
// Split cmd to name and args.
|
||||
split := strings.Split(cmd, " ")
|
||||
require.True(t, len(split) > 0, "no command provided")
|
||||
|
||||
var cmd *exec.Cmd
|
||||
if len(split) == 1 {
|
||||
cmd = exec.Command(split[0])
|
||||
} else {
|
||||
cmd = exec.Command(split[0], split[1:]...)
|
||||
name, args := split[0], []string(nil)
|
||||
if len(split) > 1 {
|
||||
args = split[1:]
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
// Execute the command, return standard output and error, try a few times if requested
|
||||
func ExecuteT(t *testing.T, command string) (out string) {
|
||||
cmd := getCmd(t, command)
|
||||
bz, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
// Start process and wait.
|
||||
proc, err := StartProcess("", name, args, nil, nil)
|
||||
require.NoError(t, err)
|
||||
proc.Wait()
|
||||
|
||||
// Get the output.
|
||||
outbz := proc.StdoutBuffer.Bytes()
|
||||
errbz := proc.StderrBuffer.Bytes()
|
||||
|
||||
// Log output.
|
||||
if len(outbz) > 0 {
|
||||
t.Log("Stdout:", cmn.Green(string(outbz)))
|
||||
}
|
||||
require.NoError(t, err, string(bz))
|
||||
out = strings.Trim(string(bz), "\n") //trim any new lines
|
||||
time.Sleep(time.Second)
|
||||
if len(errbz) > 0 {
|
||||
t.Log("Stderr:", cmn.Red(string(errbz)))
|
||||
}
|
||||
|
||||
// Collect STDOUT output.
|
||||
out = strings.Trim(string(outbz), "\n") //trim any new lines
|
||||
return out
|
||||
}
|
||||
|
||||
// Asynchronously execute the command, return standard output and error
|
||||
func GoExecuteT(t *testing.T, command string) (cmd *exec.Cmd, pipeIn io.WriteCloser, pipeOut io.ReadCloser) {
|
||||
cmd = getCmd(t, command)
|
||||
pipeIn, err := cmd.StdinPipe()
|
||||
// Execute the command, launch goroutines to log stdout/err to t.
|
||||
// Caller should wait for .Wait() or .Stop() to terminate.
|
||||
func GoExecuteT(t *testing.T, cmd string) (proc *Process) {
|
||||
t.Log("Running", cmn.Cyan(cmd))
|
||||
|
||||
// Split cmd to name and args.
|
||||
split := strings.Split(cmd, " ")
|
||||
require.True(t, len(split) > 0, "no command provided")
|
||||
name, args := split[0], []string(nil)
|
||||
if len(split) > 1 {
|
||||
args = split[1:]
|
||||
}
|
||||
|
||||
// Start process.
|
||||
proc, err := StartProcess("", name, args, nil, nil)
|
||||
require.NoError(t, err)
|
||||
pipeOut, err = cmd.StdoutPipe()
|
||||
require.NoError(t, err)
|
||||
cmd.Start()
|
||||
time.Sleep(time.Second)
|
||||
return cmd, pipeIn, pipeOut
|
||||
|
||||
// Run goroutines to log stdout.
|
||||
go func() {
|
||||
buf := make([]byte, 10240) // TODO Document the effects.
|
||||
for {
|
||||
n, err := proc.StdoutBuffer.Read(buf)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if n > 0 {
|
||||
t.Log("Stdout:", cmn.Green(string(buf[:n])))
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// Run goroutines to log stderr.
|
||||
go func() {
|
||||
buf := make([]byte, 10240) // TODO Document the effects.
|
||||
for {
|
||||
n, err := proc.StderrBuffer.Read(buf)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if n > 0 {
|
||||
t.Log("Stderr:", cmn.Red(string(buf[:n])))
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return proc
|
||||
}
|
||||
|
||||
110
tests/process.go
Normal file
110
tests/process.go
Normal file
@ -0,0 +1,110 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"time"
|
||||
)
|
||||
|
||||
// execution process
|
||||
type Process struct {
|
||||
ExecPath string
|
||||
Args []string
|
||||
Pid int
|
||||
StartTime time.Time
|
||||
EndTime time.Time
|
||||
Cmd *exec.Cmd `json:"-"`
|
||||
ExitState *os.ProcessState `json:"-"`
|
||||
WaitCh chan struct{} `json:"-"`
|
||||
StdinPipe io.WriteCloser `json:"-"`
|
||||
StdoutBuffer *bytes.Buffer `json:"-"`
|
||||
StderrBuffer *bytes.Buffer `json:"-"`
|
||||
}
|
||||
|
||||
// dir: The working directory. If "", os.Getwd() is used.
|
||||
// name: Command name
|
||||
// args: Args to command. (should not include name)
|
||||
// outFile, errFile: If not nil, will use, otherwise new Buffers will be
|
||||
// allocated. Either way, Process.Cmd.StdoutPipe and Process.Cmd.StderrPipe will be nil
|
||||
// respectively.
|
||||
func StartProcess(dir string, name string, args []string, outFile, errFile io.WriteCloser) (*Process, error) {
|
||||
var cmd = exec.Command(name, args...) // is not yet started.
|
||||
// cmd dir
|
||||
if dir == "" {
|
||||
pwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
cmd.Dir = pwd
|
||||
} else {
|
||||
cmd.Dir = dir
|
||||
}
|
||||
// cmd stdin
|
||||
stdin, err := cmd.StdinPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// cmd stdout, stderr
|
||||
var outBuffer, errBuffer *bytes.Buffer
|
||||
if outFile != nil {
|
||||
cmd.Stdout = outFile
|
||||
} else {
|
||||
outBuffer = bytes.NewBuffer(nil)
|
||||
cmd.Stdout = outBuffer
|
||||
}
|
||||
if errFile != nil {
|
||||
cmd.Stderr = errFile
|
||||
} else {
|
||||
errBuffer = bytes.NewBuffer(nil)
|
||||
cmd.Stderr = errBuffer
|
||||
}
|
||||
// cmd start
|
||||
if err := cmd.Start(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
proc := &Process{
|
||||
ExecPath: name,
|
||||
Args: args,
|
||||
Pid: cmd.Process.Pid,
|
||||
StartTime: time.Now(),
|
||||
Cmd: cmd,
|
||||
ExitState: nil,
|
||||
WaitCh: make(chan struct{}),
|
||||
StdinPipe: stdin,
|
||||
}
|
||||
if outBuffer != nil {
|
||||
proc.StdoutBuffer = outBuffer
|
||||
}
|
||||
if errBuffer != nil {
|
||||
proc.StderrBuffer = errBuffer
|
||||
}
|
||||
go func() {
|
||||
err := proc.Cmd.Wait()
|
||||
if err != nil {
|
||||
// fmt.Printf("Process exit: %v\n", err)
|
||||
if exitError, ok := err.(*exec.ExitError); ok {
|
||||
proc.ExitState = exitError.ProcessState
|
||||
}
|
||||
}
|
||||
proc.ExitState = proc.Cmd.ProcessState
|
||||
proc.EndTime = time.Now() // TODO make this goroutine-safe
|
||||
close(proc.WaitCh)
|
||||
}()
|
||||
return proc, nil
|
||||
}
|
||||
|
||||
// stop the process
|
||||
func (proc *Process) Stop(kill bool) error {
|
||||
if kill {
|
||||
// fmt.Printf("Killing process %v\n", proc.Cmd.Process)
|
||||
return proc.Cmd.Process.Kill()
|
||||
}
|
||||
return proc.Cmd.Process.Signal(os.Interrupt)
|
||||
}
|
||||
|
||||
// wait for the process
|
||||
func (proc *Process) Wait() {
|
||||
<-proc.WaitCh
|
||||
}
|
||||
@ -9,7 +9,6 @@ import (
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
//"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -239,7 +238,9 @@ func StartNodeServerForTest(t *testing.T, home string) *exec.Cmd {
|
||||
// expects TestInitBaseCoin to have been run
|
||||
func StartLCDServerForTest(t *testing.T, home, chainID string) (cmd *exec.Cmd, port string) {
|
||||
cmdName := whereIsBasecli()
|
||||
port = strings.Split(server.FreeTCPAddr(t), ":")[2]
|
||||
var err error
|
||||
_, port, err = server.FreeTCPAddr()
|
||||
require.NoError(t, err)
|
||||
cmdArgs := []string{
|
||||
"rest-server",
|
||||
"--home",
|
||||
@ -252,7 +253,7 @@ func StartLCDServerForTest(t *testing.T, home, chainID string) (cmd *exec.Cmd, p
|
||||
cmd = exec.Command(cmdName, cmdArgs...)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
err := cmd.Start()
|
||||
err = cmd.Start()
|
||||
require.Nil(t, err)
|
||||
time.Sleep(time.Second * 2) // TODO: LOL
|
||||
return cmd, port
|
||||
|
||||
@ -11,16 +11,22 @@ import (
|
||||
rpcclient "github.com/tendermint/tendermint/rpc/lib/client"
|
||||
)
|
||||
|
||||
// TODO: these functions just print to Stdout.
|
||||
// consider using the logger.
|
||||
|
||||
// Uses localhost
|
||||
func WaitForHeight(height int64, port string) {
|
||||
for {
|
||||
var resultBlock ctypes.ResultBlock
|
||||
|
||||
url := fmt.Sprintf("http://localhost:%v%v", port, "/blocks/latest")
|
||||
res, err := http.Get(url)
|
||||
url := fmt.Sprintf("http://localhost:%v/blocks/latest", port)
|
||||
|
||||
// get url, try a few times
|
||||
var res *http.Response
|
||||
var err error
|
||||
for i := 0; i < 5; i++ {
|
||||
res, err = http.Get(url)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -31,6 +37,7 @@ func WaitForHeight(height int64, port string) {
|
||||
}
|
||||
res.Body.Close()
|
||||
|
||||
var resultBlock ctypes.ResultBlock
|
||||
err = cdc.UnmarshalJSON([]byte(body), &resultBlock)
|
||||
if err != nil {
|
||||
fmt.Println("RES", res)
|
||||
@ -45,45 +52,35 @@ func WaitForHeight(height int64, port string) {
|
||||
}
|
||||
}
|
||||
|
||||
// wait for 2 blocks.
|
||||
// uses localhost
|
||||
// wait for tendermint to start
|
||||
func WaitForStart(port string) {
|
||||
waitHeight := int64(2)
|
||||
for {
|
||||
var err error
|
||||
for i := 0; i < 5; i++ {
|
||||
time.Sleep(time.Second)
|
||||
|
||||
url := fmt.Sprintf("http://localhost:%v%v", port, "/blocks/latest")
|
||||
res, err := http.Get(url)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
url := fmt.Sprintf("http://localhost:%v/blocks/latest", port)
|
||||
|
||||
// get url, try a few times
|
||||
var res *http.Response
|
||||
res, err = http.Get(url)
|
||||
if err == nil || res == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// waiting for server to start ...
|
||||
if res.StatusCode != http.StatusOK {
|
||||
res.Body.Close()
|
||||
continue
|
||||
}
|
||||
|
||||
body, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
res.Body.Close()
|
||||
|
||||
resultBlock := new(ctypes.ResultBlock)
|
||||
err = cdc.UnmarshalJSON([]byte(body), &resultBlock)
|
||||
if err != nil {
|
||||
fmt.Println("RES", res)
|
||||
fmt.Println("BODY", string(body))
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if resultBlock.Block.Height >= waitHeight {
|
||||
return
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: these functions just print to Stdout.
|
||||
// consider using the logger.
|
||||
|
||||
// Wait for the RPC server to respond to /status
|
||||
func WaitForRPC(laddr string) {
|
||||
fmt.Println("LADDR", laddr)
|
||||
|
||||
@ -16,7 +16,7 @@ func TestHandleDoubleSign(t *testing.T) {
|
||||
// initial setup
|
||||
ctx, ck, sk, keeper := createTestInput(t)
|
||||
addr, val, amt := addrs[0], pks[0], int64(100)
|
||||
got := stake.NewHandler(sk)(ctx, newTestMsgDeclareCandidacy(addr, val, amt))
|
||||
got := stake.NewHandler(sk)(ctx, newTestMsgCreateValidator(addr, val, amt))
|
||||
require.True(t, got.IsOK())
|
||||
sk.Tick(ctx)
|
||||
require.Equal(t, ck.GetCoins(ctx, addr), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins - amt}})
|
||||
@ -39,7 +39,7 @@ func TestHandleAbsentValidator(t *testing.T) {
|
||||
addr, val, amt := addrs[0], pks[0], int64(100)
|
||||
sh := stake.NewHandler(sk)
|
||||
slh := NewHandler(keeper)
|
||||
got := sh(ctx, newTestMsgDeclareCandidacy(addr, val, amt))
|
||||
got := sh(ctx, newTestMsgCreateValidator(addr, val, amt))
|
||||
require.True(t, got.IsOK())
|
||||
sk.Tick(ctx)
|
||||
require.Equal(t, ck.GetCoins(ctx, addr), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins - amt}})
|
||||
|
||||
@ -85,8 +85,8 @@ func testAddr(addr string) sdk.Address {
|
||||
return res
|
||||
}
|
||||
|
||||
func newTestMsgDeclareCandidacy(address sdk.Address, pubKey crypto.PubKey, amt int64) stake.MsgDeclareCandidacy {
|
||||
return stake.MsgDeclareCandidacy{
|
||||
func newTestMsgCreateValidator(address sdk.Address, pubKey crypto.PubKey, amt int64) stake.MsgCreateValidator {
|
||||
return stake.MsgCreateValidator{
|
||||
Description: stake.Description{},
|
||||
ValidatorAddr: address,
|
||||
PubKey: pubKey,
|
||||
|
||||
@ -13,8 +13,8 @@ import (
|
||||
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||
)
|
||||
|
||||
// create declare candidacy command
|
||||
func GetCmdDeclareCandidacy(cdc *wire.Codec) *cobra.Command {
|
||||
// create create validator command
|
||||
func GetCmdCreateValidator(cdc *wire.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "create-validator",
|
||||
Short: "create new validator initialized with a self-delegation to it",
|
||||
@ -47,7 +47,7 @@ func GetCmdDeclareCandidacy(cdc *wire.Codec) *cobra.Command {
|
||||
Website: viper.GetString(FlagWebsite),
|
||||
Details: viper.GetString(FlagDetails),
|
||||
}
|
||||
msg := stake.NewMsgDeclareCandidacy(validatorAddr, pk, amount, description)
|
||||
msg := stake.NewMsgCreateValidator(validatorAddr, pk, amount, description)
|
||||
|
||||
// build and sign the transaction, then broadcast to Tendermint
|
||||
res, err := ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, msg, cdc)
|
||||
@ -67,8 +67,8 @@ func GetCmdDeclareCandidacy(cdc *wire.Codec) *cobra.Command {
|
||||
return cmd
|
||||
}
|
||||
|
||||
// create edit candidacy command
|
||||
func GetCmdEditCandidacy(cdc *wire.Codec) *cobra.Command {
|
||||
// create edit validator command
|
||||
func GetCmdEditValidator(cdc *wire.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "edit-validator",
|
||||
Short: "edit and existing validator account",
|
||||
@ -84,7 +84,7 @@ func GetCmdEditCandidacy(cdc *wire.Codec) *cobra.Command {
|
||||
Website: viper.GetString(FlagWebsite),
|
||||
Details: viper.GetString(FlagDetails),
|
||||
}
|
||||
msg := stake.NewMsgEditCandidacy(validatorAddr, description)
|
||||
msg := stake.NewMsgEditValidator(validatorAddr, description)
|
||||
|
||||
// build and sign the transaction, then broadcast to Tendermint
|
||||
ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc))
|
||||
@ -104,7 +104,7 @@ func GetCmdEditCandidacy(cdc *wire.Codec) *cobra.Command {
|
||||
return cmd
|
||||
}
|
||||
|
||||
// create edit candidacy command
|
||||
// create edit validator command
|
||||
func GetCmdDelegate(cdc *wire.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "delegate",
|
||||
@ -142,7 +142,7 @@ func GetCmdDelegate(cdc *wire.Codec) *cobra.Command {
|
||||
return cmd
|
||||
}
|
||||
|
||||
// create edit candidacy command
|
||||
// create edit validator command
|
||||
func GetCmdUnbond(cdc *wire.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "unbond",
|
||||
|
||||
@ -73,10 +73,10 @@ func ErrBadDelegatorAddr(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidValidator, "Delegator does not exist for that address")
|
||||
}
|
||||
func ErrValidatorExistsAddr(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidValidator, "Validator already exist, cannot re-declare candidacy")
|
||||
return newError(codespace, CodeInvalidValidator, "Validator already exist, cannot re-create validator")
|
||||
}
|
||||
func ErrValidatorRevoked(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidValidator, "Candidacy for this address is currently revoked")
|
||||
return newError(codespace, CodeInvalidValidator, "Validator for this address is currently revoked")
|
||||
}
|
||||
func ErrMissingSignature(codespace sdk.CodespaceType) sdk.Error {
|
||||
return newError(codespace, CodeInvalidValidator, "Missing signature")
|
||||
|
||||
@ -11,10 +11,10 @@ func NewHandler(k Keeper) sdk.Handler {
|
||||
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
|
||||
// NOTE msg already has validate basic run
|
||||
switch msg := msg.(type) {
|
||||
case MsgDeclareCandidacy:
|
||||
return handleMsgDeclareCandidacy(ctx, msg, k)
|
||||
case MsgEditCandidacy:
|
||||
return handleMsgEditCandidacy(ctx, msg, k)
|
||||
case MsgCreateValidator:
|
||||
return handleMsgCreateValidator(ctx, msg, k)
|
||||
case MsgEditValidator:
|
||||
return handleMsgEditValidator(ctx, msg, k)
|
||||
case MsgDelegate:
|
||||
return handleMsgDelegate(ctx, msg, k)
|
||||
case MsgUnbond:
|
||||
@ -39,7 +39,7 @@ func NewEndBlocker(k Keeper) sdk.EndBlocker {
|
||||
// These functions assume everything has been authenticated,
|
||||
// now we just perform action and save
|
||||
|
||||
func handleMsgDeclareCandidacy(ctx sdk.Context, msg MsgDeclareCandidacy, k Keeper) sdk.Result {
|
||||
func handleMsgCreateValidator(ctx sdk.Context, msg MsgCreateValidator, k Keeper) sdk.Result {
|
||||
|
||||
// check to see if the pubkey or sender has been registered before
|
||||
_, found := k.GetValidator(ctx, msg.ValidatorAddr)
|
||||
@ -57,7 +57,7 @@ func handleMsgDeclareCandidacy(ctx sdk.Context, msg MsgDeclareCandidacy, k Keepe
|
||||
k.setValidator(ctx, validator)
|
||||
k.setValidatorByPubKeyIndex(ctx, validator)
|
||||
tags := sdk.NewTags(
|
||||
"action", []byte("declareCandidacy"),
|
||||
"action", []byte("createValidator"),
|
||||
"validator", msg.ValidatorAddr.Bytes(),
|
||||
"moniker", []byte(msg.Description.Moniker),
|
||||
"identity", []byte(msg.Description.Identity),
|
||||
@ -75,7 +75,7 @@ func handleMsgDeclareCandidacy(ctx sdk.Context, msg MsgDeclareCandidacy, k Keepe
|
||||
}
|
||||
}
|
||||
|
||||
func handleMsgEditCandidacy(ctx sdk.Context, msg MsgEditCandidacy, k Keeper) sdk.Result {
|
||||
func handleMsgEditValidator(ctx sdk.Context, msg MsgEditValidator, k Keeper) sdk.Result {
|
||||
|
||||
// validator must already be registered
|
||||
validator, found := k.GetValidator(ctx, msg.ValidatorAddr)
|
||||
@ -95,7 +95,7 @@ func handleMsgEditCandidacy(ctx sdk.Context, msg MsgEditCandidacy, k Keeper) sdk
|
||||
|
||||
k.updateValidator(ctx, validator)
|
||||
tags := sdk.NewTags(
|
||||
"action", []byte("editCandidacy"),
|
||||
"action", []byte("editValidator"),
|
||||
"validator", msg.ValidatorAddr.Bytes(),
|
||||
"moniker", []byte(msg.Description.Moniker),
|
||||
"identity", []byte(msg.Description.Identity),
|
||||
@ -207,14 +207,14 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result {
|
||||
bond.Shares = bond.Shares.Sub(delShares)
|
||||
|
||||
// remove the bond
|
||||
revokeCandidacy := false
|
||||
revokeValidator := false
|
||||
if bond.Shares.IsZero() {
|
||||
|
||||
// if the bond is the owner of the validator then
|
||||
// trigger a revoke candidacy
|
||||
// trigger a revoke validator
|
||||
if bytes.Equal(bond.DelegatorAddr, validator.Owner) &&
|
||||
validator.Revoked == false {
|
||||
revokeCandidacy = true
|
||||
revokeValidator = true
|
||||
}
|
||||
|
||||
k.removeDelegation(ctx, bond)
|
||||
@ -233,7 +233,7 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result {
|
||||
|
||||
/////////////////////////////////////
|
||||
// revoke validator if necessary
|
||||
if revokeCandidacy {
|
||||
if revokeValidator {
|
||||
validator.Revoked = true
|
||||
}
|
||||
|
||||
|
||||
@ -14,8 +14,8 @@ import (
|
||||
|
||||
//______________________________________________________________________
|
||||
|
||||
func newTestMsgDeclareCandidacy(address sdk.Address, pubKey crypto.PubKey, amt int64) MsgDeclareCandidacy {
|
||||
return MsgDeclareCandidacy{
|
||||
func newTestMsgCreateValidator(address sdk.Address, pubKey crypto.PubKey, amt int64) MsgCreateValidator {
|
||||
return MsgCreateValidator{
|
||||
Description: Description{},
|
||||
ValidatorAddr: address,
|
||||
PubKey: pubKey,
|
||||
@ -33,13 +33,13 @@ func newTestMsgDelegate(delegatorAddr, validatorAddr sdk.Address, amt int64) Msg
|
||||
|
||||
//______________________________________________________________________
|
||||
|
||||
func TestDuplicatesMsgDeclareCandidacy(t *testing.T) {
|
||||
func TestDuplicatesMsgCreateValidator(t *testing.T) {
|
||||
ctx, _, keeper := createTestInput(t, false, 1000)
|
||||
|
||||
validatorAddr := addrs[0]
|
||||
pk := pks[0]
|
||||
msgDeclareCandidacy := newTestMsgDeclareCandidacy(validatorAddr, pk, 10)
|
||||
got := handleMsgDeclareCandidacy(ctx, msgDeclareCandidacy, keeper)
|
||||
msgCreateValidator := newTestMsgCreateValidator(validatorAddr, pk, 10)
|
||||
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
||||
assert.True(t, got.IsOK(), "%v", got)
|
||||
validator, found := keeper.GetValidator(ctx, validatorAddr)
|
||||
require.True(t, found)
|
||||
@ -51,8 +51,8 @@ func TestDuplicatesMsgDeclareCandidacy(t *testing.T) {
|
||||
assert.Equal(t, Description{}, validator.Description)
|
||||
|
||||
// one validator cannot bond twice
|
||||
msgDeclareCandidacy.PubKey = pks[1]
|
||||
got = handleMsgDeclareCandidacy(ctx, msgDeclareCandidacy, keeper)
|
||||
msgCreateValidator.PubKey = pks[1]
|
||||
got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
||||
assert.False(t, got.IsOK(), "%v", got)
|
||||
}
|
||||
|
||||
@ -64,10 +64,10 @@ func TestIncrementsMsgDelegate(t *testing.T) {
|
||||
bondAmount := int64(10)
|
||||
validatorAddr, delegatorAddr := addrs[0], addrs[1]
|
||||
|
||||
// first declare candidacy
|
||||
msgDeclareCandidacy := newTestMsgDeclareCandidacy(validatorAddr, pks[0], bondAmount)
|
||||
got := handleMsgDeclareCandidacy(ctx, msgDeclareCandidacy, keeper)
|
||||
assert.True(t, got.IsOK(), "expected declare candidacy msg to be ok, got %v", got)
|
||||
// first create validator
|
||||
msgCreateValidator := newTestMsgCreateValidator(validatorAddr, pks[0], bondAmount)
|
||||
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
||||
assert.True(t, got.IsOK(), "expected create validator msg to be ok, got %v", got)
|
||||
|
||||
validator, found := keeper.GetValidator(ctx, validatorAddr)
|
||||
require.True(t, found)
|
||||
@ -134,12 +134,12 @@ func TestIncrementsMsgUnbond(t *testing.T) {
|
||||
ctx, accMapper, keeper := createTestInput(t, false, initBond)
|
||||
params := keeper.GetParams(ctx)
|
||||
|
||||
// declare candidacy, delegate
|
||||
// create validator, delegate
|
||||
validatorAddr, delegatorAddr := addrs[0], addrs[1]
|
||||
|
||||
msgDeclareCandidacy := newTestMsgDeclareCandidacy(validatorAddr, pks[0], initBond)
|
||||
got := handleMsgDeclareCandidacy(ctx, msgDeclareCandidacy, keeper)
|
||||
assert.True(t, got.IsOK(), "expected declare-candidacy to be ok, got %v", got)
|
||||
msgCreateValidator := newTestMsgCreateValidator(validatorAddr, pks[0], initBond)
|
||||
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
||||
assert.True(t, got.IsOK(), "expected create-validator to be ok, got %v", got)
|
||||
|
||||
msgDelegate := newTestMsgDelegate(delegatorAddr, validatorAddr, initBond)
|
||||
got = handleMsgDelegate(ctx, msgDelegate, keeper)
|
||||
@ -216,7 +216,7 @@ func TestIncrementsMsgUnbond(t *testing.T) {
|
||||
"got: %v\nmsgUnbond: %v\nshares: %v\nleftBonded: %v\n", got, msgUnbond, unbondSharesStr, leftBonded)
|
||||
}
|
||||
|
||||
func TestMultipleMsgDeclareCandidacy(t *testing.T) {
|
||||
func TestMultipleMsgCreateValidator(t *testing.T) {
|
||||
initBond := int64(1000)
|
||||
ctx, accMapper, keeper := createTestInput(t, false, initBond)
|
||||
params := keeper.GetParams(ctx)
|
||||
@ -224,8 +224,8 @@ func TestMultipleMsgDeclareCandidacy(t *testing.T) {
|
||||
|
||||
// bond them all
|
||||
for i, validatorAddr := range validatorAddrs {
|
||||
msgDeclareCandidacy := newTestMsgDeclareCandidacy(validatorAddr, pks[i], 10)
|
||||
got := handleMsgDeclareCandidacy(ctx, msgDeclareCandidacy, keeper)
|
||||
msgCreateValidator := newTestMsgCreateValidator(validatorAddr, pks[i], 10)
|
||||
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
||||
require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got)
|
||||
|
||||
//Check that the account is bonded
|
||||
@ -266,8 +266,8 @@ func TestMultipleMsgDelegate(t *testing.T) {
|
||||
validatorAddr, delegatorAddrs := addrs[0], addrs[1:]
|
||||
|
||||
//first make a validator
|
||||
msgDeclareCandidacy := newTestMsgDeclareCandidacy(validatorAddr, pks[0], 10)
|
||||
got := handleMsgDeclareCandidacy(ctx, msgDeclareCandidacy, keeper)
|
||||
msgCreateValidator := newTestMsgCreateValidator(validatorAddr, pks[0], 10)
|
||||
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
||||
require.True(t, got.IsOK(), "expected msg to be ok, got %v", got)
|
||||
|
||||
// delegate multiple parties
|
||||
@ -294,14 +294,14 @@ func TestMultipleMsgDelegate(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestVoidCandidacy(t *testing.T) {
|
||||
func TestRevokeValidator(t *testing.T) {
|
||||
ctx, _, keeper := createTestInput(t, false, 1000)
|
||||
validatorAddr, delegatorAddr := addrs[0], addrs[1]
|
||||
|
||||
// create the validator
|
||||
msgDeclareCandidacy := newTestMsgDeclareCandidacy(validatorAddr, pks[0], 10)
|
||||
got := handleMsgDeclareCandidacy(ctx, msgDeclareCandidacy, keeper)
|
||||
require.True(t, got.IsOK(), "expected no error on runMsgDeclareCandidacy")
|
||||
msgCreateValidator := newTestMsgCreateValidator(validatorAddr, pks[0], 10)
|
||||
got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
||||
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
|
||||
|
||||
// bond a delegator
|
||||
msgDelegate := newTestMsgDelegate(delegatorAddr, validatorAddr, 10)
|
||||
@ -311,7 +311,7 @@ func TestVoidCandidacy(t *testing.T) {
|
||||
// unbond the validators bond portion
|
||||
msgUnbondValidator := NewMsgUnbond(validatorAddr, validatorAddr, "10")
|
||||
got = handleMsgUnbond(ctx, msgUnbondValidator, keeper)
|
||||
require.True(t, got.IsOK(), "expected no error on runMsgDeclareCandidacy")
|
||||
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
|
||||
validator, found := keeper.GetValidator(ctx, validatorAddr)
|
||||
require.True(t, found)
|
||||
require.True(t, validator.Revoked)
|
||||
@ -323,9 +323,9 @@ func TestVoidCandidacy(t *testing.T) {
|
||||
// test that the delegator can still withdraw their bonds
|
||||
msgUnbondDelegator := NewMsgUnbond(delegatorAddr, validatorAddr, "10")
|
||||
got = handleMsgUnbond(ctx, msgUnbondDelegator, keeper)
|
||||
require.True(t, got.IsOK(), "expected no error on runMsgDeclareCandidacy")
|
||||
require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator")
|
||||
|
||||
// verify that the pubkey can now be reused
|
||||
got = handleMsgDeclareCandidacy(ctx, msgDeclareCandidacy, keeper)
|
||||
got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
|
||||
assert.True(t, got.IsOK(), "expected ok, got %v", got)
|
||||
}
|
||||
|
||||
@ -15,21 +15,21 @@ const MsgType = "stake"
|
||||
const StakingToken = "steak"
|
||||
|
||||
//Verify interface at compile time
|
||||
var _, _, _, _ sdk.Msg = &MsgDeclareCandidacy{}, &MsgEditCandidacy{}, &MsgDelegate{}, &MsgUnbond{}
|
||||
var _, _, _, _ sdk.Msg = &MsgCreateValidator{}, &MsgEditValidator{}, &MsgDelegate{}, &MsgUnbond{}
|
||||
|
||||
//______________________________________________________________________
|
||||
|
||||
// MsgDeclareCandidacy - struct for unbonding transactions
|
||||
type MsgDeclareCandidacy struct {
|
||||
// MsgCreateValidator - struct for unbonding transactions
|
||||
type MsgCreateValidator struct {
|
||||
Description
|
||||
ValidatorAddr sdk.Address `json:"address"`
|
||||
PubKey crypto.PubKey `json:"pubkey"`
|
||||
Bond sdk.Coin `json:"bond"`
|
||||
}
|
||||
|
||||
func NewMsgDeclareCandidacy(validatorAddr sdk.Address, pubkey crypto.PubKey,
|
||||
bond sdk.Coin, description Description) MsgDeclareCandidacy {
|
||||
return MsgDeclareCandidacy{
|
||||
func NewMsgCreateValidator(validatorAddr sdk.Address, pubkey crypto.PubKey,
|
||||
bond sdk.Coin, description Description) MsgCreateValidator {
|
||||
return MsgCreateValidator{
|
||||
Description: description,
|
||||
ValidatorAddr: validatorAddr,
|
||||
PubKey: pubkey,
|
||||
@ -38,18 +38,18 @@ func NewMsgDeclareCandidacy(validatorAddr sdk.Address, pubkey crypto.PubKey,
|
||||
}
|
||||
|
||||
//nolint
|
||||
func (msg MsgDeclareCandidacy) Type() string { return MsgType } //TODO update "stake/declarecandidacy"
|
||||
func (msg MsgDeclareCandidacy) GetSigners() []sdk.Address {
|
||||
func (msg MsgCreateValidator) Type() string { return MsgType }
|
||||
func (msg MsgCreateValidator) GetSigners() []sdk.Address {
|
||||
return []sdk.Address{msg.ValidatorAddr}
|
||||
}
|
||||
|
||||
// get the bytes for the message signer to sign on
|
||||
func (msg MsgDeclareCandidacy) GetSignBytes() []byte {
|
||||
func (msg MsgCreateValidator) GetSignBytes() []byte {
|
||||
return msgCdc.MustMarshalBinary(msg)
|
||||
}
|
||||
|
||||
// quick validity check
|
||||
func (msg MsgDeclareCandidacy) ValidateBasic() sdk.Error {
|
||||
func (msg MsgCreateValidator) ValidateBasic() sdk.Error {
|
||||
if msg.ValidatorAddr == nil {
|
||||
return ErrValidatorEmpty(DefaultCodespace)
|
||||
}
|
||||
@ -68,27 +68,27 @@ func (msg MsgDeclareCandidacy) ValidateBasic() sdk.Error {
|
||||
|
||||
//______________________________________________________________________
|
||||
|
||||
// MsgEditCandidacy - struct for editing a validator
|
||||
type MsgEditCandidacy struct {
|
||||
// MsgEditValidator - struct for editing a validator
|
||||
type MsgEditValidator struct {
|
||||
Description
|
||||
ValidatorAddr sdk.Address `json:"address"`
|
||||
}
|
||||
|
||||
func NewMsgEditCandidacy(validatorAddr sdk.Address, description Description) MsgEditCandidacy {
|
||||
return MsgEditCandidacy{
|
||||
func NewMsgEditValidator(validatorAddr sdk.Address, description Description) MsgEditValidator {
|
||||
return MsgEditValidator{
|
||||
Description: description,
|
||||
ValidatorAddr: validatorAddr,
|
||||
}
|
||||
}
|
||||
|
||||
//nolint
|
||||
func (msg MsgEditCandidacy) Type() string { return MsgType } //TODO update "stake/msgeditcandidacy"
|
||||
func (msg MsgEditCandidacy) GetSigners() []sdk.Address {
|
||||
func (msg MsgEditValidator) Type() string { return MsgType }
|
||||
func (msg MsgEditValidator) GetSigners() []sdk.Address {
|
||||
return []sdk.Address{msg.ValidatorAddr}
|
||||
}
|
||||
|
||||
// get the bytes for the message signer to sign on
|
||||
func (msg MsgEditCandidacy) GetSignBytes() []byte {
|
||||
func (msg MsgEditValidator) GetSignBytes() []byte {
|
||||
b, err := msgCdc.MarshalJSON(msg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@ -97,7 +97,7 @@ func (msg MsgEditCandidacy) GetSignBytes() []byte {
|
||||
}
|
||||
|
||||
// quick validity check
|
||||
func (msg MsgEditCandidacy) ValidateBasic() sdk.Error {
|
||||
func (msg MsgEditValidator) ValidateBasic() sdk.Error {
|
||||
if msg.ValidatorAddr == nil {
|
||||
return ErrValidatorEmpty(DefaultCodespace)
|
||||
}
|
||||
@ -126,7 +126,7 @@ func NewMsgDelegate(delegatorAddr, validatorAddr sdk.Address, bond sdk.Coin) Msg
|
||||
}
|
||||
|
||||
//nolint
|
||||
func (msg MsgDelegate) Type() string { return MsgType } //TODO update "stake/msgeditcandidacy"
|
||||
func (msg MsgDelegate) Type() string { return MsgType }
|
||||
func (msg MsgDelegate) GetSigners() []sdk.Address {
|
||||
return []sdk.Address{msg.DelegatorAddr}
|
||||
}
|
||||
@ -175,7 +175,7 @@ func NewMsgUnbond(delegatorAddr, validatorAddr sdk.Address, shares string) MsgUn
|
||||
}
|
||||
|
||||
//nolint
|
||||
func (msg MsgUnbond) Type() string { return MsgType } //TODO update "stake/msgeditcandidacy"
|
||||
func (msg MsgUnbond) Type() string { return MsgType }
|
||||
func (msg MsgUnbond) GetSigners() []sdk.Address { return []sdk.Address{msg.DelegatorAddr} }
|
||||
|
||||
// get the bytes for the message signer to sign on
|
||||
|
||||
@ -18,8 +18,8 @@ var (
|
||||
coinNegNotAtoms = sdk.Coin{"foo", -10000}
|
||||
)
|
||||
|
||||
// test ValidateBasic for MsgDeclareCandidacy
|
||||
func TestMsgDeclareCandidacy(t *testing.T) {
|
||||
// test ValidateBasic for MsgCreateValidator
|
||||
func TestMsgCreateValidator(t *testing.T) {
|
||||
tests := []struct {
|
||||
name, moniker, identity, website, details string
|
||||
validatorAddr sdk.Address
|
||||
@ -40,7 +40,7 @@ func TestMsgDeclareCandidacy(t *testing.T) {
|
||||
|
||||
for _, tc := range tests {
|
||||
description := NewDescription(tc.moniker, tc.identity, tc.website, tc.details)
|
||||
msg := NewMsgDeclareCandidacy(tc.validatorAddr, tc.pubkey, tc.bond, description)
|
||||
msg := NewMsgCreateValidator(tc.validatorAddr, tc.pubkey, tc.bond, description)
|
||||
if tc.expectPass {
|
||||
assert.Nil(t, msg.ValidateBasic(), "test: %v", tc.name)
|
||||
} else {
|
||||
@ -49,8 +49,8 @@ func TestMsgDeclareCandidacy(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// test ValidateBasic for MsgEditCandidacy
|
||||
func TestMsgEditCandidacy(t *testing.T) {
|
||||
// test ValidateBasic for MsgEditValidator
|
||||
func TestMsgEditValidator(t *testing.T) {
|
||||
tests := []struct {
|
||||
name, moniker, identity, website, details string
|
||||
validatorAddr sdk.Address
|
||||
@ -64,7 +64,7 @@ func TestMsgEditCandidacy(t *testing.T) {
|
||||
|
||||
for _, tc := range tests {
|
||||
description := NewDescription(tc.moniker, tc.identity, tc.website, tc.details)
|
||||
msg := NewMsgEditCandidacy(tc.validatorAddr, description)
|
||||
msg := NewMsgEditValidator(tc.validatorAddr, description)
|
||||
if tc.expectPass {
|
||||
assert.Nil(t, msg.ValidateBasic(), "test: %v", tc.name)
|
||||
} else {
|
||||
@ -139,8 +139,8 @@ func TestMsgUnbond(t *testing.T) {
|
||||
//tests := []struct {
|
||||
//tx sdk.Msg
|
||||
//}{
|
||||
//{NewMsgDeclareCandidacy(addrs[0], pks[0], bond, Description{})},
|
||||
//{NewMsgEditCandidacy(addrs[0], Description{})},
|
||||
//{NewMsgCreateValidator(addrs[0], pks[0], bond, Description{})},
|
||||
//{NewMsgEditValidator(addrs[0], Description{})},
|
||||
//{NewMsgDelegate(addrs[0], addrs[1], bond)},
|
||||
//{NewMsgUnbond(addrs[0], addrs[1], strconv.Itoa(bondAmt))},
|
||||
//}
|
||||
|
||||
@ -68,8 +68,8 @@ func makeTestCodec() *wire.Codec {
|
||||
cdc.RegisterInterface((*sdk.Msg)(nil), nil)
|
||||
cdc.RegisterConcrete(bank.MsgSend{}, "test/stake/Send", nil)
|
||||
cdc.RegisterConcrete(bank.MsgIssue{}, "test/stake/Issue", nil)
|
||||
cdc.RegisterConcrete(MsgDeclareCandidacy{}, "test/stake/DeclareCandidacy", nil)
|
||||
cdc.RegisterConcrete(MsgEditCandidacy{}, "test/stake/EditCandidacy", nil)
|
||||
cdc.RegisterConcrete(MsgCreateValidator{}, "test/stake/CreateValidator", nil)
|
||||
cdc.RegisterConcrete(MsgEditValidator{}, "test/stake/EditValidator", nil)
|
||||
cdc.RegisterConcrete(MsgUnbond{}, "test/stake/Unbond", nil)
|
||||
|
||||
// Register AppAccount
|
||||
|
||||
@ -6,8 +6,8 @@ import (
|
||||
|
||||
// Register concrete types on wire codec
|
||||
func RegisterWire(cdc *wire.Codec) {
|
||||
cdc.RegisterConcrete(MsgDeclareCandidacy{}, "cosmos-sdk/MsgDeclareCandidacy", nil)
|
||||
cdc.RegisterConcrete(MsgEditCandidacy{}, "cosmos-sdk/MsgEditCandidacy", nil)
|
||||
cdc.RegisterConcrete(MsgCreateValidator{}, "cosmos-sdk/MsgCreateValidator", nil)
|
||||
cdc.RegisterConcrete(MsgEditValidator{}, "cosmos-sdk/MsgEditValidator", nil)
|
||||
cdc.RegisterConcrete(MsgDelegate{}, "cosmos-sdk/MsgDelegate", nil)
|
||||
cdc.RegisterConcrete(MsgUnbond{}, "cosmos-sdk/MsgUnbond", nil)
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user