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

Genesis export stream #519

Merged
merged 32 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
b844bb9
boilerplate code
jewei1997 Jun 19, 2024
6bf36e0
able to write the modules in proper json
jewei1997 Jun 20, 2024
afcca80
all params in
jewei1997 Jun 21, 2024
ba56b81
some fixes
jewei1997 Jun 21, 2024
1a6aa0a
Merge branch 'main' into genesis-export-oom
jewei1997 Jun 21, 2024
778d35e
fix simapp
jewei1997 Jun 21, 2024
57374b8
minor fix
jewei1997 Jun 21, 2024
7d5d858
debug
jewei1997 Jun 21, 2024
e9ece1f
debug
jewei1997 Jun 27, 2024
c1d6750
validate-genesis using streaming works
jewei1997 Jul 5, 2024
748bdf1
only validate genesis for ibc
jewei1997 Jul 9, 2024
0177e03
do all modules
jewei1997 Jul 9, 2024
2271605
checkpoint -- get import to work
jewei1997 Jul 12, 2024
f8685be
forgot a file
jewei1997 Jul 12, 2024
8aa4ec0
export, validate, import work locally
jewei1997 Jul 16, 2024
290e5e7
remove prints
jewei1997 Jul 17, 2024
91e6100
remove some prints
jewei1997 Jul 17, 2024
b5f1687
Merge branch 'main' into genesis-export-oom
jewei1997 Jul 17, 2024
37ed60a
change seid start flag to config in app.toml
jewei1997 Jul 20, 2024
6ff8124
cleanup
jewei1997 Jul 20, 2024
8567729
add err to ProcessGenesisPerModule
jewei1997 Jul 20, 2024
dbb7436
change name of StreamGenesis to ExportGenesisStream
jewei1997 Jul 21, 2024
a3e4941
change name of AppExporterToFile to AppExporterStream
jewei1997 Jul 21, 2024
8da6f31
make validate-gensis streaming a flag
jewei1997 Jul 21, 2024
e934019
change export-to-file to a flag in export cmd
jewei1997 Jul 22, 2024
e1800c4
regenerate mocks
jewei1997 Jul 22, 2024
87a49a3
Merge branch 'main' into genesis-export-oom
jewei1997 Jul 22, 2024
900346b
minor fix
jewei1997 Jul 22, 2024
db06037
add begin block, mid block, end block to mock
jewei1997 Jul 22, 2024
5b0783a
small fixes
jewei1997 Jul 29, 2024
9e74e30
fix
jewei1997 Jul 29, 2024
117dbce
Merge branch 'main' into genesis-export-oom
jewei1997 Jul 29, 2024
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
18 changes: 18 additions & 0 deletions server/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,15 @@
SnapshotDirectory string `mapstructure:"snapshot-directory"`
}

// GenesisConfig defines the genesis export, validation, and import configuration
type GenesisConfig struct {
// StreamImport defines if the genesis.json is in stream form or not.
StreamImport bool `mapstructure:"stream-import"`

// ImportFile sets the genesis json file from which to stream from
ImportFile string `mapstructure:"import-file"`
jewei1997 marked this conversation as resolved.
Show resolved Hide resolved
}

// Config defines the server's top level configuration
type Config struct {
BaseConfig `mapstructure:",squash"`
Expand All @@ -205,6 +214,7 @@
StateSync StateSyncConfig `mapstructure:"state-sync"`
StateCommit config.StateCommitConfig `mapstructure:"state-commit"`
StateStore config.StateStoreConfig `mapstructure:"state-store"`
Genesis GenesisConfig `mapstructure:genesis`
}

// SetMinGasPrices sets the validator's minimum gas prices.
Expand Down Expand Up @@ -288,6 +298,10 @@
},
StateCommit: config.DefaultStateCommitConfig(),
StateStore: config.DefaultStateStoreConfig(),
Genesis: GenesisConfig{
StreamImport: false,
ImportFile: "",
},
}
}

Expand Down Expand Up @@ -391,6 +405,10 @@
PruneIntervalSeconds: v.GetInt("state-store.prune-interval-seconds"),
ImportNumWorkers: v.GetInt("state-store.import-num-workers"),
},
Genesis: GenesisConfig{
StreamImport: v.GetBool("genesis.stream-import"),
ImportFile: v.GetString("genesis.import-file"),
},

Check warning on line 411 in server/config/config.go

View check run for this annotation

Codecov / codecov/patch

server/config/config.go#L408-L411

Added lines #L408 - L411 were not covered by tests
}, nil
}

Expand Down
14 changes: 14 additions & 0 deletions server/config/toml.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,20 @@ snapshot-keep-recent = {{ .StateSync.SnapshotKeepRecent }}
# default is emtpy which will then store under the app home directory same as before.
snapshot-directory = "{{ .StateSync.SnapshotDirectory }}"

