Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

R4R: Additional gentx verfication #2971

Merged
merged 19 commits into from
Dec 4, 2018
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ godocs:
test: test_unit

test_cli:
@go test -count 1 `go list github.com/cosmos/cosmos-sdk/cmd/gaia/cli_test` -tags=cli_test
@go test -p 4 `go list github.com/cosmos/cosmos-sdk/cmd/gaia/cli_test` -tags=cli_test
alessio marked this conversation as resolved.
Show resolved Hide resolved

test_examples:
@go test -count 1 -p 1 `go list github.com/cosmos/cosmos-sdk/docs/examples/basecoin/cli_test` -tags=cli_test
Expand Down
3 changes: 2 additions & 1 deletion PENDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ BREAKING CHANGES

* Gaia CLI (`gaiacli`)
* [cli] [\#2595](https://github.com/cosmos/cosmos-sdk/issues/2595) Remove `keys new` in favor of `keys add` incorporating existing functionality with addition of key recovery functionality.
* [cli] [\#2971](https://github.com/cosmos/cosmos-sdk/pull/2971) Additional verification when running `gaiad gentx`

* Gaia
- [#128](https://github.com/tendermint/devops/issues/128) Updated CircleCI job to trigger website build on every push to master/develop.
Expand Down Expand Up @@ -39,7 +40,7 @@ IMPROVEMENTS

* SDK
- \#1277 Complete bank module specification

* Tendermint


Expand Down
9 changes: 7 additions & 2 deletions cmd/gaia/app/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ func CollectStdTxs(cdc *codec.Codec, moniker string, genTxsDir string, genDoc tm
if err := cdc.UnmarshalJSON(genDoc.AppState, &appState); err != nil {
return appGenTxs, persistentPeers, err
}

addrMap := make(map[string]GenesisAccount, len(appState.Accounts))
for i := 0; i < len(appState.Accounts); i++ {
acc := appState.Accounts[i]
Expand Down Expand Up @@ -257,13 +258,17 @@ func CollectStdTxs(cdc *codec.Codec, moniker string, genTxsDir string, genDoc tm
msg := msgs[0].(stake.MsgCreateValidator)
addr := string(sdk.AccAddress(msg.ValidatorAddr))
acc, ok := addrMap[addr]

if !ok {
return appGenTxs, persistentPeers, fmt.Errorf(
"account %v not in genesis.json: %+v", addr, addrMap)
}

if acc.Coins.AmountOf(msg.Delegation.Denom).LT(msg.Delegation.Amount) {
err = fmt.Errorf("insufficient fund for the delegation: %v < %v",
acc.Coins.AmountOf(msg.Delegation.Denom), msg.Delegation.Amount)
return appGenTxs, persistentPeers, fmt.Errorf(
"insufficient fund for delegation %v: %v < %v",
acc.Address, acc.Coins.AmountOf(msg.Delegation.Denom), msg.Delegation.Amount,
)
}

// exclude itself from persistent peers
Expand Down
90 changes: 40 additions & 50 deletions cmd/gaia/cli_test/cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ import (
)

func TestGaiaCLIMinimumFees(t *testing.T) {
gaiadHome, gaiacliHome := getTestingHomeDirs(t)
alexanderbez marked this conversation as resolved.
Show resolved Hide resolved
chainID, servAddr, port := initializeFixtures(t, gaiadHome, gaiacliHome)
t.Parallel()
chainID, servAddr, port, gaiadHome, gaiacliHome, p2pAddr := initializeFixtures(t)
flags := fmt.Sprintf("--home=%s --node=%v --chain-id=%v", gaiacliHome, servAddr, chainID)

// start gaiad server with minimum fees
proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("gaiad start --home=%s --rpc.laddr=%v --minimum_fees=2feeToken", gaiadHome, servAddr))
proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("gaiad start --home=%s --rpc.laddr=%v --p2p.laddr=%v --minimum_fees=2feeToken", gaiadHome, servAddr, p2pAddr))

defer proc.Stop(false)
tests.WaitForTMStart(port)
Expand All @@ -57,12 +57,12 @@ func TestGaiaCLIMinimumFees(t *testing.T) {
}

func TestGaiaCLIFeesDeduction(t *testing.T) {
gaiadHome, gaiacliHome := getTestingHomeDirs(t)
chainID, servAddr, port := initializeFixtures(t, gaiadHome, gaiacliHome)
t.Parallel()
chainID, servAddr, port, gaiadHome, gaiacliHome, p2pAddr := initializeFixtures(t)
flags := fmt.Sprintf("--home=%s --node=%v --chain-id=%v", gaiacliHome, servAddr, chainID)

// start gaiad server with minimum fees
proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("gaiad start --home=%s --rpc.laddr=%v --minimum_fees=1fooToken", gaiadHome, servAddr))
proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("gaiad start --home=%s --rpc.laddr=%v --p2p.laddr=%v --minimum_fees=1fooToken", gaiadHome, servAddr, p2pAddr))

defer proc.Stop(false)
tests.WaitForTMStart(port)
Expand Down Expand Up @@ -100,13 +100,12 @@ func TestGaiaCLIFeesDeduction(t *testing.T) {
}

func TestGaiaCLISend(t *testing.T) {
gaiadHome, gaiacliHome := getTestingHomeDirs(t)
chainID, servAddr, port := initializeFixtures(t, gaiadHome, gaiacliHome)
t.Parallel()
chainID, servAddr, port, gaiadHome, gaiacliHome, p2pAddr := initializeFixtures(t)
flags := fmt.Sprintf("--home=%s --node=%v --chain-id=%v", gaiacliHome, servAddr, chainID)

// start gaiad server
proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("gaiad start --home=%s --rpc.laddr=%v", gaiadHome, servAddr))

proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("gaiad start --home=%s --rpc.laddr=%v --p2p.laddr=%v", gaiadHome, servAddr, p2pAddr))
defer proc.Stop(false)
tests.WaitForTMStart(port)
tests.WaitForNextNBlocksTM(1, port)
Expand Down Expand Up @@ -153,12 +152,12 @@ func TestGaiaCLISend(t *testing.T) {
}

func TestGaiaCLIGasAuto(t *testing.T) {
gaiadHome, gaiacliHome := getTestingHomeDirs(t)
chainID, servAddr, port := initializeFixtures(t, gaiadHome, gaiacliHome)
t.Parallel()
chainID, servAddr, port, gaiadHome, gaiacliHome, p2pAddr := initializeFixtures(t)
flags := fmt.Sprintf("--home=%s --node=%v --chain-id=%v", gaiacliHome, servAddr, chainID)

// start gaiad server
proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("gaiad start --home=%s --rpc.laddr=%v", gaiadHome, servAddr))
proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("gaiad start --home=%s --rpc.laddr=%v --p2p.laddr=%v", gaiadHome, servAddr, p2pAddr))

defer proc.Stop(false)
tests.WaitForTMStart(port)
Expand Down Expand Up @@ -206,12 +205,12 @@ func TestGaiaCLIGasAuto(t *testing.T) {
}

func TestGaiaCLICreateValidator(t *testing.T) {
gaiadHome, gaiacliHome := getTestingHomeDirs(t)
chainID, servAddr, port := initializeFixtures(t, gaiadHome, gaiacliHome)
t.Parallel()
chainID, servAddr, port, gaiadHome, gaiacliHome, p2pAddr := initializeFixtures(t)
flags := fmt.Sprintf("--home=%s --chain-id=%v --node=%s", gaiacliHome, chainID, servAddr)

// start gaiad server
proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("gaiad start --home=%s --rpc.laddr=%v", gaiadHome, servAddr))
proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("gaiad start --home=%s --rpc.laddr=%v --p2p.laddr=%v", gaiadHome, servAddr, p2pAddr))

defer proc.Stop(false)
tests.WaitForTMStart(port)
Expand Down Expand Up @@ -305,12 +304,12 @@ func TestGaiaCLICreateValidator(t *testing.T) {
}

func TestGaiaCLISubmitProposal(t *testing.T) {
gaiadHome, gaiacliHome := getTestingHomeDirs(t)
chainID, servAddr, port := initializeFixtures(t, gaiadHome, gaiacliHome)
t.Parallel()
chainID, servAddr, port, gaiadHome, gaiacliHome, p2pAddr := initializeFixtures(t)
flags := fmt.Sprintf("--home=%s --node=%v --chain-id=%v", gaiacliHome, servAddr, chainID)

// start gaiad server
proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("gaiad start --home=%s --rpc.laddr=%v", gaiadHome, servAddr))
proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("gaiad start --home=%s --rpc.laddr=%v --p2p.laddr=%v", gaiadHome, servAddr, p2pAddr))

