github.com/palisadeinc/bor@v0.0.0-20230615125219-ab7196213d15/internal/cli/snapshot.go (about)

     1  // Snapshot related commands
     2  
     3  package cli
     4  
     5  import (
     6  	"strings"
     7  
     8  	"github.com/ethereum/go-ethereum/common"
     9  	"github.com/ethereum/go-ethereum/core/state/pruner"
    10  	"github.com/ethereum/go-ethereum/internal/cli/flagset"
    11  	"github.com/ethereum/go-ethereum/internal/cli/server"
    12  	"github.com/ethereum/go-ethereum/log"
    13  	"github.com/ethereum/go-ethereum/node"
    14  
    15  	"github.com/mitchellh/cli"
    16  )
    17  
    18  // SnapshotCommand is the command to group the snapshot commands
    19  type SnapshotCommand struct {
    20  	UI cli.Ui
    21  }
    22  
    23  // MarkDown implements cli.MarkDown interface
    24  func (a *SnapshotCommand) MarkDown() string {
    25  	items := []string{
    26  		"# snapshot",
    27  		"The ```snapshot``` command groups snapshot related actions:",
    28  		"- [```snapshot prune-state```](./snapshot_prune-state.md): Prune state databases at the given datadir location.",
    29  	}
    30  
    31  	return strings.Join(items, "\n\n")
    32  }
    33  
    34  // Help implements the cli.Command interface
    35  func (c *SnapshotCommand) Help() string {
    36  	return `Usage: bor snapshot <subcommand>
    37  
    38    This command groups snapshot related actions.
    39  
    40    Prune the state trie:
    41  
    42      $ bor snapshot prune-state`
    43  }
    44  
    45  // Synopsis implements the cli.Command interface
    46  func (c *SnapshotCommand) Synopsis() string {
    47  	return "Snapshot related commands"
    48  }
    49  
    50  // Run implements the cli.Command interface
    51  func (c *SnapshotCommand) Run(args []string) int {
    52  	return cli.RunResultHelp
    53  }
    54  
    55  type PruneStateCommand struct {
    56  	*Meta
    57  
    58  	datadirAncient   string
    59  	cache            uint64
    60  	cacheTrie        uint64
    61  	cacheTrieJournal string
    62  	bloomfilterSize  uint64
    63  }
    64  
    65  // MarkDown implements cli.MarkDown interface
    66  func (c *PruneStateCommand) MarkDown() string {
    67  	items := []string{
    68  		"# Prune state",
    69  		"The ```bor snapshot prune-state``` command will prune historical state data with the help of the state snapshot. All trie nodes and contract codes that do not belong to the specified	version state will be deleted from the database. After pruning, only two version states are available: genesis and the specific one.",
    70  		c.Flags().MarkDown(),
    71  	}
    72  
    73  	return strings.Join(items, "\n\n")
    74  }
    75  
    76  // Help implements the cli.Command interface
    77  func (c *PruneStateCommand) Help() string {
    78  	return `Usage: bor snapshot prune-state <datadir>
    79  
    80    This command will prune state databases at the given datadir location` + c.Flags().Help()
    81  }
    82  
    83  // Synopsis implements the cli.Command interface
    84  func (c *PruneStateCommand) Synopsis() string {
    85  	return "Prune state databases"
    86  }
    87  
    88  // Flags: datadir, datadir.ancient, cache.trie.journal, bloomfilter.size
    89  func (c *PruneStateCommand) Flags() *flagset.Flagset {
    90  	flags := c.NewFlagSet("prune-state")
    91  
    92  	flags.StringFlag(&flagset.StringFlag{
    93  		Name:    "datadir.ancient",
    94  		Value:   &c.datadirAncient,
    95  		Usage:   "Path of the ancient data directory to store information",
    96  		Default: "",
    97  	})
    98  
    99  	flags.Uint64Flag(&flagset.Uint64Flag{
   100  		Name:    "cache",
   101  		Usage:   "Megabytes of memory allocated to internal caching",
   102  		Value:   &c.cache,
   103  		Default: 1024.0,
   104  		Group:   "Cache",
   105  	})
   106  
   107  	flags.Uint64Flag(&flagset.Uint64Flag{
   108  		Name:    "cache.trie",
   109  		Usage:   "Percentage of cache memory allowance to use for trie caching",
   110  		Value:   &c.cacheTrie,
   111  		Default: 25,
   112  		Group:   "Cache",
   113  	})
   114  
   115  	flags.StringFlag(&flagset.StringFlag{
   116  		Name:    "cache.trie.journal",
   117  		Value:   &c.cacheTrieJournal,
   118  		Usage:   "Path of the trie journal directory to store information",
   119  		Default: trieCacheJournalPath,
   120  		Group:   "Cache",
   121  	})
   122  
   123  	flags.Uint64Flag(&flagset.Uint64Flag{
   124  		Name:    "bloomfilter.size",
   125  		Value:   &c.bloomfilterSize,
   126  		Usage:   "Size of the bloom filter",
   127  		Default: 2048,
   128  	})
   129  
   130  	return flags
   131  }
   132  
   133  // Run implements the cli.Command interface
   134  func (c *PruneStateCommand) Run(args []string) int {
   135  	flags := c.Flags()
   136  
   137  	if err := flags.Parse(args); err != nil {
   138  		c.UI.Error(err.Error())
   139  		return 1
   140  	}
   141  
   142  	datadir := c.dataDir
   143  	if datadir == "" {
   144  		c.UI.Error("datadir is required")
   145  		return 1
   146  	}
   147  
   148  	// Create the node
   149  	node, err := node.New(&node.Config{
   150  		DataDir: datadir,
   151  	})
   152  
   153  	if err != nil {
   154  		c.UI.Error(err.Error())
   155  		return 1
   156  	}
   157  
   158  	dbHandles, err := server.MakeDatabaseHandles(0)
   159  	if err != nil {
   160  		c.UI.Error(err.Error())
   161  		return 1
   162  	}
   163  
   164  	chaindb, err := node.OpenDatabaseWithFreezer(chaindataPath, int(c.cache), dbHandles, c.datadirAncient, "", false)
   165  
   166  	if err != nil {
   167  		c.UI.Error(err.Error())
   168  		return 1
   169  	}
   170  
   171  	pruner, err := pruner.NewPruner(chaindb, node.ResolvePath(""), node.ResolvePath(c.cacheTrieJournal), c.bloomfilterSize)
   172  	if err != nil {
   173  		log.Error("Failed to open snapshot tree", "err", err)
   174  		return 1
   175  	}
   176  
   177  	if err = pruner.Prune(common.Hash{}); err != nil {
   178  		log.Error("Failed to prune state", "err", err)
   179  		return 1
   180  	}
   181  
   182  	return 0
   183  }