gaiad: ExportGenesisFile() incorrectly overwrites genesis (#4063)

ExportGenesisFile() overwrites all non-gaia related
sections of the genesis.json file as it always
creates a new one from scratch.

Remove cmd/gaia/init.LoadGenesisDoc() in favor of
tendermint's types.GenesisDocFromFile().

Closes: #4066
This commit is contained in:
Alessio Treglia 2019-04-08 18:54:45 +01:00 committed by GitHub
parent 9e7440a92c
commit fbc6bdae18
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 51 additions and 68 deletions

View File

@ -0,0 +1 @@
#4066 Fix 'ExportGenesisFile() incorrectly overwrites genesis'

View File

@ -15,6 +15,7 @@ import (
"time" "time"
"github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/crypto/ed25519"
tmtypes "github.com/tendermint/tendermint/types"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -992,6 +993,7 @@ trust-node = true
func TestGaiadCollectGentxs(t *testing.T) { func TestGaiadCollectGentxs(t *testing.T) {
t.Parallel() t.Parallel()
var customMaxBytes, customMaxGas int64 = 99999999, 1234567
f := NewFixtures(t) f := NewFixtures(t)
// Initialise temporary directories // Initialise temporary directories
@ -1011,6 +1013,15 @@ func TestGaiadCollectGentxs(t *testing.T) {
// Run init // Run init
f.GDInit(keyFoo) f.GDInit(keyFoo)
// Customise genesis.json
genFile := f.GenesisFile()
genDoc, err := tmtypes.GenesisDocFromFile(genFile)
require.NoError(t, err)
genDoc.ConsensusParams.Block.MaxBytes = customMaxBytes
genDoc.ConsensusParams.Block.MaxGas = customMaxGas
genDoc.SaveAs(genFile)
// Add account to genesis.json // Add account to genesis.json
f.AddGenesisAccount(f.KeyAddress(keyFoo), startCoins) f.AddGenesisAccount(f.KeyAddress(keyFoo), startCoins)
@ -1020,6 +1031,11 @@ func TestGaiadCollectGentxs(t *testing.T) {
// Collect gentxs from a custom directory // Collect gentxs from a custom directory
f.CollectGenTxs(fmt.Sprintf("--gentx-dir=%s", gentxDir)) f.CollectGenTxs(fmt.Sprintf("--gentx-dir=%s", gentxDir))
genDoc, err = tmtypes.GenesisDocFromFile(genFile)
require.NoError(t, err)
require.Equal(t, genDoc.ConsensusParams.Block.MaxBytes, customMaxBytes)
require.Equal(t, genDoc.ConsensusParams.Block.MaxGas, customMaxGas)
f.Cleanup(gentxDir) f.Cleanup(gentxDir)
} }

View File

@ -15,10 +15,10 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
cmn "github.com/tendermint/tendermint/libs/common" cmn "github.com/tendermint/tendermint/libs/common"
tmtypes "github.com/tendermint/tendermint/types"
clientkeys "github.com/cosmos/cosmos-sdk/client/keys" clientkeys "github.com/cosmos/cosmos-sdk/client/keys"
"github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/cmd/gaia/app"
appInit "github.com/cosmos/cosmos-sdk/cmd/gaia/init"
"github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/crypto/keys" "github.com/cosmos/cosmos-sdk/crypto/keys"
"github.com/cosmos/cosmos-sdk/server" "github.com/cosmos/cosmos-sdk/server"
@ -98,7 +98,7 @@ func (f Fixtures) GenesisFile() string {
// GenesisFile returns the application's genesis state // GenesisFile returns the application's genesis state
func (f Fixtures) GenesisState() app.GenesisState { func (f Fixtures) GenesisState() app.GenesisState {
cdc := codec.New() cdc := codec.New()
genDoc, err := appInit.LoadGenesisDoc(cdc, f.GenesisFile()) genDoc, err := tmtypes.GenesisDocFromFile(f.GenesisFile())
require.NoError(f.T, err) require.NoError(f.T, err)
var appState app.GenesisState var appState app.GenesisState

View File

@ -46,7 +46,7 @@ func CollectGenTxsCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command {
return err return err
} }
genDoc, err := LoadGenesisDoc(cdc, config.GenesisFile()) genDoc, err := types.GenesisDocFromFile(config.GenesisFile())
if err != nil { if err != nil {
return err return err
} }
@ -59,7 +59,7 @@ func CollectGenTxsCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command {
toPrint := newPrintInfo(config.Moniker, genDoc.ChainID, nodeID, genTxsDir, json.RawMessage("")) toPrint := newPrintInfo(config.Moniker, genDoc.ChainID, nodeID, genTxsDir, json.RawMessage(""))
initCfg := newInitConfig(genDoc.ChainID, genTxsDir, name, nodeID, valPubKey) initCfg := newInitConfig(genDoc.ChainID, genTxsDir, name, nodeID, valPubKey)
appMessage, err := genAppStateFromConfig(cdc, config, initCfg, genDoc) appMessage, err := genAppStateFromConfig(cdc, config, initCfg, *genDoc)
if err != nil { if err != nil {
return err return err
} }
@ -82,7 +82,6 @@ func genAppStateFromConfig(
cdc *codec.Codec, config *cfg.Config, initCfg initConfig, genDoc types.GenesisDoc, cdc *codec.Codec, config *cfg.Config, initCfg initConfig, genDoc types.GenesisDoc,
) (appState json.RawMessage, err error) { ) (appState json.RawMessage, err error) {
genFile := config.GenesisFile()
var ( var (
appGenTxs []auth.StdTx appGenTxs []auth.StdTx
persistentPeers string persistentPeers string
@ -116,7 +115,8 @@ func genAppStateFromConfig(
return return
} }
err = ExportGenesisFile(genFile, initCfg.ChainID, nil, appState) genDoc.AppState = appState
err = ExportGenesisFile(&genDoc, config.GenesisFile())
return return
} }

View File

@ -7,6 +7,7 @@ import (
"github.com/spf13/viper" "github.com/spf13/viper"
"github.com/tendermint/tendermint/libs/cli" "github.com/tendermint/tendermint/libs/cli"
"github.com/tendermint/tendermint/libs/common" "github.com/tendermint/tendermint/libs/common"
tmtypes "github.com/tendermint/tendermint/types"
"github.com/cosmos/cosmos-sdk/client/keys" "github.com/cosmos/cosmos-sdk/client/keys"
"github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/cmd/gaia/app"
@ -58,7 +59,7 @@ func AddGenesisAccountCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command
return fmt.Errorf("%s does not exist, run `gaiad init` first", genFile) return fmt.Errorf("%s does not exist, run `gaiad init` first", genFile)
} }
genDoc, err := LoadGenesisDoc(cdc, genFile) genDoc, err := tmtypes.GenesisDocFromFile(genFile)
if err != nil { if err != nil {
return err return err
} }
@ -78,7 +79,8 @@ func AddGenesisAccountCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command
return err return err
} }
return ExportGenesisFile(genFile, genDoc.ChainID, nil, appStateJSON) genDoc.AppState = appStateJSON
return ExportGenesisFile(genDoc, genFile)
}, },
} }