defer proc.Stop(false)
tests.WaitForTMStart(port)
Expand Down Expand Up @@ -459,13 +458,12 @@ func TestGaiaCLISubmitProposal(t *testing.T) {
}

func TestGaiaCLISendGenerateSignAndBroadcast(t *testing.T) {
gaiadHome, gaiacliHome := getTestingHomeDirs(t)
chainID, servAddr, port := initializeFixtures(t, gaiadHome, gaiacliHome)
t.Parallel()
chainID, servAddr, port, gaiadHome, gaiacliHome, p2pAddr := initializeFixtures(t)
flags := fmt.Sprintf("--home=%s --node=%v --chain-id=%v", gaiacliHome, servAddr, chainID)

// start gaiad server
proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf(
"gaiad start --home=%s --rpc.laddr=%v", gaiadHome, servAddr))
proc := tests.GoExecuteTWithStdout(t, fmt.Sprintf("gaiad start --home=%s --rpc.laddr=%v --p2p.laddr=%v", gaiadHome, servAddr, p2pAddr))

defer proc.Stop(false)
tests.WaitForTMStart(port)
Expand Down Expand Up @@ -562,11 +560,9 @@ func TestGaiaCLISendGenerateSignAndBroadcast(t *testing.T) {
}

func TestGaiaCLIConfig(t *testing.T) {
gaiadHome, gaiacliHome := getTestingHomeDirs(t)
servAddr, port, err := server.FreeTCPAddr()
require.NoError(t, err)
t.Parallel()
chainID, servAddr, port, gaiadHome, gaiacliHome, _ := initializeFixtures(t)
node := fmt.Sprintf("%s:%s", servAddr, port)
chainID := executeInit(t, fmt.Sprintf("gaiad init -o --moniker=foo --home=%s", gaiadHome))
executeWrite(t, fmt.Sprintf("gaiacli --home=%s config", gaiadHome), gaiacliHome, node, "y")
config, err := ioutil.ReadFile(path.Join(gaiacliHome, "config", "config.toml"))
require.NoError(t, err)
Expand Down Expand Up @@ -604,40 +600,34 @@ trust_node = true
//___________________________________________________________________________________
// helper methods

func getTestingHomeDirs(t *testing.T) (string, string) {
tmpDir, err := ioutil.TempDir("", t.Name())
require.NoError(t, err)
gaiadHome := fmt.Sprintf("%s%s.test_gaiad", tmpDir, string(os.PathSeparator))
gaiacliHome := fmt.Sprintf("%s%s.test_gaiacli", tmpDir, string(os.PathSeparator))
func getTestingHomeDirs(name string) (string, string) {
tmpDir := os.TempDir()
gaiadHome := fmt.Sprintf("%s%s%s%s.test_gaiad", tmpDir, string(os.PathSeparator), name, string(os.PathSeparator))
gaiacliHome := fmt.Sprintf("%s%s%s%s.test_gaiacli", tmpDir, string(os.PathSeparator), name, string(os.PathSeparator))
return gaiadHome, gaiacliHome
}

func initializeFixtures(t *testing.T, gaiadHome, gaiacliHome string) (chainID, servAddr, port string) {
func initializeFixtures(t *testing.T) (chainID, servAddr, port, gaiadHome, gaiacliHome, p2pAddr string) {
gaiadHome, gaiacliHome = getTestingHomeDirs(t.Name())
tests.ExecuteT(t, fmt.Sprintf("gaiad --home=%s unsafe-reset-all", gaiadHome), "")
os.RemoveAll(filepath.Join(gaiadHome, "config", "gentx"))
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s --force foo", gaiacliHome))
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s --force bar", gaiacliHome))
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s foo", gaiacliHome), app.DefaultKeyPass)
executeWrite(t, fmt.Sprintf("gaiacli keys delete --home=%s bar", gaiacliHome), app.DefaultKeyPass)
executeWriteCheckErr(t, fmt.Sprintf("gaiacli keys add --home=%s foo", gaiacliHome), app.DefaultKeyPass)
executeWriteCheckErr(t, fmt.Sprintf("gaiacli keys add --home=%s bar", gaiacliHome), app.DefaultKeyPass)
fooAddr, _ := executeGetAddrPK(t, fmt.Sprintf(
"gaiacli keys show foo --output=json --home=%s", gaiacliHome))
fooAddr, _ := executeGetAddrPK(t, fmt.Sprintf("gaiacli keys show foo --output=json --home=%s", gaiacliHome))
chainID = executeInit(t, fmt.Sprintf("gaiad init -o --moniker=foo --home=%s", gaiadHome))
genFile := filepath.Join(gaiadHome, "config", "genesis.json")
genDoc := readGenesisFile(t, genFile)
var appState app.GenesisState
err := codec.Cdc.UnmarshalJSON(genDoc.AppState, &appState)
require.NoError(t, err)
appState.Accounts = []app.GenesisAccount{app.NewDefaultGenesisAccount(fooAddr)}
appStateJSON, err := codec.Cdc.MarshalJSON(appState)
require.NoError(t, err)
genDoc.AppState = appStateJSON
genDoc.SaveAs(genFile)

executeWriteCheckErr(t, fmt.Sprintf(
"gaiad add-genesis-account %s 150%s,1000fooToken --home=%s", fooAddr, stakeTypes.DefaultBondDenom, gaiadHome))
executeWrite(t, fmt.Sprintf("cat %s%sconfig%sgenesis.json", gaiadHome, string(os.PathSeparator), string(os.PathSeparator)))
executeWriteCheckErr(t, fmt.Sprintf(
"gaiad gentx --name=foo --home=%s --home-client=%s", gaiadHome, gaiacliHome),
app.DefaultKeyPass)
"gaiad gentx --name=foo --home=%s --home-client=%s", gaiadHome, gaiacliHome), app.DefaultKeyPass)
executeWriteCheckErr(t, fmt.Sprintf("gaiad collect-gentxs --home=%s", gaiadHome), app.DefaultKeyPass)
// get a free port, also setup some common flags
servAddr, port, err = server.FreeTCPAddr()
servAddr, port, err := server.FreeTCPAddr()
require.NoError(t, err)
p2pAddr, _, err = server.FreeTCPAddr()
require.NoError(t, err)
return
}
Expand Down
51 changes: 49 additions & 2 deletions cmd/gaia/init/gentx.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,18 +64,25 @@ following delegation and commission default parameters:
if err != nil {
return err
}

genDoc, err := loadGenesisDoc(cdc, config.GenesisFile())
if err != nil {
return err
}

genesisState := app.GenesisState{}
if err = cdc.UnmarshalJSON(genDoc.AppState, &genesisState); err != nil {
return err
}

kb, err := keys.GetKeyBaseFromDir(viper.GetString(flagClientHome))
if err != nil {
return err
}

name := viper.GetString(client.FlagName)
if _, err := kb.Get(name); err != nil {
key, err := kb.Get(name)
if err != nil {
return err
}

Expand All @@ -86,8 +93,45 @@ following delegation and commission default parameters:
return err
}
}
// Run gaiad tx create-validator

