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

chore: small snapshot commands & docs improvement (backport #16404) #16409

Merged
merged 2 commits into from
Jun 2, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 0 additions & 1 deletion client/snapshot/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ func Cmd(appCreator servertypes.AppCreator) *cobra.Command {
cmd := &cobra.Command{
Use: "snapshots",
Short: "Manage local snapshots",
Long: "Manage local snapshots",
}
cmd.AddCommand(
ListSnapshotsCmd,
Expand Down
6 changes: 2 additions & 4 deletions client/snapshot/export.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package snapshot

import (
"fmt"

"github.com/cosmos/cosmos-sdk/server"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -34,15 +32,15 @@ func ExportSnapshotCmd(appCreator servertypes.AppCreator) *cobra.Command {
height = app.CommitMultiStore().LastCommitID().Version
}

fmt.Printf("Exporting snapshot for height %d\n", height)
cmd.Printf("Exporting snapshot for height %d\n", height)

sm := app.SnapshotManager()
snapshot, err := sm.Create(uint64(height))
if err != nil {
return err
}

fmt.Printf("Snapshot created at height %d, format %d, chunks %d\n", snapshot.Height, snapshot.Format, snapshot.Chunks)
cmd.Printf("Snapshot created at height %d, format %d, chunks %d\n", snapshot.Height, snapshot.Format, snapshot.Chunks)
return nil
},
}
Expand Down
2 changes: 1 addition & 1 deletion client/snapshot/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ var ListSnapshotsCmd = &cobra.Command{
return fmt.Errorf("failed to list snapshots: %w", err)
}
for _, snapshot := range snapshots {
fmt.Println("height:", snapshot.Height, "format:", snapshot.Format, "chunks:", snapshot.Chunks)
cmd.Println("height:", snapshot.Height, "format:", snapshot.Format, "chunks:", snapshot.Chunks)
}

return nil
Expand Down
4 changes: 2 additions & 2 deletions client/snapshot/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const SnapshotFileName = "_snapshot"
func LoadArchiveCmd() *cobra.Command {
return &cobra.Command{
Use: "load <archive-file>",
Short: "Load a snapshot archive file into snapshot store",
Short: "Load a snapshot archive file (.tar.gz) into snapshot store",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
ctx := server.GetServerContextFromCmd(cmd)
Expand Down Expand Up @@ -70,7 +70,7 @@ func LoadArchiveCmd() *cobra.Command {

savedSnapshot, err := snapshotStore.Save(snapshot.Height, snapshot.Format, chunks)
if err != nil {
fmt.Println("failed to save snapshot", err)
cmd.Println("failed to save snapshot", err)
return
}
quitChan <- savedSnapshot
Expand Down
38 changes: 32 additions & 6 deletions docs/run-node/run-node.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,15 +127,41 @@ The naive way would be to run the same commands again in separate terminal windo

## State Sync

State sync is the act in which a node syncs the latest or close to the latest state of a blockchain. This is useful for users who don't want to sync all the blocks in history. You can read more here: https://docs.cometbft.com/v0.37/core/state-sync
State sync is the act in which a node syncs the latest or close to the latest state of a blockchain. This is useful for users who don't want to sync all the blocks in history. Read more in [CometBFT documentation](https://docs.cometbft.com/v0.34/core/state-sync).

State sync works thanks to snapshots. Read how the SDK handles snapshots [here](https://github.com/cosmos/cosmos-sdk/blob/825245d/store/snapshots/README.md).

### Local State Sync

Local state sync work similar to normal state sync except that it works off a local snapshot of state instead of one provided via the p2p network. The steps to start local state sync are similar to normal state sync with a few different designs.

1. As mentioned in https://docs.cometbft.com/v0.37/core/state-sync, one must set a height and hash in the config.toml along with a few rpc servers (the afromentioned link has instructions on how to do this).
2. Bootsrapping Comet state in order to start the node after the snapshot has been ingested. This can be done with the bootstrap command `<app> comet bootstrap-state`
<!-- 3. TODO after https://github.com/cosmos/cosmos-sdk/pull/16060 is merged -->
## Next {hide}
1. As mentioned in https://docs.cometbft.com/v0.34/core/state-sync, one must set a height and hash in the config.toml along with a few rpc servers (the afromentioned link has instructions on how to do this).
2. Run `<appd snapshot restore <height> <format>` to restore a local snapshot (note: first load it from a file with the *load* command).
3. Bootsrapping Comet state in order to start the node after the snapshot has been ingested. This can be done with the bootstrap command `<app> tendermint bootstrap-state`

### Snapshots Commands

The Cosmos SDK provides commands for managing snapshots.
These commands can be added in an app with the following snippet in `cmd/<app>/root.go`:

```go
import (
"github.com/cosmos/cosmos-sdk/client/snapshot"
)

func initRootCmd(/* ... */) {
// ...
rootCmd.AddCommand(
snapshot.Cmd(appCreator),
)
}
```

Then following commands are available at `<appd> snapshots [command]`:

Read about the [Interacting with your Node](./interact-node.md) {hide}
* **list**: list local snapshots
* **load**: Load a snapshot archive file into snapshot store
* **restore**: Restore app state from local snapshot
* **export**: Export app state to snapshot store
* **dump**: Dump the snapshot as portable archive format
* **delete**: Delete a local snapshot
2 changes: 1 addition & 1 deletion server/tm_cmds.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ func BootstrapStateCmd(appCreator types.AppCreator) *cobra.Command {
},
}

cmd.Flags().Int64("height", 0, "Block height to bootstrap state at, if not provided will use the latest block height in app state")
cmd.Flags().Int64("height", 0, "Block height to bootstrap state at, if not provided it uses the latest block height in app state")

return cmd
}
5 changes: 3 additions & 2 deletions server/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,8 +273,9 @@ func interceptConfigs(rootViper *viper.Viper, customAppTemplate string, customCo
// add server commands
func AddCommands(rootCmd *cobra.Command, defaultNodeHome string, appCreator types.AppCreator, appExport types.AppExporter, addStartFlags types.ModuleInitFlags) {
tendermintCmd := &cobra.Command{
Use: "tendermint",
Short: "Tendermint subcommands",
Use: "tendermint",
Aliases: []string{"comet", "cometbft"},
Short: "Tendermint subcommands",
}

tendermintCmd.AddCommand(
Expand Down
23 changes: 11 additions & 12 deletions snapshots/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,16 @@ Snapshot settings are optional. However, if set, they have an effect on how prun
persisting the heights that are multiples of `state-sync.snapshot-interval` until after the snapshot is complete.

If pruning is enabled (not `pruning = "nothing"`), we avoid pruning heights that are multiples of
`state-sync.snapshot-interval` in the regular logic determined by the
pruning settings and applied after every `Commit()`. This is done to prevent a
height from being removed before a snapshot is complete. Therefore, we keep
such heights until after a snapshot is done. At this point, the height is sent to
`state-sync.snapshot-interval` in the regular logic determined by the
pruning settings and applied after every `Commit()`. This is done to prevent a
height from being removed before a snapshot is complete. Therefore, we keep
such heights until after a snapshot is done. At this point, the height is sent to
the `pruning.Manager` to be pruned according to the pruning settings after the next `Commit()`.

To illustrate, assume that we are currently at height 960 with `pruning-keep-recent = 50`,
`pruning-interval = 10`, and `state-sync.snapshot-interval = 100`. Let's assume that
the snapshot that was triggered at height `900` **just finishes**. Then, we can prune height
`900` right away (that is, when we call `Commit()` at height 960 because 900 is less than `960 - 50 = 910`.
`900` right away (that is, when we call `Commit()` at height 960 because 900 is less than `960 - 50 = 910`).

Let's now assume that all conditions stay the same but the snapshot at height 900 is **not complete yet**.
Then, we cannot prune it to avoid deleting a height that is still being snapshotted. Therefore, we keep track
Expand All @@ -78,23 +78,22 @@ Note that in both examples, if we let current height = C, and previous height P

P - `pruning-keep-recent` - `pruning-interval` <= h <= P - `pruning-keep-recent`

we can prune height h. In our first example, all heights 899 - 909 fall in this range and are pruned at height 960 as long as
we can prune height h. In our first example, all heights 899 - 909 fall in this range and are pruned at height 960 as long as
h is not a snapshot height (E.g. 900).

That is, we always use current height to determine at which height to prune (960) while we use previous
to determine which heights are to be pruned (959 - 50 - 10 = 899-909 = 959 - 50).


## Configuration

* `state-sync.snapshot-interval`
* the interval at which to take snapshots.
* the value of 0 disables snapshots.
* if pruning is enabled, it is done after a snapshot is complete for the heights that are multiples of this interval.
* the interval at which to take snapshots.
* the value of 0 disables snapshots.
* if pruning is enabled, it is done after a snapshot is complete for the heights that are multiples of this interval.

* `state-sync.snapshot-keep-recent`:
* the number of recent snapshots to keep.
* 0 means keep all.
* the number of recent snapshots to keep.
* 0 means keep all.

## Snapshot Metadata

Expand Down