R4R: Additional gentx verfication (#2971)
* Add check that account is in genesis and contains enough funds to gentx command * Fix CLI tests and make them parallel * Update makefile to take advantage of parallel tests * Add path seperator back in * Don 't check error on key delete * Add debuggin printout for debugging remote test failures * Update cmd/gaia/init/gentx.go Co-Authored-By: jackzampolin <jack.zampolin@gmail.com> * Update cmd/gaia/init/gentx.go Co-Authored-By: jackzampolin <jack.zampolin@gmail.com> * Change to bondDenom from the stake section in genesis * Add PENDING.md * Push changes * Fix CI failure * Address PR comments * Fix broken gov tests * Address PR comments * Address PR comments
This commit is contained in:
committed by
Christopher Goes
parent
886bd35670
commit
d8fbae677f
@@ -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]
|
||||
@@ -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
|
||||
|
||||
@@ -33,12 +33,12 @@ import (
|
||||
)
|
||||
|
||||
func TestGaiaCLIMinimumFees(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=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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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 gentx --name=foo --home=%s --home-client=%s", gaiadHome, gaiacliHome),
|
||||
app.DefaultKeyPass)
|
||||
"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)
|
||||
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
|
||||
}
|
||||
|
||||
+55
-2
@@ -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
|
||||
}
|
||||
|
||||
@@ -86,8 +93,23 @@ 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
|
||||
}
|
||||
|
||||
err = accountInGenesis(genesisState, key.GetAddress(), coins)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Run gaiad tx create-validator
|
||||
txBldr := authtxb.NewTxBuilderFromCLI().WithCodec(cdc)
|
||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||
cliCtx, txBldr, msg, err := cli.BuildCreateValidatorMsg(cliCtx, txBldr)
|
||||
@@ -113,13 +135,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
|
||||
},
|
||||
@@ -135,6 +160,34 @@ following delegation and commission default parameters:
|
||||
return cmd
|
||||
}
|
||||
|
||||
func accountInGenesis(genesisState app.GenesisState, key sdk.AccAddress, coins sdk.Coins) error {
|
||||
accountIsInGenesis := false
|
||||
bondDenom := genesisState.StakeData.Params.BondDenom
|
||||
|
||||
// Check if the account is in genesis
|
||||
for _, acc := range genesisState.Accounts {
|
||||
// Ensure that account is in genesis
|
||||
if acc.Address.Equals(key) {
|
||||
|
||||
// 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, acc.Coins.AmountOf(bondDenom), bondDenom, coins.AmountOf(bondDenom), bondDenom,
|
||||
)
|
||||
}
|
||||
accountIsInGenesis = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if accountIsInGenesis {
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("Account %s in not in the app_state.accounts array of genesis.json", key)
|
||||
}
|
||||
|
||||
func prepareFlagsForTxCreateValidator(config *cfg.Config, nodeID, ip, chainID string,
|
||||
valPubKey crypto.PubKey) {
|
||||
viper.Set(tmcli.HomeFlag, viper.GetString(flagClientHome)) // --home
|
||||
|
||||
Reference in New Issue
Block a user