code.vegaprotocol.io/vega@v0.79.0/cmd/vegatools/snapshot.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package tools 17 18 import ( 19 "encoding/json" 20 "errors" 21 "fmt" 22 23 "code.vegaprotocol.io/vega/core/config" 24 "code.vegaprotocol.io/vega/paths" 25 "code.vegaprotocol.io/vega/vegatools/snapshotdb" 26 27 tmconfig "github.com/cometbft/cometbft/config" 28 "github.com/cometbft/cometbft/store" 29 "github.com/spf13/viper" 30 ) 31 32 type snapshotCmd struct { 33 config.OutputFlag 34 DBPath string `description:"path to snapshot state data" long:"db-path" short:"d"` 35 SnapshotContentsPath string `description:"path to file where to write the content of a snapshot" long:"snapshot-contents" short:"c"` 36 BlockHeight uint64 `description:"block-height of requested snapshot" long:"block-height" short:"b"` 37 SetProtocolUpgrade bool `description:"set protocol-upgrade flag to true in the latest snapshot" long:"set-pup" short:"p"` 38 TendermintHome string `description:"tendermint home directory, if set will print the last processed block height" long:"tendermint-home"` 39 } 40 41 func getLastProcessedBlock(homeDir string) (int64, error) { 42 conf := tmconfig.DefaultConfig() 43 if err := viper.Unmarshal(conf); err != nil { 44 return 0, err 45 } 46 conf.SetRoot(homeDir) 47 48 // lets get the last processed block from tendermint 49 blockStoreDB, err := tmconfig.DefaultDBProvider(&tmconfig.DBContext{ID: "blockstore", Config: conf}) 50 if err != nil { 51 return 0, err 52 } 53 blockStore := store.NewBlockStore(blockStoreDB) 54 return blockStore.Height(), nil 55 } 56 57 func (opts *snapshotCmd) Execute(_ []string) error { 58 if opts.SnapshotContentsPath != "" && opts.BlockHeight == 0 { 59 return errors.New("must specify --block-height when using --write-payload") 60 } 61 62 db := opts.DBPath 63 if opts.DBPath == "" { 64 vegaPaths := paths.New(rootCmd.VegaHome) 65 db = vegaPaths.StatePathFor(paths.SnapshotStateHome) 66 } 67 68 if opts.SetProtocolUpgrade { 69 err := snapshotdb.SetProtocolUpgrade(paths.New(rootCmd.VegaHome)) 70 return err 71 } 72 73 if opts.SnapshotContentsPath != "" { 74 fmt.Printf("finding payloads for block-height %d...\n", opts.BlockHeight) 75 err := snapshotdb.SavePayloadsToFile(db, opts.SnapshotContentsPath, opts.BlockHeight) 76 if err != nil { 77 return err 78 } 79 fmt.Printf("payloads saved to '%s'\n", opts.SnapshotContentsPath) 80 return nil 81 } 82 83 snapshots, invalid, err := snapshotdb.SnapshotData(db, opts.BlockHeight) 84 if err != nil { 85 return err 86 } 87 88 var lastProcessedBlock int64 89 if opts.TendermintHome != "" { 90 if lastProcessedBlock, err = getLastProcessedBlock(opts.TendermintHome); err != nil { 91 return err 92 } 93 } 94 95 if opts.Output.IsJSON() { 96 o := struct { 97 Snapshots []snapshotdb.Data `json:"snapshots"` 98 Invalid []snapshotdb.Data `json:"invalidSnapshots,omitempty"` 99 LastProcessedBlock int64 `json:"lastProcessedBlock,omitempty"` 100 }{ 101 Snapshots: snapshots, 102 Invalid: invalid, 103 LastProcessedBlock: lastProcessedBlock, 104 } 105 b, err := json.Marshal(o) 106 if err != nil { 107 return err 108 } 109 fmt.Println(string(b)) 110 return nil 111 } 112 113 if lastProcessedBlock != 0 { 114 fmt.Printf("\nLast processed block: %d\n", lastProcessedBlock) 115 } 116 117 fmt.Println("\nSnapshots available:", len(snapshots)) 118 for _, snap := range snapshots { 119 fmt.Printf("\tHeight: %d, Version: %d, Size %d, Hash: %s\n", snap.Height, snap.Version, snap.Size, snap.Hash) 120 } 121 122 if len(invalid) == 0 { 123 return nil 124 } 125 fmt.Println("Invalid snapshots:", len(invalid)) 126 for _, snap := range invalid { 127 fmt.Printf("\tVersion: %d, Size %d, Hash: %s\n", snap.Version, snap.Size, snap.Hash) 128 } 129 130 return nil 131 }