package commands import ( "context" "fmt" "os" "os/signal" "syscall" "github.com/c2h5oh/datasize" "github.com/ledgerwatch/turbo-geth/cmd/utils" "github.com/ledgerwatch/turbo-geth/ethdb" "github.com/ledgerwatch/turbo-geth/internal/debug" "github.com/ledgerwatch/turbo-geth/log" "github.com/spf13/cobra" ) var ( filesDir string // Directory when the files should be stored sentryAddr string // Address of the sentry : coreAddr string // Address of the core : chaindata string // Path to chaindata database string // Type of database (lmdb or mdbx) mapSizeStr string // Map size for LMDB freelistReuse int ) func init() { utils.CobraFlags(rootCmd, append(debug.Flags, utils.MetricFlags...)) } func rootContext() context.Context { ctx, cancel := context.WithCancel(context.Background()) go func() { ch := make(chan os.Signal, 1) signal.Notify(ch, os.Interrupt, syscall.SIGTERM) defer signal.Stop(ch) select { case <-ch: log.Info("Got interrupt, shutting down...") case <-ctx.Done(): } cancel() }() return ctx } var rootCmd = &cobra.Command{ Use: "headers", Short: "headers is Proof Of Concept for new header/block downloading algorithms", PersistentPreRun: func(cmd *cobra.Command, args []string) { if err := debug.SetupCobra(cmd); err != nil { panic(err) } }, PersistentPostRun: func(cmd *cobra.Command, args []string) { debug.Exit() }, } func Execute() { if err := rootCmd.ExecuteContext(rootContext()); err != nil { fmt.Println(err) os.Exit(1) } } func must(err error) { if err != nil { panic(err) } } func withChaindata(cmd *cobra.Command) { cmd.Flags().StringVar(&chaindata, "chaindata", "", "path to the db") must(cmd.MarkFlagDirname("chaindata")) must(cmd.MarkFlagRequired("chaindata")) cmd.Flags().StringVar(&database, "database", "", "lmdb|mdbx") } func withLmdbFlags(cmd *cobra.Command) { cmd.Flags().StringVar(&mapSizeStr, "lmdb.mapSize", "", "map size for LMDB") cmd.Flags().IntVar(&freelistReuse, "maxFreelistReuse", 0, "Find a big enough contiguous page range for large values in freelist is hard just allocate new pages and even don't try to search if value is bigger than this limit. Measured in pages.") } func openDatabase(path string) *ethdb.ObjectDatabase { db := ethdb.NewObjectDatabase(openKV(path, false)) return db } func openKV(path string, exclusive bool) ethdb.KV { if database == "mdbx" { opts := ethdb.NewMDBX().Path(path) if exclusive { opts = opts.Exclusive() } if mapSizeStr != "" { var mapSize datasize.ByteSize must(mapSize.UnmarshalText([]byte(mapSizeStr))) opts = opts.MapSize(mapSize) } if freelistReuse > 0 { opts = opts.MaxFreelistReuse(uint(freelistReuse)) } return opts.MustOpen() } opts := ethdb.NewLMDB().Path(path) if exclusive { opts = opts.Exclusive() } if mapSizeStr != "" { var mapSize datasize.ByteSize must(mapSize.UnmarshalText([]byte(mapSizeStr))) opts = opts.MapSize(mapSize) } if freelistReuse > 0 { opts = opts.MaxFreelistReuse(uint(freelistReuse)) } return opts.MustOpen() }