Skip to content

Commit

Permalink
Merge pull request #59 from bnb-chain/develop
Browse files Browse the repository at this point in the history
feat: support custom blocks to rollback, fix bug in rollback, add support for state sync at specific height
  • Loading branch information
cosinlink authored Jan 26, 2024
2 parents 1145516 + 612799c commit 13fc717
Show file tree
Hide file tree
Showing 19 changed files with 337 additions and 134 deletions.
30 changes: 20 additions & 10 deletions cmd/cometbft/commands/rollback.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,36 @@ import (
"github.com/cometbft/cometbft/store"
)

const (
maxRollbackBlocks = uint(1000)
)

var removeBlock = false
var rollbackBlocks = uint(1)

func init() {
RollbackStateCmd.Flags().BoolVar(&removeBlock, "hard", false, "remove last block as well as state")
RollbackStateCmd.Flags().UintVar(&rollbackBlocks, "blocks", 1, "number of blocks to rollback")
RollbackStateCmd.Flags().BoolVar(&removeBlock, "hard", false, "remove blocks as well as state")
}

var RollbackStateCmd = &cobra.Command{
Use: "rollback",
Short: "rollback CometBFT state by one height",
Short: "rollback CometBFT state",
Long: `
A state rollback is performed to recover from an incorrect application state transition,
when CometBFT has persisted an incorrect app hash and is thus unable to make
progress. Rollback overwrites a state at height n with the state at height n - 1.
The application should also roll back to height n - 1. If the --hard flag is not used,
no blocks will be removed so upon restarting CometBFT the transactions in block n will be
re-executed against the application. Using --hard will also remove block n. This can
progress. Rollback overwrites a state at height n with the state at height n - rollbackBlocks.
The application should also roll back to height n - rollbackBlocks. If the --hard flag is not used,
no blocks will be removed so upon restarting CometBFT the transactions in block n will be
re-executed against the application. Using --hard will also remove blocks n, n-1 ...n - rollbackBlocks + 1 . This can
be done multiple times.
`,
RunE: func(cmd *cobra.Command, args []string) error {
height, hash, err := RollbackState(config, removeBlock)
if rollbackBlocks == 0 || rollbackBlocks > maxRollbackBlocks {
return fmt.Errorf("invalid rollback blocks: %v", rollbackBlocks)
}

height, hash, err := RollbackState(config, removeBlock, int64(rollbackBlocks))
if err != nil {
return fmt.Errorf("failed to rollback state: %w", err)
}
Expand All @@ -49,9 +59,9 @@ be done multiple times.
}

// RollbackState takes the state at the current height n and overwrites it with the state
// at height n - 1. Note state here refers to CometBFT state not application state.
// at height n - rollbackBlocks. Note state here refers to CometBFT state not application state.
// Returns the latest state height and app hash alongside an error if there was one.
func RollbackState(config *cfg.Config, removeBlock bool) (int64, []byte, error) {
func RollbackState(config *cfg.Config, removeBlock bool, rollbackBlocks int64) (int64, []byte, error) {
// use the parsed config to load the block and state store
blockStore, stateStore, err := loadStateAndBlockStore(config)
if err != nil {
Expand All @@ -63,7 +73,7 @@ func RollbackState(config *cfg.Config, removeBlock bool) (int64, []byte, error)
}()

// rollback the last state
return state.Rollback(blockStore, stateStore, removeBlock)
return state.Rollback(blockStore, stateStore, removeBlock, rollbackBlocks)
}

func loadStateAndBlockStore(config *cfg.Config) (*store.BlockStore, state.Store, error) {
Expand Down
5 changes: 3 additions & 2 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ type Config struct {
Mempool *MempoolConfig `mapstructure:"mempool"`
StateSync *StateSyncConfig `mapstructure:"statesync"`
BlockSync *BlockSyncConfig `mapstructure:"blocksync"`
//TODO(williambanfield): remove this field once v0.37 is released.
// TODO(williambanfield): remove this field once v0.37 is released.
// https://github.com/tendermint/tendermint/issues/9279
DeprecatedFastSyncConfig map[interface{}]interface{} `mapstructure:"fastsync"`
Consensus *ConsensusConfig `mapstructure:"consensus"`
Expand Down Expand Up @@ -202,7 +202,7 @@ type BaseConfig struct { //nolint: maligned
// Deprecated: BlockSync will be enabled unconditionally in the next major release.
BlockSyncMode bool `mapstructure:"block_sync"`

//TODO(williambanfield): remove this field once v0.37 is released.
// TODO(williambanfield): remove this field once v0.37 is released.
// https://github.com/tendermint/tendermint/issues/9279
DeprecatedFastSyncMode interface{} `mapstructure:"fast_sync"`

Expand Down Expand Up @@ -854,6 +854,7 @@ type StateSyncConfig struct {
DiscoveryTime time.Duration `mapstructure:"discovery_time"`
ChunkRequestTimeout time.Duration `mapstructure:"chunk_request_timeout"`
ChunkFetchers int32 `mapstructure:"chunk_fetchers"`
TargetHeight int64 `mapstructure:"target_height"`
}

func (cfg *StateSyncConfig) TrustHashBytes() []byte {
Expand Down
4 changes: 4 additions & 0 deletions config/toml.go
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,10 @@ chunk_request_timeout = "{{ .StateSync.ChunkRequestTimeout }}"
# The number of concurrent chunk fetchers to run (default: 1).
chunk_fetchers = "{{ .StateSync.ChunkFetchers }}"
# The target height to sync (default: 0).
# If not provided, the node will sync to the best snapshot.
target_height = "{{ .StateSync.TargetHeight }}"
#######################################################
### Block Sync Configuration Options ###
#######################################################
Expand Down
2 changes: 2 additions & 0 deletions consensus/replay_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1232,6 +1232,8 @@ func (bs *mockBlockStore) PruneBlocks(height int64) (uint64, error) {

func (bs *mockBlockStore) DeleteLatestBlock() error { return nil }

func (bs *mockBlockStore) DeleteLatestBlocks(n uint64) error { return nil }

//---------------------------------------
// Test handshake/init chain

Expand Down
9 changes: 6 additions & 3 deletions docs/core/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ moniker = "anonymous"
# allows them to catchup quickly by downloading blocks in parallel
# and verifying their commits
#
# Deprecated: this key will be removed and BlockSync will be enabled
# Deprecated: this key will be removed and BlockSync will be enabled
# unconditionally in the next major release.
block_sync = true

Expand Down Expand Up @@ -380,13 +380,17 @@ chunk_request_timeout = "10s"
# The number of concurrent chunk fetchers to run (default: 1).
chunk_fetchers = "4"

# The target height to sync (default: 0).
# If not provided, the node will sync to the best snapshot.
target_height = "0"

#######################################################
### Block Sync Configuration Options ###
#######################################################
[blocksync]

# Block Sync version to use:
#
#
# In v0.37, v1 and v2 of the block sync protocols were deprecated.
# Please use v0 instead.
#
Expand Down Expand Up @@ -541,4 +545,3 @@ Here's a brief summary of the timeouts:
- `timeout_commit` = how long we wait after committing a block, before starting
on the new height (this gives us a chance to receive some more precommits,
even though we already have +2/3)

34 changes: 17 additions & 17 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ require (
github.com/spf13/cobra v1.6.1
github.com/spf13/viper v1.13.0
github.com/stretchr/testify v1.8.4
golang.org/x/crypto v0.14.0
golang.org/x/net v0.17.0
golang.org/x/crypto v0.17.0
golang.org/x/net v0.19.0
google.golang.org/grpc v1.58.3
)

Expand All @@ -52,7 +52,7 @@ require (
github.com/cometbft/cometbft-db v0.7.0
github.com/cosmos/gogoproto v1.4.1
github.com/ethereum/go-ethereum v1.10.26
github.com/go-git/go-git/v5 v5.5.2
github.com/go-git/go-git/v5 v5.11.0
github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d
github.com/prysmaticlabs/prysm v0.0.0-20220124113610-e26cde5e091b
github.com/vektra/mockery/v2 v2.14.0
Expand All @@ -63,18 +63,18 @@ require (
require (
4d63.com/gocheckcompilerdirectives v1.2.1 // indirect
4d63.com/gochecknoglobals v0.2.1 // indirect
dario.cat/mergo v1.0.0 // indirect
github.com/Abirdcfly/dupword v0.0.9 // indirect
github.com/Antonboom/errname v0.1.7 // indirect
github.com/Antonboom/nilnil v0.1.1 // indirect
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect
github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 // indirect
github.com/Masterminds/semver v1.5.0 // indirect
github.com/Microsoft/go-winio v0.6.0 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
github.com/OpenPeeDeeP/depguard v1.1.1 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20221026131551-cf6655e29de4 // indirect
github.com/acomagu/bufpipe v1.0.3 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect
github.com/alexkohler/prealloc v1.0.0 // indirect
github.com/alingse/asasalint v0.0.11 // indirect
github.com/ashanbrown/forbidigo v1.4.0 // indirect
Expand All @@ -99,6 +99,7 @@ require (
github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/curioswitch/go-reassign v0.2.0 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/daixiang0/gci v0.9.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
Expand All @@ -122,8 +123,8 @@ require (
github.com/fzipp/gocyclo v0.6.0 // indirect
github.com/go-chi/chi/v5 v5.0.7 // indirect
github.com/go-critic/go-critic v0.6.7 // indirect
github.com/go-git/gcfg v1.5.0 // indirect
github.com/go-git/go-billy/v5 v5.4.0 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.5.0 // indirect
github.com/go-logr/logr v1.2.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-toolsmith/astcast v1.1.0 // indirect
Expand All @@ -150,7 +151,7 @@ require (
github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 // indirect
github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28 // indirect
github.com/gostaticanalysis/analysisutil v0.7.1 // indirect
github.com/gostaticanalysis/comment v1.4.2 // indirect
Expand All @@ -164,7 +165,6 @@ require (
github.com/hashicorp/go-version v1.6.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/hexops/gotextdiff v1.0.3 // indirect
github.com/imdario/mergo v0.3.13 // indirect
github.com/inconshreveable/mousetrap v1.0.1 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/jdxcode/netrc v0.0.0-20210204082910-926c7f70242a // indirect
Expand Down Expand Up @@ -222,7 +222,7 @@ require (
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.0.5 // indirect
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 // indirect
github.com/pjbgf/sha1cd v0.2.3 // indirect
github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/pkg/profile v1.6.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
Expand Down Expand Up @@ -250,7 +250,7 @@ require (
github.com/sivchari/containedctx v1.0.2 // indirect
github.com/sivchari/nosnakecase v1.7.0 // indirect
github.com/sivchari/tenv v1.7.1 // indirect
github.com/skeema/knownhosts v1.1.0 // indirect
github.com/skeema/knownhosts v1.2.1 // indirect
github.com/sonatard/noctx v0.0.1 // indirect
github.com/sourcegraph/go-diff v0.7.0 // indirect
github.com/spf13/afero v1.8.2 // indirect
Expand Down Expand Up @@ -289,12 +289,12 @@ require (
go.uber.org/zap v1.23.0 // indirect
golang.org/x/exp v0.0.0-20230131160201-f062dba9d201 // indirect
golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9 // indirect
golang.org/x/mod v0.8.0 // indirect
golang.org/x/mod v0.12.0 // indirect
golang.org/x/sync v0.3.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/term v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/tools v0.6.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/term v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/tools v0.13.0 // indirect
google.golang.org/genproto v0.0.0-20230711160842-782d3b101e98 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
Expand Down
Loading

0 comments on commit 13fc717

Please sign in to comment.