View File

@ -17,6 +17,7 @@ import (
"github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto"
tmcli "github.com/tendermint/tendermint/libs/cli" tmcli "github.com/tendermint/tendermint/libs/cli"
"github.com/tendermint/tendermint/libs/common" "github.com/tendermint/tendermint/libs/common"
tmtypes "github.com/tendermint/tendermint/types"
"github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/context"
@ -79,7 +80,7 @@ following delegation and commission default parameters:
"the tx's memo field will be unset") "the tx's memo field will be unset")
} }
genDoc, err := LoadGenesisDoc(cdc, config.GenesisFile()) genDoc, err := tmtypes.GenesisDocFromFile(config.GenesisFile())
if err != nil { if err != nil {
return err return err
} }

View File

@ -11,6 +11,7 @@ import (
cfg "github.com/tendermint/tendermint/config" cfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/libs/cli" "github.com/tendermint/tendermint/libs/cli"
"github.com/tendermint/tendermint/libs/common" "github.com/tendermint/tendermint/libs/common"
"github.com/tendermint/tendermint/types"
"github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/cmd/gaia/app" "github.com/cosmos/cosmos-sdk/cmd/gaia/app"
@ -76,7 +77,22 @@ func InitCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command { // nolint:
return err return err
} }
if err = ExportGenesisFile(genFile, chainID, nil, appState); err != nil { genDoc := &types.GenesisDoc{}
if _, err := os.Stat(genFile); err != nil {
if !os.IsNotExist(err) {
return err
}
} else {
genDoc, err = types.GenesisDocFromFile(genFile)
if err != nil {
return err
}
}
genDoc.ChainID = chainID
genDoc.Validators = nil
genDoc.AppState = appState
if err = ExportGenesisFile(genDoc, genFile); err != nil {
return err return err
} }

View File

