diff --git a/Gopkg.lock b/Gopkg.lock index 2df087d59..0863943eb 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -55,8 +55,8 @@ revision = "d4cc87b860166d00d6b5b9e0d3b3d71d6088d4d4" [[projects]] - branch = "develop" - digest = "1:d666b920d3fbbe614d13cfa3656a34fb6cd0cfcfc5333a755774c5c58442c97d" + branch = "release/v0.25.0-binance.18" + digest = "1:dcf0dd82d24effc14335caeb94e8d0f13dd51e62e686d0f0f0d85784c4a281e5" name = "github.com/cosmos/cosmos-sdk" packages = [ "baseapp", @@ -104,7 +104,7 @@ "x/stake/types", ] pruneopts = "UT" - revision = "d595a84b199811205a8632b5f1a0782b450314a3" + revision = "" source = "github.com/binance-chain/bnc-cosmos-sdk" [[projects]] @@ -591,17 +591,17 @@ version = "v0.14.1-binance.1" [[projects]] - digest = "1:c317eec9047bdcd14dff925f34e07d22c6886faf22bf7c9286ea56ad962bcc22" + branch = "release/v0.12.0-binance.1" + digest = "1:d059e9aff696313113cafc12955cfdf41fae32a7f183334929b846c9fbb3e4b9" name = "github.com/tendermint/iavl" packages = ["."] pruneopts = "UT" - revision = "65e487d3a8d4d6624d8779c1f42cff31d61a9146" + revision = "" source = "github.com/binance-chain/bnc-tendermint-iavl" - version = "v0.12.0-binance.0" [[projects]] - branch = "develop" - digest = "1:32214aa8210aac34a1a8a23af458c628f7931b17d500940af5ccb0b9afaf89f7" + branch = "release/v0.31.5-binance.0" + digest = "1:04d3a35cd2a2e4a6366ecd3b6909ef1a2a67da54e017f1248cab52746dc29e97" name = "github.com/tendermint/tendermint" packages = [ "abci/client", @@ -660,6 +660,7 @@ "rpc/lib/client", "rpc/lib/server", "rpc/lib/types", + "snapshot", "state", "state/blockindex", "state/blockindex/kv", @@ -672,7 +673,7 @@ "version", ] pruneopts = "UT" - revision = "ef181dd2019f342be39436c2265910e816e66172" + revision = "" source = "github.com/binance-chain/bnc-tendermint" [[projects]] @@ -913,6 +914,7 @@ "github.com/tendermint/tendermint/rpc/client", "github.com/tendermint/tendermint/rpc/core/types", "github.com/tendermint/tendermint/rpc/lib/server", + "github.com/tendermint/tendermint/snapshot", "github.com/tendermint/tendermint/state", "github.com/tendermint/tendermint/types", "go.uber.org/ratelimit", diff --git a/Gopkg.toml b/Gopkg.toml index 40d6f18c0..1a6f4994d 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -32,21 +32,27 @@ [[override]] name = "github.com/tendermint/iavl" source = "github.com/binance-chain/bnc-tendermint-iavl" - version = "=v0.12.0-binance.0" + branch = "release/v0.12.0-binance.1" +# version = "=v0.12.0-binance.0" [[override]] name = "github.com/tendermint/tendermint" source = "github.com/binance-chain/bnc-tendermint" - branch = "develop" + branch = "release/v0.31.5-binance.0" +# version = "=v0.30.1-binance.3" [[constraint]] name = "github.com/cosmos/cosmos-sdk" source = "github.com/binance-chain/bnc-cosmos-sdk" - branch = "develop" + branch = "release/v0.25.0-binance.18" [[prune.project]] name = "github.com/zondax/hid" unused-packages = false +[[constraint]] + name = "github.com/btcsuite/btcd" + revision = "ed77733ec07dfc8a513741138419b8d9d3de9d2d" + [[constraint]] name = "github.com/pkg/errors" version = "0.8.0" diff --git a/app/app.go b/app/app.go index c8ae3f808..d5ae78870 100644 --- a/app/app.go +++ b/app/app.go @@ -10,6 +10,7 @@ import ( "time" "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" @@ -81,8 +82,6 @@ type BinanceChain struct { govKeeper gov.Keeper // keeper to process param store and update ParamHub *param.ParamHub - // manage state sync related status - StateSyncManager baseConfig *config.BaseConfig upgradeConfig *config.UpgradeConfig @@ -94,7 +93,7 @@ type BinanceChain struct { // TODO(#246): make it an aggregated wrapper of all component metrics (i.e. DexKeeper, StakeKeeper) metrics *pub.Metrics - blockStore *blockchain.BlockStore + takeSnapshotHeight int64 // whether to take snapshot of current height, set at endblock(), reset at commit() } // NewBinanceChain creates a new instance of the BinanceChain. @@ -115,7 +114,6 @@ func NewBinanceChain(logger log.Logger, db dbm.DB, traceStore io.Writer, baseApp } // set upgrade config app.setUpgradeConfig() - app.SetPruning(viper.GetString("pruning")) app.initRunningMode() app.SetCommitMultiStoreTracer(traceStore) @@ -226,7 +224,11 @@ func NewBinanceChain(logger log.Logger, db dbm.DB, traceStore io.Writer, baseApp app.initGovHooks() app.initPlugins() app.initParams() - app.initStateSyncManager(ServerContext.Config.StateSyncReactor) + if ServerContext.Config.StateSyncReactor { + lastBreatheBlockHeight := app.getLastBreatheBlockHeight() + app.StateSyncHelper = store.NewStateSyncHelper(app.Logger.With("module", "statesync"), db, app.GetCommitMultiStore(), app.Codec) + app.StateSyncHelper.Init(lastBreatheBlockHeight) + } return app } @@ -253,12 +255,18 @@ func (app *BinanceChain) initDex(pairMapper dex.TradingPairMapper) { return } // count back to days in config. + blockDB := baseapp.LoadBlockDB() + defer blockDB.Close() + blockStore := blockchain.NewBlockStore(blockDB) + txDB := baseapp.LoadTxDB() + defer txDB.Close() + app.DexKeeper.Init( app.CheckState.Ctx, app.baseConfig.BreatheBlockInterval, app.baseConfig.BreatheBlockDaysCountBack, - baseapp.LoadBlockDB(), - baseapp.LoadTxDB(), + blockStore, + txDB, app.LastBlockHeight(), app.TxDecoder) } @@ -464,13 +472,12 @@ func (app *BinanceChain) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) a // breathe block bnclog.Info("Start Breathe Block Handling", "height", height, "lastBlockTime", lastBlockTime, "newBlockTime", blockTime) + app.takeSnapshotHeight = height icoDone := ico.EndBlockAsync(ctx) dex.EndBreatheBlock(ctx, app.DexKeeper, app.govKeeper, height, blockTime) param.EndBreatheBlock(ctx, app.ParamHub) // other end blockers <-icoDone - // fire and forget reload snapshot - go app.reloadSnapshot(height, true) } app.DexKeeper.StoreTradePrices(ctx) @@ -513,6 +520,26 @@ func (app *BinanceChain) EndBlocker(ctx sdk.Context, req abci.RequestEndBlock) a } } +func (app *BinanceChain) Commit() (res abci.ResponseCommit) { + res = app.BaseApp.Commit() + if ServerContext.Config.StateSyncReactor && app.takeSnapshotHeight > 0 { + app.StateSyncHelper.SnapshotHeights <- app.takeSnapshotHeight + app.takeSnapshotHeight = 0 + } + return +} + +func (app *BinanceChain) WriteRecoveryChunk(hash abci.SHA256Sum, chunk *abci.AppStateChunk, isComplete bool) (err error) { + err = app.BaseApp.WriteRecoveryChunk(hash, chunk, isComplete) + if err != nil { + return err + } + if isComplete { + err = app.reInitChain() + } + return err +} + // ExportAppStateAndValidators exports blockchain world state to json. func (app *BinanceChain) ExportAppStateAndValidators() (appState json.RawMessage, validators []tmtypes.GenesisValidator, err error) { ctx := app.NewContext(sdk.RunTxModeCheck, abci.Header{}) @@ -719,27 +746,3 @@ func (app *BinanceChain) publish(tradesToPublish []*pub.Trade, proposalsToPublis pub.Logger.Debug("finish publish", "height", height) } - -// SetPruning sets a pruning option on the multistore associated with the app -func (app *BinanceChain) SetPruning(pruning string) { - var pruningStrategy sdk.PruningStrategy - switch pruning { - case "nothing": - pruningStrategy = sdk.PruneNothing{} - case "everything": - pruningStrategy = sdk.PruneEverything{} - case "syncable": - // TODO: make these parameters configurable - pruningStrategy = sdk.PruneSyncable{NumRecent: 100, StoreEvery: 10000} - case "breathe": - pruningStrategy = NewKeepRecentAndBreatheBlock(int64(app.baseConfig.BreatheBlockInterval), 10000, ServerContext.Config) - default: - pruningStrategy = NewKeepRecentAndBreatheBlock(int64(app.baseConfig.BreatheBlockInterval), 10000, ServerContext.Config) - app.Logger.Error("failed to load pruning, set to breathe", "strategy", pruning) - } - app.BaseApp.SetPruning(pruningStrategy) -} - -func (app *BinanceChain) SetBlockStore(store *blockchain.BlockStore) { - app.blockStore = store -} diff --git a/app/app_pub_test.go b/app/app_pub_test.go index 92e22fd84..d03e905b6 100644 --- a/app/app_pub_test.go +++ b/app/app_pub_test.go @@ -1,5 +1,3 @@ -// +build !race - package app import ( diff --git a/app/app_test.go b/app/app_test.go index 370f3e16f..f7d4911ca 100644 --- a/app/app_test.go +++ b/app/app_test.go @@ -1,5 +1,3 @@ -// +build !race - package app import ( diff --git a/app/helpers.go b/app/helpers.go index 905fc40a4..704413098 100644 --- a/app/helpers.go +++ b/app/helpers.go @@ -6,12 +6,12 @@ import ( "path" "path/filepath" "runtime/debug" - "sync" + "time" "github.com/spf13/cobra" "github.com/spf13/viper" - cosmossrv "github.com/cosmos/cosmos-sdk/server" + "github.com/cosmos/cosmos-sdk/baseapp" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/version" @@ -23,9 +23,10 @@ import ( tmflags "github.com/tendermint/tendermint/libs/cli/flags" cmn "github.com/tendermint/tendermint/libs/common" "github.com/tendermint/tendermint/libs/log" - "github.com/tendermint/tmlibs/cli" + "github.com/tendermint/tendermint/snapshot" "github.com/binance-chain/node/app/config" + "github.com/binance-chain/node/common" bnclog "github.com/binance-chain/node/common/log" "github.com/binance-chain/node/common/utils" "github.com/binance-chain/node/plugins/dex/order" @@ -159,56 +160,44 @@ func (app *BinanceChain) processErrAbciResponseForPub(txBytes []byte) { } } -// binance-chain implementation of PruningStrategy -type KeepRecentAndBreatheBlock struct { - breatheBlockInterval int64 - - // Keep recent number blocks in case of rollback - numRecent int64 - - blockStore *blockchain.BlockStore - - blockStoreInitializer sync.Once -} - -func NewKeepRecentAndBreatheBlock(breatheBlockInterval, numRecent int64, config *tmcfg.Config) *KeepRecentAndBreatheBlock { - return &KeepRecentAndBreatheBlock{ - breatheBlockInterval: breatheBlockInterval, - numRecent: numRecent, - } -} - -// TODO: must enhance performance! -func (strategy KeepRecentAndBreatheBlock) ShouldPrune(version, latestVersion int64) bool { - // we are replay the possible 1 block diff between state and blockstore db - // save this block anyway and don't init strategy's blockStore - if cosmossrv.BlockStore == nil { - return false +func (app *BinanceChain) getLastBreatheBlockHeight() int64 { + // we should only sync to breathe block height + latestBlockHeight := app.LastBlockHeight() + var timeOfLatestBlock time.Time + if latestBlockHeight == 0 { + timeOfLatestBlock = utils.Now() + } else { + blockDB := baseapp.LoadBlockDB() + defer blockDB.Close() + blockStore := blockchain.NewBlockStore(blockDB) + block := blockStore.LoadBlock(latestBlockHeight) + timeOfLatestBlock = block.Time } - // only at this time block store is initialized! - // block store has been opened after the start of tendermint node, we have to share same instance of block store - strategy.blockStoreInitializer.Do(func() { - strategy.blockStore = cosmossrv.BlockStore - }) + height := app.DexKeeper.GetLastBreatheBlockHeight( + app.CheckState.Ctx, + latestBlockHeight, + timeOfLatestBlock, + app.baseConfig.BreatheBlockInterval, + app.baseConfig.BreatheBlockDaysCountBack) + app.Logger.Info("get last breathe block height", "height", height) + return height +} - if version == 1 { - return false - } else if latestVersion-version < strategy.numRecent { - return false - } else { - if strategy.breatheBlockInterval > 0 { - return version%strategy.breatheBlockInterval != 0 - } else { - lastBlock := strategy.blockStore.LoadBlock(version - 1) - block := strategy.blockStore.LoadBlock(version) +func (app *BinanceChain) reInitChain() error { + app.DexKeeper.Init( + app.CheckState.Ctx, + app.baseConfig.BreatheBlockInterval, + app.baseConfig.BreatheBlockDaysCountBack, + snapshot.Manager().GetBlockStore(), + snapshot.Manager().GetTxDB(), + app.LastBlockHeight(), + app.TxDecoder) + + // init app cache + stores := app.GetCommitMultiStore() + accountStore := stores.GetKVStore(common.AccountStoreKey) + app.SetAccountStoreCache(app.Codec, accountStore, app.baseConfig.AccountCacheSize) - if lastBlock == nil { - // this node is a state_synced node, previously block is not synced - // so we cannot tell whether this (first) block is breathe block or not - return false - } - return utils.SameDayInUTC(lastBlock.Time, block.Time) - } - } + return nil } diff --git a/app/ordertx_test.go b/app/ordertx_test.go index 7ab383dda..55c8f9f83 100644 --- a/app/ordertx_test.go +++ b/app/ordertx_test.go @@ -1,5 +1,3 @@ -// +build !race - package app import ( diff --git a/app/statesync_helper.go b/app/statesync_helper.go deleted file mode 100644 index f7219afae..000000000 --- a/app/statesync_helper.go +++ /dev/null @@ -1,264 +0,0 @@ -package app - -import ( - "fmt" - "runtime/debug" - "sync" - "time" - - "github.com/cosmos/cosmos-sdk/baseapp" - storePkg "github.com/cosmos/cosmos-sdk/store" - - "github.com/tendermint/iavl" - abci "github.com/tendermint/tendermint/abci/types" - bc "github.com/tendermint/tendermint/blockchain" - cmn "github.com/tendermint/tendermint/libs/common" - dbm "github.com/tendermint/tendermint/libs/db" - - "github.com/binance-chain/node/common" - "github.com/binance-chain/node/common/utils" -) - -type StateSyncManager struct { - enabledStateSyncReactor bool // whether we enabledStateSyncReactor state sync reactor - - stateSyncHeight int64 - stateSyncNumKeys []int64 - stateSyncStoreInfos []storePkg.StoreInfo - - reloadingMtx sync.RWMutex // guard below fields to make sure no concurrent load snapshot and response snapshot, and they should be updated atomically - - stateCachedHeight int64 - numKeysCache []int64 - totalKeyCache int64 // cache sum of numKeysCache - chunkCache [][]byte -} - -// Implement state sync related ABCI interfaces -func (app *BinanceChain) LatestSnapshot() (height int64, numKeys []int64, err error) { - app.reloadingMtx.RLock() - defer app.reloadingMtx.RUnlock() - - return app.stateCachedHeight, app.numKeysCache, nil -} - -func (app *BinanceChain) ReadSnapshotChunk(height int64, startIndex, endIndex int64) (chunk [][]byte, err error) { - app.reloadingMtx.RLock() - defer app.reloadingMtx.RUnlock() - - app.Logger.Info("read snapshot chunk", "height", height, "startIndex", startIndex, "endIndex", endIndex) - if height != app.stateCachedHeight { - return nil, fmt.Errorf("peer requested a stale height we do not have, cacheHeight: %d", app.stateCachedHeight) - } - return app.chunkCache[startIndex:endIndex], nil -} - -func (app *BinanceChain) StartRecovery(height int64, numKeys []int64) error { - app.Logger.Info("start recovery") - app.stateSyncHeight = height - app.stateSyncNumKeys = numKeys - app.stateSyncStoreInfos = make([]storePkg.StoreInfo, 0) - - return nil -} - -func (app *BinanceChain) WriteRecoveryChunk(chunk [][]byte) error { - //store := app.GetCommitMultiStore().GetKVStore(common.StoreKeyNameMap[storeName]) - app.Logger.Info("start write recovery chunk", "totalKeys", len(chunk)) - nodes := make([]*iavl.Node, 0) - for idx := 0; idx < len(chunk); idx++ { - node, _ := iavl.MakeNode(chunk[idx]) - iavl.Hash(node) - nodes = append(nodes, node) - } - - iterated := int64(0) - for storeIdx, storeName := range common.StoreKeyNames { - db := dbm.NewPrefixDB(app.GetDB(), []byte("s/k:"+storeName+"/")) - nodeDB := iavl.NewNodeDB(db, 10000) - - var nodeHash []byte - storeKeys := app.stateSyncNumKeys[storeIdx] - if storeKeys > 0 { - nodeDB.SaveRoot(nodes[iterated], app.stateSyncHeight, true) - nodeHash = iavl.Hash(nodes[iterated]) - for i := int64(0); i < storeKeys; i++ { - node := nodes[iterated+i] - nodeDB.SaveNode(node) - } - } else { - nodeDB.SaveEmptyRoot(app.stateSyncHeight, true) - nodeHash = nil - } - - app.stateSyncStoreInfos = append(app.stateSyncStoreInfos, storePkg.StoreInfo{ - Name: storeName, - Core: storePkg.StoreCore{ - CommitID: storePkg.CommitID{ - Version: app.stateSyncHeight, - Hash: nodeHash, - }, - }, - }) - - app.Logger.Debug("commit store", "store", storeName, "hash", nodeHash) - nodeDB.Commit() - iterated += storeKeys - } - - // start serve other's state sync request - app.reloadingMtx.Lock() - defer app.reloadingMtx.Unlock() - app.stateCachedHeight = app.stateSyncHeight - app.numKeysCache = app.stateSyncNumKeys - app.chunkCache = chunk - - app.Logger.Info("finished write recovery chunk") - return nil -} - -func (app *BinanceChain) EndRecovery(height int64) error { - app.Logger.Info("finished recovery", "height", height) - - // simulate setLatestversion key - batch := app.GetDB().NewBatch() - latestBytes, _ := app.Codec.MarshalBinaryLengthPrefixed(height) // Does not error - batch.Set([]byte("s/latest"), latestBytes) - - ci := storePkg.CommitInfo{ - Version: height, - StoreInfos: app.stateSyncStoreInfos, - } - cInfoBytes, err := app.Codec.MarshalBinaryLengthPrefixed(ci) - if err != nil { - panic(err) - } - cInfoKey := fmt.Sprintf("s/%d", height) - batch.Set([]byte(cInfoKey), cInfoBytes) - batch.WriteSync() - - // load into memory from db - err = app.LoadCMSLatestVersion() - if err != nil { - cmn.Exit(err.Error()) - } - stores := app.GetCommitMultiStore() - commitId := stores.LastCommitID() - hashHex := fmt.Sprintf("%X", commitId.Hash) - app.Logger.Info("commit by state reactor", "version", commitId.Version, "hash", hashHex) - - // simulate we just "Commit()" :P - app.SetCheckState(abci.Header{Height: height}) - app.DeliverState = nil - - // TODO: sync the breathe block on state sync and just call app.DexKeeper.Init() to recover order book and recentPrices to memory - app.resetDexKeeper(height) - - // init app cache - accountStore := stores.GetKVStore(common.AccountStoreKey) - app.SetAccountStoreCache(app.Codec, accountStore, app.baseConfig.AccountCacheSize) - - return nil -} - -func (app BinanceChain) resetDexKeeper(height int64) { - app.DexKeeper.ClearOrders() - - // TODO: figure out how to get block time here to get rid of time.Now() :( - _, err := app.DexKeeper.LoadOrderBookSnapshot(app.CheckState.Ctx, height, time.Now(), app.baseConfig.BreatheBlockInterval, app.baseConfig.BreatheBlockDaysCountBack) - if err != nil { - panic(err) - } - app.DexKeeper.InitRecentPrices(app.CheckState.Ctx) - -} - -func (app *BinanceChain) initStateSyncManager(enabled bool) { - app.enabledStateSyncReactor = enabled - if enabled { - height := app.getLastBreatheBlockHeight() - go app.reloadSnapshot(height, false) - } -} - -// the method might take quite a while (> 5 seconds), BETTER to be called concurrently -// so we only do it once a day after breathe block -// we will refactor it into split chunks into snapshot file soon -func (app *BinanceChain) reloadSnapshot(height int64, retry bool) { - if app.enabledStateSyncReactor { - app.reloadingMtx.Lock() - defer app.reloadingMtx.Unlock() - - app.latestSnapshotImpl(height, retry) - } -} - -func (app *BinanceChain) getLastBreatheBlockHeight() int64 { - // we should only sync to breathe block height - latestBlockHeight := app.LastBlockHeight() - var timeOfLatestBlock time.Time - if latestBlockHeight == 0 { - timeOfLatestBlock = utils.Now() - } else { - blockDB := baseapp.LoadBlockDB() - defer blockDB.Close() - blockStore := bc.NewBlockStore(blockDB) - block := blockStore.LoadBlock(latestBlockHeight) - timeOfLatestBlock = block.Time - } - - height := app.DexKeeper.GetLastBreatheBlockHeight( - app.CheckState.Ctx, - latestBlockHeight, - timeOfLatestBlock, - app.baseConfig.BreatheBlockInterval, - app.baseConfig.BreatheBlockDaysCountBack) - app.Logger.Info("get last breathe block height", "height", height) - return height -} - -func (app *BinanceChain) latestSnapshotImpl(height int64, retry bool) { - defer func() { - if r := recover(); r != nil { - log := fmt.Sprintf("recovered: %v\nstack:\n%v", r, string(debug.Stack())) - app.Logger.Error("failed loading latest snapshot", "err", log) - } - }() - app.Logger.Info("reload latest snapshot", "height", height) - - failed := true - for failed { - failed = false - totalKeys := int64(0) - app.numKeysCache = make([]int64, 0, len(common.StoreKeyNames)) - app.chunkCache = make([][]byte, 0, app.totalKeyCache) // assuming we didn't increase too many account in a day - - for _, key := range common.StoreKeyNames { - var storeKeys int64 - store := app.GetCommitMultiStore().GetKVStore(common.StoreKeyNameMap[key]) - mutableTree := store.(*storePkg.IavlStore).Tree - if tree, err := mutableTree.GetImmutable(height); err == nil { - tree.IterateFirst(func(nodeBytes []byte) { - storeKeys++ - app.chunkCache = append(app.chunkCache, nodeBytes) - }) - } else { - app.Logger.Error("failed to load immutable tree", "err", err) - failed = true - time.Sleep(1 * time.Second) // Endblocker has notified this reload snapshot, - // wait for 1 sec after commit finish - if retry { - break - } else { - return - } - } - totalKeys += storeKeys - app.numKeysCache = append(app.numKeysCache, storeKeys) - } - - app.stateCachedHeight = height - app.totalKeyCache = totalKeys - app.Logger.Info("finish read snapshot chunk", "height", height, "keys", totalKeys) - } -} diff --git a/cmd/bnbchaind/init/snapshot.go b/cmd/bnbchaind/init/snapshot.go new file mode 100644 index 000000000..b8855f248 --- /dev/null +++ b/cmd/bnbchaind/init/snapshot.go @@ -0,0 +1,93 @@ +package init + +import ( + "os" + + "github.com/spf13/cobra" + "github.com/spf13/viper" + + "github.com/tendermint/tendermint/blockchain" + "github.com/tendermint/tendermint/libs/cli" + "github.com/tendermint/tendermint/libs/log" + "github.com/tendermint/tendermint/node" + "github.com/tendermint/tendermint/snapshot" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/server" + "github.com/cosmos/cosmos-sdk/store" + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/binance-chain/node/common" +) + +const ( + flagHeight = "height" +) + +func SnapshotCmd(ctx *server.Context, cdc *codec.Codec) *cobra.Command { + cmd := &cobra.Command{ + Use: "snapshot", + Short: "Take a snapshot for state sync", + RunE: func(_ *cobra.Command, _ []string) error { + logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) + config := ctx.Config + config.SetRoot(viper.GetString(cli.HomeFlag)) + + logger.Info("setup block db") + blockDB, err := node.DefaultDBProvider(&node.DBContext{"blockstore", config}) + if err != nil { + return err + } + + logger.Info("setup state db") + stateDB, err := node.DefaultDBProvider(&node.DBContext{"state", config}) + if err != nil { + return err + } + + logger.Info("setup tx db") + txDB, err := node.DefaultDBProvider(&node.DBContext{"tx_index", config}) + if err != nil { + return err + } + + logger.Info("setup application db") + appDB, err := node.DefaultDBProvider(&node.DBContext{"application", config}) + if err != nil { + return err + } + + logger.Info("build cms") + cms := store.NewCommitMultiStore(appDB) + for _, name := range common.StoreKeyNames { + cms.MountStoreWithDB(common.StoreKeyNameMap[name], sdk.StoreTypeIAVL, nil) + } + cms.MountStoreWithDB(common.TParamsStoreKey, sdk.StoreTypeTransient, nil) + cms.MountStoreWithDB(common.TStakeStoreKey, sdk.StoreTypeTransient, nil) + + logger.Info("load latest version") + if err := cms.LoadLatestVersion(); err != nil { + return err + } + + snapshot.InitSnapshotManager( + stateDB, + txDB, + blockchain.NewBlockStore(blockDB), + config.DBDir(), + logger) + + helper := store.NewStateSyncHelper(logger, appDB, cms, cdc) + + logger.Info("start take snapshot") + helper.ReloadSnapshotRoutine(viper.GetInt64(flagHeight), 0) + + return nil + }, + } + + cmd.Flags().Int64(flagHeight, 0, "specify a syncable height (the height must haven't been pruned") + cmd.MarkFlagRequired(flagHeight) + + return cmd +} diff --git a/cmd/bnbchaind/main.go b/cmd/bnbchaind/main.go index 1df8e55e3..6e22c228b 100644 --- a/cmd/bnbchaind/main.go +++ b/cmd/bnbchaind/main.go @@ -47,6 +47,7 @@ func main() { startCmd := server.StartCmd(ctx.ToCosmosServerCtx(), newApp) startCmd.Flags().Int64VarP(&ctx.PublicationConfig.FromHeightInclusive, "fromHeight", "f", 1, "from which height (inclusive) we want publish market data") rootCmd.AddCommand(startCmd) + rootCmd.AddCommand(bnbInit.SnapshotCmd(ctx.ToCosmosServerCtx(), cdc)) // prepare and add flags executor := cli.PrepareBaseCmd(rootCmd, "BC", app.DefaultNodeHome) diff --git a/networks/publisher/ordergen.sh b/networks/publisher/ordergen.sh index d01711a22..ea9ffb8bc 100755 --- a/networks/publisher/ordergen.sh +++ b/networks/publisher/ordergen.sh @@ -43,10 +43,10 @@ do pause=$(random 5 7) symbolNum=$(random 1 10) - symbol="NNB-3DE_BNB" + symbol="NNB-FCA_BNB" if [ $symbolNum -lt 4 ] then - symbol="NNB-3DE_BNB" + symbol="NNB-FCA_BNB" fi from="zc" diff --git a/networks/publisher/setup.sh b/networks/publisher/setup.sh index aa7834e84..12fe03445 100755 --- a/networks/publisher/setup.sh +++ b/networks/publisher/setup.sh @@ -70,7 +70,7 @@ validator_id=$(echo ${validatorStatus} | grep -o "\"id\":\"[a-zA-Z0-9]*\"" | sed # set witness peer to validator and start witness sed -i -e "s/persistent_peers = \"\"/persistent_peers = \"${validator_id}@127.0.0.1:26656\"/g" ${witnesshome}/config/config.toml -sed -i -e "s/state_sync = false/state_sync = true/g" ${witnesshome}/config/config.toml +sed -i -e "s/state_sync_height = -1/state_sync_height = 0/g" ${witnesshome}/config/config.toml ${executable} start --pruning breathe --home ${witnesshome} > ${witnesshome}/log.txt 2>&1 & witness_pid=$! echo ${witness_pid} diff --git a/plugins/dex/order/keeper.go b/plugins/dex/order/keeper.go index 845526d7a..8108672ae 100644 --- a/plugins/dex/order/keeper.go +++ b/plugins/dex/order/keeper.go @@ -8,6 +8,7 @@ import ( "sync" "time" + bc "github.com/tendermint/tendermint/blockchain" dbm "github.com/tendermint/tendermint/libs/db" tmlog "github.com/tendermint/tendermint/libs/log" @@ -88,8 +89,8 @@ func NewKeeper(key sdk.StoreKey, am auth.AccountKeeper, tradingPairMapper store. } } -func (kp *Keeper) Init(ctx sdk.Context, blockInterval, daysBack int, blockDB dbm.DB, txDB dbm.DB, lastHeight int64, txDecoder sdk.TxDecoder) { - kp.initOrderBook(ctx, blockInterval, daysBack, blockDB, txDB, lastHeight, txDecoder) +func (kp *Keeper) Init(ctx sdk.Context, blockInterval, daysBack int, blockStore *bc.BlockStore, txDB dbm.DB, lastHeight int64, txDecoder sdk.TxDecoder) { + kp.initOrderBook(ctx, blockInterval, daysBack, blockStore, txDB, lastHeight, txDecoder) kp.InitRecentPrices(ctx) } diff --git a/plugins/dex/order/keeper_recovery.go b/plugins/dex/order/keeper_recovery.go index 0d7f51fd5..2fe6dd465 100644 --- a/plugins/dex/order/keeper_recovery.go +++ b/plugins/dex/order/keeper_recovery.go @@ -258,10 +258,7 @@ func (kp *Keeper) ReplayOrdersFromBlock(ctx sdk.Context, bc *bc.BlockStore, txDB return nil } -func (kp *Keeper) initOrderBook(ctx sdk.Context, daysBack int, blockDB dbm.DB, txDB dbm.DB, lastHeight int64, txDecoder sdk.TxDecoder) { - defer blockDB.Close() - defer txDB.Close() - blockStore := bc.NewBlockStore(blockDB) +func (kp *Keeper) initOrderBook(ctx sdk.Context, blockInterval, daysBack int, blockStore *bc.BlockStore, txDB dbm.DB, lastHeight int64, txDecoder sdk.TxDecoder) { var timeOfLatestBlock time.Time if lastHeight == 0 { timeOfLatestBlock = utils.Now() diff --git a/plugins/dex/order/keeper_test.go b/plugins/dex/order/keeper_test.go index 903d72caa..fa79a62fc 100644 --- a/plugins/dex/order/keeper_test.go +++ b/plugins/dex/order/keeper_test.go @@ -459,9 +459,10 @@ func TestKeeper_InitOrderBookDay1(t *testing.T) { keeper.AddEngine(tradingPair) keeper2 := MakeKeeper(cdc) + blockStore := bc.NewBlockStore(memDB) ctx = sdk.NewContext(cms, abci.Header{}, sdk.RunTxModeCheck, logger) keeper2.PairMapper.AddTradingPair(ctx, tradingPair) - keeper2.initOrderBook(ctx, 0, 7, memDB, db.NewMemDB(), 3, auth.DefaultTxDecoder(cdc)) + keeper2.initOrderBook(ctx, 0, 7, blockStore, db.NewMemDB(), 3, auth.DefaultTxDecoder(cdc)) buys, sells := keeper2.engines["XYZ-000_BNB"].Book.GetAllLevels() assert.Equal(2, len(buys)) assert.Equal(1, len(sells))