Skip to content

Commit

Permalink
feat: improve code quality and add concurrency
Browse files Browse the repository at this point in the history
  • Loading branch information
AaronCQL committed Oct 10, 2023
1 parent dd621dc commit 1683cc3
Show file tree
Hide file tree
Showing 8 changed files with 409 additions and 343 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
data
bin
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
build:
go build -o ./bin/cosmos-gc ./cmd/cosmos-gc/main.go

install:
go install ./cmd/cosmos-gc
45 changes: 29 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,41 @@
# Cosmos Garbage Collector

## Running
CLI tool to *really* prune a Cosmos SDK full node.

## Assumptions

- Target chain is running Cosmos SDK version v0.46 or v0.47 (does NOT work on v0.45)
- Full node uses LevelDB (support for other DBs can be added if need be)

## Installing

Using Go:

```bash
go run main.go PATH_TO_APP_HOME # eg. ~/.terra
go install github.com/coinhall/cosmos-gc/cmd/cosmos-gc
```

## Notes
OR, from source:

```bash
# Data held in our 10TB archival full node:
du -sh ./*
5.6T ./application.db
813G ./blockstore.db
1022M ./cs.wal
104K ./evidence.db
4.0K ./priv_validator_state.json
3.0G ./snapshots
1.5T ./state.db
3.3T ./tx_index.db
4.0K ./upgrade-info.json
git clone https://github.com/coinhall/cosmos-gc
cd cosmos-gc
make install
```

## Running

Make sure to stop the full node first (if it is running). Then, run the following command:

```bash
cosmos-gc PATH_TO_APP_HOME # eg. ~/.terra
```

You may proceed to start the full node after the above command has finished.

## Implementation Notes

- A new db is created to replace the old db as opposed to pruning the old db as deletions are extremely slow
- Latest block height must be read from each database (ie. cannot read from one db and assume it's the same for all)
- `state.db` must contain `validatorsKey` for last valset changed height, latest height, latest height + 1, and latest height + 2; else, starting the daemon will result in consensus failure
- `application.db` holds the AVL tree for Cosmos SDK, iteration itself is already very expensive (worse still for reads and writes)
- Tested (and working) for chains using Cosmos SDK versions 0.46 and 0.47
- `application.db` holds the IAVL tree for Cosmos SDK, iteration itself is already very expensive (worse still for reads and writes)
56 changes: 56 additions & 0 deletions cmd/cosmos-gc/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package main

import (
"fmt"
"os"
"path/filepath"
"sync"

"github.com/coinhall/cosmos-gc/pkg/pruner"
)

func main() {
if len(os.Args) != 2 {
fmt.Printf("Usage: cosmos-gc <app_home>\n")
os.Exit(1)
}
appHome := os.Args[1]
dataDir := filepath.Join(appHome, "data")
fmt.Printf("Using app data dir at [%v]\n", dataDir)

wg := sync.WaitGroup{}
wg.Add(3)

go func() {
defer wg.Done()
fmt.Println("[blockstore] starting to prune...")
if err := pruner.PruneBlockstoreDB(dataDir); err != nil {
fmt.Printf("[blockstore] pruning failed: %v\n", err)
return
}
fmt.Println("[blockstore] pruned successfully!")
}()

go func() {
defer wg.Done()
fmt.Println("[state] starting to prune...")
if err := pruner.PruneStateDB(dataDir); err != nil {
fmt.Printf("[state] pruning failed: %v\n", err)
return
}
fmt.Println("[state] pruned successfully!")
}()

go func() {
defer wg.Done()
fmt.Println("[application] starting to prune...")
fmt.Println("[application] WARNING: THIS IS KNOWN TO TAKE A VERY LONG TIME!")
if err := pruner.PruneApplicationDB(dataDir); err != nil {
fmt.Printf("[application] pruning failed: %v\n", err)
return
}
fmt.Println("[application] pruned successfully!")
}()

wg.Wait()
}
Loading

0 comments on commit 1683cc3

Please sign in to comment.