###############################################################################
### Genesis Configuration ###
###############################################################################


# Genesis config allows configuring whether to stream from an genesis json file in streamed form
[genesis]

# stream-import specifies whether to the stream the import from the genesis json file. The genesis
# file must be in stream form and exported in a streaming fashion.
stream-import = {{ .Genesis.StreamImport }}

# import-file specifies the path of the genesis json file to stream from.
import-file = "{{ .Genesis.ImportFile }}"
` + config.DefaultConfigTemplate

var configTemplate *template.Template
Expand Down
80 changes: 79 additions & 1 deletion server/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
"fmt"
"io/ioutil"
"os"
"time"

"github.com/spf13/cobra"
tmbytes "github.com/tendermint/tendermint/libs/bytes"
tmtypes "github.com/tendermint/tendermint/types"

"github.com/cosmos/cosmos-sdk/client/flags"
Expand All @@ -17,11 +19,22 @@
)

const (
FlagIsStreaming = "streaming"
FlagStreamingFile = "streaming-file"
FlagHeight = "height"
FlagForZeroHeight = "for-zero-height"
FlagJailAllowedAddrs = "jail-allowed-addrs"
)

type GenesisDocNoAppState struct {
GenesisTime time.Time `json:"genesis_time"`
ChainID string `json:"chain_id"`
InitialHeight int64 `json:"initial_height,string"`
ConsensusParams *tmtypes.ConsensusParams `json:"consensus_params,omitempty"`
Validators []tmtypes.GenesisValidator `json:"validators,omitempty"`
AppHash tmbytes.HexBytes `json:"app_hash"`
}

// ExportCmd dumps app state to JSON.
func ExportCmd(appExporter types.AppExporter, defaultNodeHome string) *cobra.Command {
cmd := &cobra.Command{
Expand All @@ -38,6 +51,20 @@
return err
}

isStreaming, err := cmd.Flags().GetBool(FlagIsStreaming)
if err != nil {
return err
}

Check warning on line 57 in server/export.go

View check run for this annotation

Codecov / codecov/patch

server/export.go#L56-L57

Added lines #L56 - L57 were not covered by tests

streamingFile, err := cmd.Flags().GetString(FlagStreamingFile)
if err != nil {
return err
}

Check warning on line 62 in server/export.go

View check run for this annotation

Codecov / codecov/patch

server/export.go#L61-L62

Added lines #L61 - L62 were not covered by tests

if isStreaming && streamingFile == "" {
return fmt.Errorf("file to export stream to not provided")
jewei1997 marked this conversation as resolved.
Show resolved Hide resolved
}

Check warning on line 66 in server/export.go

View check run for this annotation

Codecov / codecov/patch

server/export.go#L65-L66

Added lines #L65 - L66 were not covered by tests

db, err := openDB(config.RootDir)
if err != nil {
return err
Expand Down Expand Up @@ -67,7 +94,56 @@
forZeroHeight, _ := cmd.Flags().GetBool(FlagForZeroHeight)
jailAllowedAddrs, _ := cmd.Flags().GetStringSlice(FlagJailAllowedAddrs)

exported, err := appExporter(serverCtx.Logger, db, traceWriter, height, forZeroHeight, jailAllowedAddrs, serverCtx.Viper)
if isStreaming {
file, err := os.Create(streamingFile)
if err != nil {
return err
}
exported, err := appExporter(serverCtx.Logger, db, traceWriter, height, forZeroHeight, jailAllowedAddrs, serverCtx.Viper, file)
if err != nil {
return fmt.Errorf("error exporting state: %v", err)
}

Check warning on line 105 in server/export.go

View check run for this annotation

Codecov / codecov/patch

server/export.go#L98-L105

Added lines #L98 - L105 were not covered by tests

doc, err := tmtypes.GenesisDocFromFile(serverCtx.Config.GenesisFile())
if err != nil {
return err
}

Check warning on line 110 in server/export.go

View check run for this annotation

Codecov / codecov/patch

server/export.go#L107-L110

Added lines #L107 - L110 were not covered by tests

genesisDocNoAppHash := GenesisDocNoAppState{
GenesisTime: doc.GenesisTime,
ChainID: doc.ChainID,
AppHash: doc.AppHash,
InitialHeight: exported.Height,
ConsensusParams: &tmtypes.ConsensusParams{
Block: tmtypes.BlockParams{
MaxBytes: exported.ConsensusParams.Block.MaxBytes,
MaxGas: exported.ConsensusParams.Block.MaxGas,
},
Evidence: tmtypes.EvidenceParams{
MaxAgeNumBlocks: exported.ConsensusParams.Evidence.MaxAgeNumBlocks,
MaxAgeDuration: exported.ConsensusParams.Evidence.MaxAgeDuration,
MaxBytes: exported.ConsensusParams.Evidence.MaxBytes,
},
Validator: tmtypes.ValidatorParams{
PubKeyTypes: exported.ConsensusParams.Validator.PubKeyTypes,
},
},
Validators: exported.Validators,
}

// NOTE: Tendermint uses a custom JSON decoder for GenesisDoc
// (except for stuff inside AppState). Inside AppState, we're free
// to encode as protobuf or amino.
encoded, err := json.Marshal(genesisDocNoAppHash)
if err != nil {
return err
}

Check warning on line 140 in server/export.go

View check run for this annotation

Codecov / codecov/patch

server/export.go#L112-L140

Added lines #L112 - L140 were not covered by tests

file.Write([]byte(fmt.Sprintf("%s", string(sdk.MustSortJSON(encoded)))))
return nil

Check warning on line 143 in server/export.go

View check run for this annotation

Codecov / codecov/patch

server/export.go#L142-L143

Added lines #L142 - L143 were not covered by tests
}

exported, err := appExporter(serverCtx.Logger, db, traceWriter, height, forZeroHeight, jailAllowedAddrs, serverCtx.Viper, nil)
if err != nil {
return fmt.Errorf("error exporting state: %v", err)
}
Expand Down Expand Up @@ -108,6 +184,8 @@
},
}

cmd.Flags().Bool(FlagIsStreaming, false, "Whether to stream the export in chunks. Useful when genesis is extremely large and cannot fit into memory.")
cmd.Flags().String(FlagStreamingFile, "genesis-stream.json", "The file to export the streamed genesis to")
cmd.Flags().String(flags.FlagHome, defaultNodeHome, "The application home directory")
cmd.Flags().Int64(FlagHeight, -1, "Export state from a particular height (-1 means latest height)")
cmd.Flags().Bool(FlagForZeroHeight, false, "Export state to start at height zero (perform preproccessing)")
Expand Down
2 changes: 1 addition & 1 deletion server/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ func setupApp(t *testing.T, tempDir string) (*simapp.SimApp, context.Context, *t
app.Commit(context.Background())

cmd := server.ExportCmd(
func(_ log.Logger, _ dbm.DB, _ io.Writer, height int64, forZeroHeight bool, jailAllowedAddrs []string, appOptons types.AppOptions) (types.ExportedApp, error) {
func(_ log.Logger, _ dbm.DB, _ io.Writer, height int64, forZeroHeight bool, jailAllowedAddrs []string, appOptons types.AppOptions, file *os.File) (types.ExportedApp, error) {
encCfg := simapp.MakeTestEncodingConfig()

var simApp *simapp.SimApp
Expand Down
28 changes: 22 additions & 6 deletions server/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

clientconfig "github.com/cosmos/cosmos-sdk/client/config"

genesistypes "github.com/cosmos/cosmos-sdk/types/genesis"
"github.com/spf13/cobra"
abciclient "github.com/tendermint/tendermint/abci/client"
"github.com/tendermint/tendermint/abci/server"
Expand Down Expand Up @@ -170,11 +171,6 @@

serverCtx.Viper.Set(flags.FlagChainID, chainID)

genesisFile, _ := tmtypes.GenesisDocFromFile(serverCtx.Config.GenesisFile())
if genesisFile.ChainID != clientCtx.ChainID {
panic(fmt.Sprintf("genesis file chain-id=%s does not equal config.toml chain-id=%s", genesisFile.ChainID, clientCtx.ChainID))
}

if enableTracing, _ := cmd.Flags().GetBool(tracing.FlagTracing); !enableTracing {
serverCtx.Logger.Info("--tracing not passed in, tracing is not enabled")
tracerProviderOptions = []trace.TracerProviderOption{}
Expand All @@ -197,6 +193,12 @@
if err != nil {
return fmt.Errorf("failed to initialize telemetry: %w", err)
}
if !config.Genesis.StreamImport {
genesisFile, _ := tmtypes.GenesisDocFromFile(serverCtx.Config.GenesisFile())
if genesisFile.ChainID != clientCtx.ChainID {
panic(fmt.Sprintf("genesis file chain-id=%s does not equal config.toml chain-id=%s", genesisFile.ChainID, clientCtx.ChainID))

Check warning on line 199 in server/start.go

View check run for this annotation

Codecov / codecov/patch

server/start.go#L196-L199

Added lines #L196 - L199 were not covered by tests
}
}

restartCoolDownDuration := time.Second * time.Duration(serverCtx.Config.SelfRemediation.RestartCooldownSeconds)
// Set the first restart time to be now - restartCoolDownDuration so that the first restart can trigger whenever
Expand Down Expand Up @@ -386,13 +388,27 @@
config.GRPC.Enable = true
} else {
ctx.Logger.Info("starting node with ABCI Tendermint in-process")
var gen *tmtypes.GenesisDoc
if config.Genesis.StreamImport {
lines := genesistypes.IngestGenesisFileLineByLine(config.Genesis.ImportFile)
for line := range lines {
genDoc, err := tmtypes.GenesisDocFromJSON([]byte(line))
if err != nil {
continue

Check warning on line 397 in server/start.go

View check run for this annotation

Codecov / codecov/patch

server/start.go#L391-L397

Added lines #L391 - L397 were not covered by tests
jewei1997 marked this conversation as resolved.
Show resolved Hide resolved
}
if gen != nil {
return fmt.Errorf("error: multiple genesis docs found in stream")
}
gen = genDoc

Check warning on line 402 in server/start.go

View check run for this annotation

Codecov / codecov/patch

server/start.go#L399-L402

Added lines #L399 - L402 were not covered by tests
}
}
tmNode, err = node.New(
goCtx,
ctx.Config,
ctx.Logger,
restartCh,
abciclient.NewLocalClient(ctx.Logger, app),
nil,
gen,

Check warning on line 411 in server/start.go

View check run for this annotation

Codecov / codecov/patch

server/start.go#L411

Added line #L411 was not covered by tests
tracerProviderOptions,
nodeMetricsProvider,
)
Expand Down
4 changes: 3 additions & 1 deletion server/types/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package types
import (
"encoding/json"
"io"
"os"
"time"

sdk "github.com/cosmos/cosmos-sdk/types"
Expand Down Expand Up @@ -84,5 +85,6 @@ type (

// AppExporter is a function that dumps all app state to
// JSON-serializable structure and returns the current validator set.
AppExporter func(log.Logger, dbm.DB, io.Writer, int64, bool, []string, AppOptions) (ExportedApp, error)
// If a file is specified,
AppExporter func(log.Logger, dbm.DB, io.Writer, int64, bool, []string, AppOptions, *os.File) (ExportedApp, error)
)
3 changes: 2 additions & 1 deletion simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/cosmos/cosmos-sdk/store/streaming"
"github.com/cosmos/cosmos-sdk/testutil/testdata"
sdk "github.com/cosmos/cosmos-sdk/types"
genesistypes "github.com/cosmos/cosmos-sdk/types/genesis"
"github.com/cosmos/cosmos-sdk/types/module"
"github.com/cosmos/cosmos-sdk/utils"
"github.com/cosmos/cosmos-sdk/version"
Expand Down Expand Up @@ -594,7 +595,7 @@ func (app *SimApp) InitChainer(ctx sdk.Context, req abci.RequestInitChain) abci.
panic(err)
}
app.UpgradeKeeper.SetModuleVersionMap(ctx, app.mm.GetVersionMap())
return app.mm.InitGenesis(ctx, app.appCodec, genesisState)
return app.mm.InitGenesis(ctx, app.appCodec, genesisState, genesistypes.GenesisImportConfig{})
}

// LoadHeight loads a particular height
Expand Down
3 changes: 2 additions & 1 deletion simapp/sim_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/cosmos/cosmos-sdk/simapp/helpers"
"github.com/cosmos/cosmos-sdk/store"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/genesis"
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
authzkeeper "github.com/cosmos/cosmos-sdk/x/authz/keeper"
Expand Down Expand Up @@ -155,7 +156,7 @@ func TestAppImportExport(t *testing.T) {

ctxA := app.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()})
ctxB := newApp.NewContext(true, tmproto.Header{Height: app.LastBlockHeight()})
newApp.mm.InitGenesis(ctxB, app.AppCodec(), genesisState)
newApp.mm.InitGenesis(ctxB, app.AppCodec(), genesisState, genesis.GenesisImportConfig{})
newApp.StoreConsensusParams(ctxB, exported.ConsensusParams)

fmt.Printf("comparing stores...\n")
Expand Down
2 changes: 1 addition & 1 deletion simapp/simd/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@
// and exports state.
func (a appCreator) appExport(
logger log.Logger, db dbm.DB, traceStore io.Writer, height int64, forZeroHeight bool, jailAllowedAddrs []string,
appOpts servertypes.AppOptions) (servertypes.ExportedApp, error) {
appOpts servertypes.AppOptions, file *os.File) (servertypes.ExportedApp, error) {

Check warning on line 316 in simapp/simd/cmd/root.go

View check run for this annotation

Codecov / codecov/patch

simapp/simd/cmd/root.go#L316

Added line #L316 was not covered by tests

var simApp *simapp.SimApp
homePath, ok := appOpts.Get(flags.FlagHome).(string)
Expand Down
Loading
Loading