// Set flags for creating gentx
prepareFlagsForTxCreateValidator(config, nodeID, ip, genDoc.ChainID, valPubKey)

// Fetch the amount of coins staked
amount := viper.GetString(cli.FlagAmount)
coins, err := sdk.ParseCoins(amount)
if err != nil {
return err
}

inGenesis := false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use of inGenesis is confusing - I don't intuitively know what this parameter is doing

bondDenom := genesisState.StakeData.Params.BondDenom

// Check if the account is in genesis
for _, acc := range genesisState.Accounts {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The contents of this for loop should probably be broken out into a seperate function, or this whole containing function restructured to reduce indentation

// Ensure that account is in genesis
if acc.Address.Equals(key.GetAddress()) {

// Ensure account contains enough funds of default bond denom
if coins.AmountOf(bondDenom).GT(acc.Coins.AmountOf(bondDenom)) {
return fmt.Errorf(
"Account %s is in genesis, but the only has %s%s available to stake, not %s%s",
key.GetAddress(), acc.Coins.AmountOf(bondDenom), bondDenom, coins.AmountOf(bondDenom), bondDenom,
)
}
inGenesis = true
break
}
}

if !inGenesis {
return fmt.Errorf(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can eliminate use of inGenesis by just moving this error into the above loop (which should also probably get moved to it's own funcion per my previous comment)

"Account %s in not in the app_state.accounts array of genesis.json",
key.GetAddress(),
)
}

// Run gaiad tx create-validator
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
cliCtx := context.NewCLIContext().WithCodec(cdc)
cliCtx, txBldr, msg, err := cli.BuildCreateValidatorMsg(cliCtx, txBldr)
Expand All @@ -113,13 +157,16 @@ following delegation and commission default parameters:
return err
}

