Skip to content

Commit b7ed9de

Browse files
committed
Add state pruning to new CLI
1 parent 660677b commit b7ed9de

File tree

11 files changed

+237
-9
lines changed

11 files changed

+237
-9
lines changed

docs/cli/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@
4444

4545
- [```server```](./server.md)
4646

47+
- [```snapshot```](./snapshot.md)
48+
49+
- [```snapshot prune-state```](./snapshot_prune-state.md)
50+
4751
- [```status```](./status.md)
4852

4953
- [```version```](./version.md)

docs/cli/account_import.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ The ```account import``` command imports an account in Json format to the Bor da
66

77
- ```datadir```: Path of the data directory to store information
88

9-
- ```keystore```: Path of the data directory to store information
9+
- ```keystore```: Path of the data directory to store keys

docs/cli/account_list.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ The `account list` command lists all the accounts in the Bor data directory.
66

77
- ```datadir```: Path of the data directory to store information
88

9-
- ```keystore```: Path of the data directory to store information
9+
- ```keystore```: Path of the data directory to store keys

docs/cli/account_new.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ The `account new` command creates a new local account file on the Bor data direc
66

77
- ```datadir```: Path of the data directory to store information
88

9-
- ```keystore```: Path of the data directory to store information
9+
- ```keystore```: Path of the data directory to store keys

docs/cli/server.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ The ```bor server``` command runs the Bor client.
3232

3333
- ```bor.withoutheimdall```: Run without Heimdall service (for testing purpose) (default: false)
3434

35+
- ```bor.heimdallgRPC```: Address of Heimdall gRPC service
36+
3537
- ```ethstats```: Reporting URL of a ethstats service (nodename:secret@host:port)
3638

3739
- ```gpo.blocks```: Number of recent blocks to check for gas prices (default: 20)
@@ -80,6 +82,8 @@ The ```bor server``` command runs the Bor client.
8082

8183
- ```cache.preimages```: Enable recording the SHA3/keccak preimages of trie keys (default: false)
8284

85+
- ```cache.triesinmemory```: Number of block states (tries) to keep in memory (default = 128) (default: 128)
86+
8387
- ```txlookuplimit```: Number of recent blocks to maintain transactions index for (default: 2350000)
8488

8589
### JsonRPC Options

docs/cli/snapshot.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# snapshot
2+
3+
The ```snapshot``` command groups snapshot related actions:
4+
5+
- [```snapshot prune-state```](./snapshot_prune-state.md): Joins the local client to another remote peer.

docs/cli/snapshot_prune-state.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Prune state
2+
3+
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.
4+
5+
## Options
6+
7+
- ```datadir```: Path of the data directory to store information
8+
9+
- ```keystore```: Path of the data directory to store keys
10+
11+
- ```datadir.ancient```: Path of the ancient data directory to store information
12+
13+
- ```bloomfilter.size```: Size of the bloom filter (default: 2048)
14+
15+
### Cache Options
16+
17+
- ```cache```: Megabytes of memory allocated to internal caching (default: 1024)
18+
19+
- ```cache.trie```: Percentage of cache memory allowance to use for trie caching (default: 25)
20+
21+
- ```cache.trie.journal```: Path of the trie journal directory to store information (default: triecache)

internal/cli/command.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,16 @@ func Commands() map[string]MarkDownCommandFactory {
189189
Meta2: meta2,
190190
}, nil
191191
},
192+
"snapshot": func() (MarkDownCommand, error) {
193+
return &SnapshotCommand{
194+
UI: ui,
195+
}, nil
196+
},
197+
"snapshot prune-state": func() (MarkDownCommand, error) {
198+
return &PruneStateCommand{
199+
Meta: meta,
200+
}, nil
201+
},
192202
}
193203
}
194204

@@ -248,7 +258,7 @@ func (m *Meta) NewFlagSet(n string) *flagset.Flagset {
248258
f.StringFlag(&flagset.StringFlag{
249259
Name: "keystore",
250260
Value: &m.keyStoreDir,
251-
Usage: "Path of the data directory to store information",
261+
Usage: "Path of the data directory to store keys",
252262
})
253263

254264
return f

internal/cli/removedb.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,10 @@ type RemoveDBCommand struct {
2424
}
2525

2626
const (
27-
chaindataPath string = "chaindata"
28-
ancientPath string = "ancient"
29-
lightchaindataPath string = "lightchaindata"
27+
chaindataPath string = "chaindata"
28+
ancientPath string = "ancient"
29+
trieCacheJournalPath string = "triecache"
30+
lightchaindataPath string = "lightchaindata"
3031
)
3132

3233
// MarkDown implements cli.MarkDown interface

internal/cli/server/config.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -686,7 +686,7 @@ func (c *Config) loadChain() error {
686686

687687
//nolint:gocognit
688688
func (c *Config) buildEth(stack *node.Node, accountManager *accounts.Manager) (*ethconfig.Config, error) {
689-
dbHandles, err := makeDatabaseHandles()
689+
dbHandles, err := MakeDatabaseHandles()
690690
if err != nil {
691691
return nil, err
692692
}
@@ -1075,7 +1075,7 @@ func (c *Config) Merge(cc ...*Config) error {
10751075
return nil
10761076
}
10771077

1078-
func makeDatabaseHandles() (int, error) {
1078+
func MakeDatabaseHandles() (int, error) {
10791079
limit, err := fdlimit.Maximum()
10801080
if err != nil {
10811081
return -1, err

internal/cli/snapshot.go

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
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): Joins the local client to another remote peer.",
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()
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+
}

0 commit comments

Comments
 (0)