@ -306,12 +306,12 @@ func collectGenFiles(
nodeID, valPubKey := nodeIDs[i], valPubKeys[i] nodeID, valPubKey := nodeIDs[i], valPubKeys[i]
initCfg := newInitConfig(chainID, gentxsDir, moniker, nodeID, valPubKey) initCfg := newInitConfig(chainID, gentxsDir, moniker, nodeID, valPubKey)
genDoc, err := LoadGenesisDoc(cdc, config.GenesisFile()) genDoc, err := types.GenesisDocFromFile(config.GenesisFile())
if err != nil { if err != nil {
return err return err
} }
nodeAppState, err := genAppStateFromConfig(cdc, config, initCfg, genDoc) nodeAppState, err := genAppStateFromConfig(cdc, config, initCfg, *genDoc)
if err != nil { if err != nil {
return err return err
} }

View File

@ -3,11 +3,9 @@ package init
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil"
"path/filepath" "path/filepath"
"time" "time"
amino "github.com/tendermint/go-amino"
cfg "github.com/tendermint/tendermint/config" cfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/libs/common" "github.com/tendermint/tendermint/libs/common"
@ -22,16 +20,7 @@ import (
// ExportGenesisFile creates and writes the genesis configuration to disk. An // ExportGenesisFile creates and writes the genesis configuration to disk. An
// error is returned if building or writing the configuration to file fails. // error is returned if building or writing the configuration to file fails.
func ExportGenesisFile( func ExportGenesisFile(genDoc *types.GenesisDoc, genFile string) error {
genFile, chainID string, validators []types.GenesisValidator, appState json.RawMessage,
) error {
genDoc := types.GenesisDoc{
ChainID: chainID,
Validators: validators,
AppState: appState,
}
if err := genDoc.ValidateAndComplete(); err != nil { if err := genDoc.ValidateAndComplete(); err != nil {
return err return err
} }
@ -88,20 +77,6 @@ func InitializeNodeValidatorFiles(
return nodeID, valPubKey, nil return nodeID, valPubKey, nil
} }
// LoadGenesisDoc reads and unmarshals GenesisDoc from the given file.
func LoadGenesisDoc(cdc *amino.Codec, genFile string) (genDoc types.GenesisDoc, err error) {
genContents, err := ioutil.ReadFile(genFile)
if err != nil {
return genDoc, err
}
if err := cdc.UnmarshalJSON(genContents, &genDoc); err != nil {
return genDoc, err
}
return genDoc, err
}
func initializeEmptyGenesis( func initializeEmptyGenesis(
cdc *codec.Codec, genFile, chainID string, overwrite bool, cdc *codec.Codec, genFile, chainID string, overwrite bool,
) (appState json.RawMessage, err error) { ) (appState json.RawMessage, err error) {

View File

@ -2,13 +2,10 @@ package init
import ( import (
"encoding/json" "encoding/json"
"fmt"
"os"
"path/filepath" "path/filepath"
"testing" "testing"
"time" "time"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/tests" "github.com/cosmos/cosmos-sdk/tests"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@ -22,28 +19,3 @@ func TestExportGenesisFileWithTime(t *testing.T) {
fname := filepath.Join(dir, "genesis.json") fname := filepath.Join(dir, "genesis.json")
require.NoError(t, ExportGenesisFileWithTime(fname, "test", nil, json.RawMessage(""), time.Now())) require.NoError(t, ExportGenesisFileWithTime(fname, "test", nil, json.RawMessage(""), time.Now()))
} }
func TestLoadGenesisDoc(t *testing.T) {
t.Parallel()
dir, cleanup := tests.NewTestCaseDir(t)
defer cleanup()
fname := filepath.Join(dir, "genesis.json")
require.NoError(t, ExportGenesisFileWithTime(fname, "test", nil, json.RawMessage(""), time.Now()))
_, err := LoadGenesisDoc(codec.Cdc, fname)
require.NoError(t, err)
// Non-existing file
_, err = LoadGenesisDoc(codec.Cdc, "non-existing-file")
require.Error(t, err)
malformedFilename := filepath.Join(dir, "malformed")
malformedFile, err := os.Create(malformedFilename)
require.NoError(t, err)
fmt.Fprint(malformedFile, "invalidjson")
malformedFile.Close()
// Non-existing file
_, err = LoadGenesisDoc(codec.Cdc, malformedFilename)
require.Error(t, err)
}

View File

@ -31,8 +31,8 @@ func ValidateGenesisCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command {
//nolint //nolint
fmt.Fprintf(os.Stderr, "validating genesis file at %s\n", genesis) fmt.Fprintf(os.Stderr, "validating genesis file at %s\n", genesis)
var genDoc types.GenesisDoc var genDoc *types.GenesisDoc
if genDoc, err = LoadGenesisDoc(cdc, genesis); err != nil { if genDoc, err = types.GenesisDocFromFile(genesis); err != nil {
return fmt.Errorf("Error loading genesis doc from %s: %s", genesis, err.Error()) return fmt.Errorf("Error loading genesis doc from %s: %s", genesis, err.Error())
} }