// Fetch output file name
outputDocument, err := makeOutputFilepath(config.RootDir, nodeID)
if err != nil {
return err
}

if err := writeSignedGenTx(cdc, outputDocument, signedTx); err != nil {
return err
}

fmt.Fprintf(os.Stderr, "Genesis transaction written to %q\n", outputDocument)
return nil
},
Expand Down
6 changes: 6 additions & 0 deletions tests/gobash.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,18 @@ func GoExecuteTWithStdout(t *testing.T, cmd string) (proc *Process) {
require.NoError(t, err)

// Without this, the test halts ?!
// (theory: because stdout and/or err aren't connected to anything the process halts)
go func() {
_, err := ioutil.ReadAll(proc.StdoutPipe)
if err != nil {
fmt.Println("-------------ERR-----------------------", err)
return
}
_, err = ioutil.ReadAll(proc.StderrPipe)
if err != nil {
fmt.Println("-------------ERR-----------------------", err)
return
}
}()

err = proc.Cmd.Start()
Expand Down
9 changes: 4 additions & 5 deletions tests/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import (
"net/http"
"time"

"strings"

amino "github.com/tendermint/go-amino"
tmclient "github.com/tendermint/tendermint/rpc/client"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
rpcclient "github.com/tendermint/tendermint/rpc/lib/client"
"strings"
)

// Wait for the next tendermint block from the Tendermint RPC
Expand Down Expand Up @@ -109,8 +110,6 @@ func waitForHeight(height int64, url string) {
var resultBlock ctypes.ResultBlock
err = cdc.UnmarshalJSON(body, &resultBlock)
if err != nil {
fmt.Println("RES", res)
fmt.Println("BODY", string(body))
panic(err)
}

Expand All @@ -135,15 +134,15 @@ func WaitForTMStart(port string) {
}

// 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,
// every 100ms for 10s 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.
// otherwise something probably went wrong
for i := 0; i < 50; i++ {
for i := 0; i < 100; i++ {
alexanderbez marked this conversation as resolved.
Show resolved Hide resolved
time.Sleep(time.Millisecond * 100)

var res *http.Response
Expand Down