Merge branch 'develop' into rigel/stake-spec-compliance
This commit is contained in:
commit
f50c7be976
|
@ -83,7 +83,7 @@ jobs:
|
|||
name: Test cli
|
||||
command: |
|
||||
export PATH="$GOBIN:$PATH"
|
||||
make test_cli_retry
|
||||
make test_cli
|
||||
|
||||
test_cover:
|
||||
<<: *defaults
|
||||
|
|
|
@ -82,6 +82,7 @@ IMPROVEMENTS
|
|||
* added contributing guidelines
|
||||
|
||||
BUG FIXES
|
||||
* [x/slashing] \#1510 Unrevoked validators cannot un-revoke themselves
|
||||
* [gaia] Added self delegation for validators in the genesis creation
|
||||
* [lcd] tests now don't depend on raw json text
|
||||
* [stake] error strings lower case
|
||||
|
|
45
Dockerfile
45
Dockerfile
|
@ -1,34 +1,35 @@
|
|||
# Simple usage with a mounted data directory:
|
||||
# > docker build -t gaia .
|
||||
# > docker run -v $HOME/.gaiad:/root/.gaiad gaia init
|
||||
# > docker run -v $HOME/.gaiad:/root/.gaiad gaia start
|
||||
|
||||
FROM alpine:edge
|
||||
# > docker run -it -p 46657:46657 -p 46656:46656 -v ~/.gaiad:/root/.gaiad -v ~/.gaiacli:/root/.gaiacli gaia gaiad init
|
||||
# > docker run -it -p 46657:46657 -p 46656:46656 -v ~/.gaiad:/root/.gaiad -v ~/.gaiacli:/root/.gaiacli gaia gaiad start
|
||||
FROM golang:alpine AS build-env
|
||||
|
||||
# Set up dependencies
|
||||
ENV PACKAGES go glide make git libc-dev bash
|
||||
ENV PACKAGES make git libc-dev bash gcc linux-headers eudev-dev
|
||||
|
||||
# Set up GOPATH & PATH
|
||||
|
||||
ENV GOPATH /root/go
|
||||
ENV BASE_PATH $GOPATH/src/github.com/cosmos
|
||||
ENV REPO_PATH $BASE_PATH/cosmos-sdk
|
||||
ENV WORKDIR /cosmos/
|
||||
ENV PATH $GOPATH/bin:$PATH
|
||||
|
||||
# Link expected Go repo path
|
||||
|
||||
RUN mkdir -p $WORKDIR $GOPATH/pkg $ $GOPATH/bin $BASE_PATH
|
||||
# Set working directory for the build
|
||||
WORKDIR /go/src/github.com/cosmos/cosmos-sdk
|
||||
|
||||
# Add source files
|
||||
|
||||
ADD . $REPO_PATH
|
||||
COPY . .
|
||||
|
||||
# Install minimum necessary dependencies, build Cosmos SDK, remove packages
|
||||
RUN apk add --no-cache $PACKAGES && \
|
||||
cd $REPO_PATH && make get_tools && make get_vendor_deps && make build && make install && \
|
||||
apk del $PACKAGES
|
||||
make get_tools && \
|
||||
make get_vendor_deps && \
|
||||
make build && \
|
||||
make install
|
||||
|
||||
# Set entrypoint
|
||||
# Final image
|
||||
FROM alpine:edge
|
||||
|
||||
ENTRYPOINT ["gaiad"]
|
||||
# Install ca-certificates
|
||||
RUN apk add --update ca-certificates
|
||||
WORKDIR /root
|
||||
|
||||
# Copy over binaries from the build-env
|
||||
COPY --from=build-env /go/bin/gaiad /usr/bin/gaiad
|
||||
COPY --from=build-env /go/bin/gaiacli /usr/bin/gaiacli
|
||||
|
||||
# Run gaiad by default, omit entrypoint to ease using container with gaiacli
|
||||
CMD ["gaiad"]
|
||||
|
|
6
Makefile
6
Makefile
|
@ -92,15 +92,9 @@ test: test_unit
|
|||
test_cli:
|
||||
@go test -count 1 -p 1 `go list github.com/cosmos/cosmos-sdk/cmd/gaia/cli_test`
|
||||
|
||||
test_cli_retry:
|
||||
for i in 1 2 3; do make test_cli && break || sleep 2; done
|
||||
|
||||
test_unit:
|
||||
@go test $(PACKAGES_NOCLITEST)
|
||||
|
||||
test_unit_retry:
|
||||
for i in 1 2 3; do make test_unit && break || sleep 2; done
|
||||
|
||||
test_race:
|
||||
@go test -race $(PACKAGES_NOCLITEST)
|
||||
|
||||
|
|
|
@ -11,10 +11,10 @@ import (
|
|||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
dbm "github.com/tendermint/tendermint/libs/db"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
|
|
|
@ -9,9 +9,9 @@ import (
|
|||
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
rpcclient "github.com/tendermint/tendermint/rpc/client"
|
||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/keys"
|
||||
|
@ -141,13 +141,22 @@ func (ctx CoreContext) SignAndBuild(name, passphrase string, msgs []sdk.Msg, cdc
|
|||
sequence := ctx.Sequence
|
||||
memo := ctx.Memo
|
||||
|
||||
fee := sdk.Coin{}
|
||||
if ctx.Fee != "" {
|
||||
parsedFee, err := sdk.ParseCoin(ctx.Fee)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fee = parsedFee
|
||||
}
|
||||
|
||||
signMsg := auth.StdSignMsg{
|
||||
ChainID: chainID,
|
||||
AccountNumber: accnum,
|
||||
Sequence: sequence,
|
||||
Msgs: msgs,
|
||||
Memo: memo,
|
||||
Fee: auth.NewStdFee(ctx.Gas, sdk.Coin{}), // TODO run simulate to estimate gas?
|
||||
Fee: auth.NewStdFee(ctx.Gas, fee), // TODO run simulate to estimate gas?
|
||||
}
|
||||
|
||||
keybase, err := keys.GetKeyBase()
|
||||
|
|
|
@ -11,6 +11,7 @@ type CoreContext struct {
|
|||
ChainID string
|
||||
Height int64
|
||||
Gas int64
|
||||
Fee string
|
||||
TrustNode bool
|
||||
NodeURI string
|
||||
FromAddressName string
|
||||
|
@ -41,6 +42,12 @@ func (c CoreContext) WithGas(gas int64) CoreContext {
|
|||
return c
|
||||
}
|
||||
|
||||
// WithFee - return a copy of the context with an updated fee
|
||||
func (c CoreContext) WithFee(fee string) CoreContext {
|
||||
c.Fee = fee
|
||||
return c
|
||||
}
|
||||
|
||||
// WithTrustNode - return a copy of the context with an updated TrustNode flag
|
||||
func (c CoreContext) WithTrustNode(trustNode bool) CoreContext {
|
||||
c.TrustNode = trustNode
|
||||
|
|
|
@ -31,6 +31,7 @@ func NewCoreContextFromViper() CoreContext {
|
|||
ChainID: chainID,
|
||||
Height: viper.GetInt64(client.FlagHeight),
|
||||
Gas: viper.GetInt64(client.FlagGas),
|
||||
Fee: viper.GetString(client.FlagFee),
|
||||
TrustNode: viper.GetBool(client.FlagTrustNode),
|
||||
FromAddressName: viper.GetString(client.FlagName),
|
||||
NodeURI: nodeURI,
|
||||
|
|
|
@ -13,9 +13,9 @@ import (
|
|||
|
||||
cryptoKeys "github.com/cosmos/cosmos-sdk/crypto/keys"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/libs/common"
|
||||
p2p "github.com/tendermint/tendermint/p2p"
|
||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||
"github.com/tendermint/tendermint/libs/common"
|
||||
|
||||
client "github.com/cosmos/cosmos-sdk/client"
|
||||
keys "github.com/cosmos/cosmos-sdk/client/keys"
|
||||
|
|
|
@ -9,8 +9,8 @@ import (
|
|||
"github.com/spf13/viper"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
|
||||
tmserver "github.com/tendermint/tendermint/rpc/lib/server"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
tmserver "github.com/tendermint/tendermint/rpc/lib/server"
|
||||
|
||||
client "github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
|
|
|
@ -19,14 +19,14 @@ import (
|
|||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
tmcfg "github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"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"
|
||||
"github.com/tendermint/tendermint/libs/cli"
|
||||
dbm "github.com/tendermint/tendermint/libs/db"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
keys "github.com/cosmos/cosmos-sdk/client/keys"
|
||||
|
@ -169,7 +169,7 @@ func InitializeTestLCD(t *testing.T, nValidators int, initAddrs []sdk.Address) (
|
|||
|
||||
//time.Sleep(time.Second)
|
||||
//tests.WaitForHeight(2, port)
|
||||
tests.WaitForStart(port)
|
||||
tests.WaitForLCDStart(port)
|
||||
tests.WaitForHeight(1, port)
|
||||
|
||||
// for use in defer
|
||||
|
|
|
@ -5,10 +5,10 @@ import (
|
|||
"os"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
dbm "github.com/tendermint/tendermint/libs/db"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
|
||||
bam "github.com/cosmos/cosmos-sdk/baseapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
@ -37,12 +37,13 @@ type GaiaApp 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
|
||||
keyIBC *sdk.KVStoreKey
|
||||
keyStake *sdk.KVStoreKey
|
||||
keySlashing *sdk.KVStoreKey
|
||||
keyGov *sdk.KVStoreKey
|
||||
keyFeeCollection *sdk.KVStoreKey
|
||||
|
||||
// Manage getting and setting accounts
|
||||
accountMapper auth.AccountMapper
|
||||
|
@ -59,14 +60,15 @@ func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp {
|
|||
|
||||
// create your application object
|
||||
var app = &GaiaApp{
|
||||
BaseApp: bam.NewBaseApp(appName, cdc, logger, db),
|
||||
cdc: cdc,
|
||||
keyMain: sdk.NewKVStoreKey("main"),
|
||||
keyAccount: sdk.NewKVStoreKey("acc"),
|
||||
keyIBC: sdk.NewKVStoreKey("ibc"),
|
||||
keyStake: sdk.NewKVStoreKey("stake"),
|
||||
keySlashing: sdk.NewKVStoreKey("slashing"),
|
||||
keyGov: sdk.NewKVStoreKey("gov"),
|
||||
BaseApp: bam.NewBaseApp(appName, cdc, logger, db),
|
||||
cdc: cdc,
|
||||
keyMain: sdk.NewKVStoreKey("main"),
|
||||
keyAccount: sdk.NewKVStoreKey("acc"),
|
||||
keyIBC: sdk.NewKVStoreKey("ibc"),
|
||||
keyStake: sdk.NewKVStoreKey("stake"),
|
||||
keySlashing: sdk.NewKVStoreKey("slashing"),
|
||||
keyGov: sdk.NewKVStoreKey("gov"),
|
||||
keyFeeCollection: sdk.NewKVStoreKey("fee"),
|
||||
}
|
||||
|
||||
// define the accountMapper
|
||||
|
@ -82,6 +84,7 @@ func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp {
|
|||
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)
|
||||
|
||||
// register message routes
|
||||
app.Router().
|
||||
|
@ -96,7 +99,7 @@ func NewGaiaApp(logger log.Logger, db dbm.DB) *GaiaApp {
|
|||
app.SetBeginBlocker(app.BeginBlocker)
|
||||
app.SetEndBlocker(app.EndBlocker)
|
||||
app.SetAnteHandler(auth.NewAnteHandler(app.accountMapper, app.feeCollectionKeeper))
|
||||
app.MountStoresIAVL(app.keyMain, app.keyAccount, app.keyIBC, app.keyStake, app.keySlashing, app.keyGov)
|
||||
app.MountStoresIAVL(app.keyMain, app.keyAccount, app.keyIBC, app.keyStake, app.keySlashing, app.keyGov, app.keyFeeCollection)
|
||||
err := app.LoadLatestVersion(app.keyMain)
|
||||
if err != nil {
|
||||
cmn.Exit(err.Error())
|
||||
|
|
|
@ -7,6 +7,9 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client/keys"
|
||||
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
|
@ -16,7 +19,6 @@ import (
|
|||
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||
"github.com/cosmos/cosmos-sdk/x/gov"
|
||||
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
)
|
||||
|
||||
func TestGaiaCLISend(t *testing.T) {
|
||||
|
@ -34,9 +36,10 @@ func TestGaiaCLISend(t *testing.T) {
|
|||
flags := fmt.Sprintf("--node=%v --chain-id=%v", servAddr, chainID)
|
||||
|
||||
// start gaiad server
|
||||
proc := tests.GoExecuteT(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr))
|
||||
proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr))
|
||||
defer proc.Stop(false)
|
||||
tests.WaitForStart(port)
|
||||
tests.WaitForTMStart(port)
|
||||
tests.WaitForNextHeightTM(port)
|
||||
|
||||
fooAddr, _ := executeGetAddrPK(t, "gaiacli keys show foo --output=json")
|
||||
fooCech, err := sdk.Bech32ifyAcc(fooAddr)
|
||||
|
@ -90,9 +93,10 @@ func TestGaiaCLICreateValidator(t *testing.T) {
|
|||
flags := fmt.Sprintf("--node=%v --chain-id=%v", servAddr, chainID)
|
||||
|
||||
// start gaiad server
|
||||
proc := tests.GoExecuteT(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr))
|
||||
proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr))
|
||||
defer proc.Stop(false)
|
||||
tests.WaitForStart(port)
|
||||
tests.WaitForTMStart(port)
|
||||
tests.WaitForNextHeightTM(port)
|
||||
|
||||
fooAddr, _ := executeGetAddrPK(t, "gaiacli keys show foo --output=json")
|
||||
fooCech, err := sdk.Bech32ifyAcc(fooAddr)
|
||||
|
@ -130,19 +134,20 @@ func TestGaiaCLICreateValidator(t *testing.T) {
|
|||
require.Equal(t, "2/1", validator.PoolShares.Amount.String())
|
||||
|
||||
// unbond a single share
|
||||
unbondStr := fmt.Sprintf("gaiacli stake unbond %v", flags)
|
||||
unbondStr := fmt.Sprintf("gaiacli stake unbond begin %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))
|
||||
unbondStr += fmt.Sprintf(" --shares-amount=%v", "1")
|
||||
|
||||
executeWrite(t, unbondStr, pass)
|
||||
success := executeWrite(t, unbondStr, pass)
|
||||
require.True(t, success)
|
||||
tests.WaitForNextHeightTM(port)
|
||||
|
||||
/* // this won't be what we expect because we've only started unbonding, haven't completed
|
||||
barAcc = executeGetAccount(t, fmt.Sprintf("gaiacli account %v %v", barCech, flags))
|
||||
require.Equal(t, int64(9), barAcc.GetCoins().AmountOf("steak").Int64(), "%v", barAcc)
|
||||
*/
|
||||
validator = executeGetValidator(t, fmt.Sprintf("gaiacli stake validator %v --output=json %v", barCech, flags))
|
||||
require.Equal(t, "1/1", validator.PoolShares.Amount.String())
|
||||
}
|
||||
|
@ -162,9 +167,10 @@ func TestGaiaCLISubmitProposal(t *testing.T) {
|
|||
flags := fmt.Sprintf("--node=%v --chain-id=%v", servAddr, chainID)
|
||||
|
||||
// start gaiad server
|
||||
proc := tests.GoExecuteT(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr))
|
||||
proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("gaiad start --rpc.laddr=%v", servAddr))
|
||||
defer proc.Stop(false)
|
||||
tests.WaitForStart(port)
|
||||
tests.WaitForTMStart(port)
|
||||
tests.WaitForNextHeightTM(port)
|
||||
|
||||
fooAddr, _ := executeGetAddrPK(t, "gaiacli keys show foo --output=json")
|
||||
fooCech, err := sdk.Bech32ifyAcc(fooAddr)
|
||||
|
@ -203,14 +209,27 @@ func TestGaiaCLISubmitProposal(t *testing.T) {
|
|||
//___________________________________________________________________________________
|
||||
// executors
|
||||
|
||||
func executeWrite(t *testing.T, cmdStr string, writes ...string) {
|
||||
func executeWrite(t *testing.T, cmdStr string, writes ...string) bool {
|
||||
proc := tests.GoExecuteT(t, cmdStr)
|
||||
|
||||
for _, write := range writes {
|
||||
_, err := proc.StdinPipe.Write([]byte(write + "\n"))
|
||||
require.NoError(t, err)
|
||||
}
|
||||
stdout, stderr, err := proc.ReadAll()
|
||||
if err != nil {
|
||||
fmt.Println("Err on proc.ReadAll()", err, cmdStr)
|
||||
}
|
||||
// Log output.
|
||||
if len(stdout) > 0 {
|
||||
t.Log("Stdout:", cmn.Green(string(stdout)))
|
||||
}
|
||||
if len(stderr) > 0 {
|
||||
t.Log("Stderr:", cmn.Red(string(stderr)))
|
||||
}
|
||||
|
||||
proc.Wait()
|
||||
return proc.ExitState.Success()
|
||||
// bz := proc.StdoutBuffer.Bytes()
|
||||
// fmt.Println("EXEC WRITE", string(bz))
|
||||
}
|
||||
|
|
|
@ -6,10 +6,10 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
"github.com/tendermint/tendermint/libs/cli"
|
||||
dbm "github.com/tendermint/tendermint/libs/db"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/cmd/gaia/app"
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
|
|
|
@ -4,10 +4,10 @@ import (
|
|||
"encoding/json"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
dbm "github.com/tendermint/tendermint/libs/db"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
|
||||
bam "github.com/cosmos/cosmos-sdk/baseapp"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
|
|
@ -7,10 +7,10 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
"github.com/tendermint/tendermint/libs/cli"
|
||||
dbm "github.com/tendermint/tendermint/libs/db"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/examples/democoin/app"
|
||||
"github.com/cosmos/cosmos-sdk/server"
|
||||
|
|
|
@ -5,9 +5,9 @@ import (
|
|||
"path/filepath"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
dbm "github.com/tendermint/tendermint/libs/db"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
// AppCreator lets us lazily initialize app, using home dir
|
||||
|
|
|
@ -18,12 +18,12 @@ import (
|
|||
"github.com/tendermint/tendermint/crypto"
|
||||
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/p2p"
|
||||
pvm "github.com/tendermint/tendermint/privval"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
tmcli "github.com/tendermint/tendermint/libs/cli"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
dbm "github.com/tendermint/tendermint/libs/db"
|
||||
"github.com/tendermint/tendermint/p2p"
|
||||
pvm "github.com/tendermint/tendermint/privval"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
|
||||
clkeys "github.com/cosmos/cosmos-sdk/client/keys"
|
||||
serverconfig "github.com/cosmos/cosmos-sdk/server/config"
|
||||
|
|
|
@ -7,9 +7,9 @@ import (
|
|||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
dbm "github.com/tendermint/tendermint/libs/db"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
tmtypes "github.com/tendermint/tendermint/types"
|
||||
|
||||
bam "github.com/cosmos/cosmos-sdk/baseapp"
|
||||
gc "github.com/cosmos/cosmos-sdk/server/config"
|
||||
|
|
|
@ -8,10 +8,10 @@ import (
|
|||
"github.com/tendermint/tendermint/abci/server"
|
||||
|
||||
tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
"github.com/tendermint/tendermint/node"
|
||||
pvm "github.com/tendermint/tendermint/privval"
|
||||
"github.com/tendermint/tendermint/proxy"
|
||||
cmn "github.com/tendermint/tendermint/libs/common"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -7,8 +7,8 @@ import (
|
|||
"golang.org/x/crypto/ripemd160"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
dbm "github.com/tendermint/tendermint/libs/db"
|
||||
"github.com/tendermint/tendermint/crypto/merkle"
|
||||
dbm "github.com/tendermint/tendermint/libs/db"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
|
|
@ -5,8 +5,8 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/require"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
dbm "github.com/tendermint/tendermint/libs/db"
|
||||
"github.com/tendermint/tendermint/crypto/merkle"
|
||||
dbm "github.com/tendermint/tendermint/libs/db"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
)
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package tests
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
|
@ -21,13 +23,15 @@ func ExecuteT(t *testing.T, cmd string) (out string) {
|
|||
}
|
||||
|
||||
// Start process and wait.
|
||||
proc, err := StartProcess("", name, args, nil, nil)
|
||||
proc, err := StartProcess("", name, args)
|
||||
require.NoError(t, err)
|
||||
proc.Wait()
|
||||
|
||||
// Get the output.
|
||||
outbz := proc.StdoutBuffer.Bytes()
|
||||
errbz := proc.StderrBuffer.Bytes()
|
||||
outbz, errbz, err := proc.ReadAll()
|
||||
if err != nil {
|
||||
fmt.Println("Err on proc.ReadAll()", err, args)
|
||||
}
|
||||
proc.Wait()
|
||||
|
||||
// Log output.
|
||||
if len(outbz) > 0 {
|
||||
|
@ -56,36 +60,38 @@ func GoExecuteT(t *testing.T, cmd string) (proc *Process) {
|
|||
}
|
||||
|
||||
// Start process.
|
||||
proc, err := StartProcess("", name, args, nil, nil)
|
||||
proc, err := StartProcess("", name, args)
|
||||
require.NoError(t, err)
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// Same as GoExecuteT but spawns a go routine to ReadAll off stdout.
|
||||
func GoExecuteTWithStdout(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 := CreateProcess("", name, args)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Without this, the test halts ?!
|
||||
go func() {
|
||||
_, err := ioutil.ReadAll(proc.StdoutPipe)
|
||||
if err != nil {
|
||||
fmt.Println("-------------ERR-----------------------", err)
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
err = proc.Cmd.Start()
|
||||
require.NoError(t, err)
|
||||
proc.Pid = proc.Cmd.Process.Pid
|
||||
return proc
|
||||
}
|
||||
|
|
125
tests/process.go
125
tests/process.go
|
@ -1,8 +1,8 @@
|
|||
package tests
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"time"
|
||||
|
@ -10,26 +10,37 @@ import (
|
|||
|
||||
// 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:"-"`
|
||||
ExecPath string
|
||||
Args []string
|
||||
Pid int
|
||||
StartTime time.Time
|
||||
EndTime time.Time
|
||||
Cmd *exec.Cmd `json:"-"`
|
||||
ExitState *os.ProcessState `json:"-"`
|
||||
StdinPipe io.WriteCloser `json:"-"`
|
||||
StdoutPipe io.ReadCloser `json:"-"`
|
||||
StderrPipe io.ReadCloser `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) {
|
||||
func StartProcess(dir string, name string, args []string) (*Process, error) {
|
||||
proc, err := CreateProcess(dir, name, args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// cmd start
|
||||
if err := proc.Cmd.Start(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
proc.Pid = proc.Cmd.Process.Pid
|
||||
|
||||
return proc, nil
|
||||
}
|
||||
|
||||
// Same as StartProcess but doesn't start the process
|
||||
func CreateProcess(dir string, name string, args []string) (*Process, error) {
|
||||
var cmd = exec.Command(name, args...) // is not yet started.
|
||||
// cmd dir
|
||||
if dir == "" {
|
||||
|
@ -46,52 +57,27 @@ func StartProcess(dir string, name string, args []string, outFile, errFile io.Wr
|
|||
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 {
|
||||
|
||||
stdout, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
stderr, err := cmd.StderrPipe()
|
||||
if 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,
|
||||
ExecPath: name,
|
||||
Args: args,
|
||||
StartTime: time.Now(),
|
||||
Cmd: cmd,
|
||||
ExitState: nil,
|
||||
StdinPipe: stdin,
|
||||
StdoutPipe: stdout,
|
||||
StderrPipe: stderr,
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -106,5 +92,26 @@ func (proc *Process) Stop(kill bool) error {
|
|||
|
||||
// wait for the process
|
||||
func (proc *Process) Wait() {
|
||||
<-proc.WaitCh
|
||||
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
|
||||
}
|
||||
|
||||
// ReadAll calls ioutil.ReadAll on the StdoutPipe and StderrPipe.
|
||||
func (proc *Process) ReadAll() (stdout []byte, stderr []byte, err error) {
|
||||
outbz, err := ioutil.ReadAll(proc.StdoutPipe)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
errbz, err := ioutil.ReadAll(proc.StderrPipe)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return outbz, errbz, nil
|
||||
}
|
||||
|
|
|
@ -21,13 +21,20 @@ func WaitForNextHeightTM(port string) {
|
|||
// Wait for N tendermint blocks to pass using the Tendermint RPC
|
||||
// on localhost
|
||||
func WaitForNextNBlocksTM(n int64, port string) {
|
||||
|
||||
// get the latest block and wait for n more
|
||||
url := fmt.Sprintf("http://localhost:%v", port)
|
||||
cl := tmclient.NewHTTP(url, "/websocket")
|
||||
resBlock, err := cl.Block(nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
var height int64
|
||||
if err != nil || resBlock.Block == nil {
|
||||
// wait for the first block to exist
|
||||
WaitForHeightTM(1, port)
|
||||
height = 1 + n
|
||||
} else {
|
||||
height = resBlock.Block.Height + n
|
||||
}
|
||||
waitForHeightTM(resBlock.Block.Height+n, url)
|
||||
waitForHeightTM(height, url)
|
||||
}
|
||||
|
||||
// Wait for the given height from the Tendermint RPC
|
||||
|
@ -57,7 +64,6 @@ func waitForHeightTM(height int64, url string) {
|
|||
|
||||
if resBlock.Block != nil &&
|
||||
resBlock.Block.Height >= height {
|
||||
fmt.Println("HEIGHT", resBlock.Block.Height)
|
||||
return
|
||||
}
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
|
@ -115,10 +121,23 @@ func waitForHeight(height int64, url string) {
|
|||
}
|
||||
}
|
||||
|
||||
// wait for tendermint to start
|
||||
func WaitForStart(port string) {
|
||||
var err error
|
||||
// wait for tendermint to start by querying the LCD
|
||||
func WaitForLCDStart(port string) {
|
||||
url := fmt.Sprintf("http://localhost:%v/blocks/latest", port)
|
||||
WaitForStart(url)
|
||||
}
|
||||
|
||||
// wait for tendermint to start by querying tendermint
|
||||
func WaitForTMStart(port string) {
|
||||
url := fmt.Sprintf("http://localhost:%v/block", port)
|
||||
WaitForStart(url)
|
||||
}
|
||||
|
||||
// WaitForStart waits for the node to start by pinging the url
|
||||
// every 100ms for 5s until it returns 200. If it takes longer than 5s,
|
||||
// it panics.
|
||||
func WaitForStart(url string) {
|
||||
var err error
|
||||
|
||||
// ping the status endpoint a few times a second
|
||||
// for a few seconds until we get a good response.
|
||||
|
@ -131,6 +150,8 @@ func WaitForStart(port string) {
|
|||
if err != nil || res == nil {
|
||||
continue
|
||||
}
|
||||
// body, _ := ioutil.ReadAll(res.Body)
|
||||
// fmt.Println("BODY", string(body))
|
||||
err = res.Body.Close()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
|
|
@ -106,7 +106,7 @@ func TestSlashingMsgs(t *testing.T) {
|
|||
// no signing info yet
|
||||
checkValidatorSigningInfo(t, mapp, keeper, addr1, false)
|
||||
|
||||
// unrevoke should fail with unknown validator
|
||||
// unrevoke should fail with validator not revoked
|
||||
res := mock.SignCheck(mapp.BaseApp, []sdk.Msg{unrevokeMsg}, []int64{0}, []int64{1}, priv1)
|
||||
require.Equal(t, sdk.ToABCICode(DefaultCodespace, CodeInvalidValidator), res.Code)
|
||||
require.Equal(t, sdk.ToABCICode(DefaultCodespace, CodeValidatorNotRevoked), res.Code)
|
||||
}
|
||||
|
|
|
@ -12,8 +12,9 @@ const (
|
|||
// Default slashing codespace
|
||||
DefaultCodespace sdk.CodespaceType = 10
|
||||
|
||||
CodeInvalidValidator CodeType = 101
|
||||
CodeValidatorJailed CodeType = 102
|
||||
CodeInvalidValidator CodeType = 101
|
||||
CodeValidatorJailed CodeType = 102
|
||||
CodeValidatorNotRevoked CodeType = 103
|
||||
)
|
||||
|
||||
func ErrNoValidatorForAddress(codespace sdk.CodespaceType) sdk.Error {
|
||||
|
@ -25,3 +26,6 @@ func ErrBadValidatorAddr(codespace sdk.CodespaceType) sdk.Error {
|
|||
func ErrValidatorJailed(codespace sdk.CodespaceType) sdk.Error {
|
||||
return sdk.NewError(codespace, CodeValidatorJailed, "validator jailed, cannot yet be unrevoked")
|
||||
}
|
||||
func ErrValidatorNotRevoked(codespace sdk.CodespaceType) sdk.Error {
|
||||
return sdk.NewError(codespace, CodeValidatorNotRevoked, "validator not revoked, cannot be unrevoked")
|
||||
}
|
||||
|
|
|
@ -26,6 +26,10 @@ func handleMsgUnrevoke(ctx sdk.Context, msg MsgUnrevoke, k Keeper) sdk.Result {
|
|||
return ErrNoValidatorForAddress(k.codespace).Result()
|
||||
}
|
||||
|
||||
if !validator.GetRevoked() {
|
||||
return ErrValidatorNotRevoked(k.codespace).Result()
|
||||
}
|
||||
|
||||
addr := validator.GetPubKey().Address()
|
||||
|
||||
// Signing info must exist
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
package slashing
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/stake"
|
||||
)
|
||||
|
||||
func TestCannotUnrevokeUnlessRevoked(t *testing.T) {
|
||||
// initial setup
|
||||
ctx, ck, sk, keeper := createTestInput(t)
|
||||
slh := NewHandler(keeper)
|
||||
amtInt := int64(100)
|
||||
addr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt)
|
||||
got := stake.NewHandler(sk)(ctx, newTestMsgCreateValidator(addr, val, amt))
|
||||
require.True(t, got.IsOK())
|
||||
stake.EndBlocker(ctx, sk)
|
||||
require.Equal(t, ck.GetCoins(ctx, addr), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.Sub(amt)}})
|
||||
require.True(t, sdk.NewRatFromInt(amt).Equal(sk.Validator(ctx, addr).GetPower()))
|
||||
|
||||
// assert non-revoked validator can't be unrevoked
|
||||
got = slh(ctx, NewMsgUnrevoke(addr))
|
||||
require.False(t, got.IsOK(), "allowed unrevoke of non-revoked validator")
|
||||
require.Equal(t, sdk.ToABCICode(DefaultCodespace, CodeValidatorNotRevoked), got.Code)
|
||||
}
|
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/client"
|
||||
"github.com/cosmos/cosmos-sdk/client/context"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/wire"
|
||||
|
@ -154,9 +155,10 @@ func GetCmdRedelegate(storeName string, cdc *wire.Codec) *cobra.Command {
|
|||
Short: "redelegate illiquid tokens from one validator to another",
|
||||
}
|
||||
cmd.AddCommand(
|
||||
GetCmdBeginRedelegate(storeName, cdc),
|
||||
GetCmdCompleteRedelegate(cdc),
|
||||
)
|
||||
client.PostCommands(
|
||||
GetCmdBeginRedelegate(storeName, cdc),
|
||||
GetCmdCompleteRedelegate(cdc),
|
||||
)...)
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
@ -301,9 +303,10 @@ func GetCmdUnbond(storeName string, cdc *wire.Codec) *cobra.Command {
|
|||
Short: "begin or complete unbonding shares from a validator",
|
||||
}
|
||||
cmd.AddCommand(
|
||||
GetCmdBeginUnbonding(storeName, cdc),
|
||||
GetCmdCompleteUnbonding(cdc),
|
||||
)
|
||||
client.PostCommands(
|
||||
GetCmdBeginUnbonding(storeName, cdc),
|
||||
GetCmdCompleteUnbonding(cdc),
|
||||
)...)
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue