Skip to content

Commit

Permalink
Enable ancient block pruning (#1216)
Browse files Browse the repository at this point in the history
* core/state: typo

Signed-off-by: Delweng <delweng@gmail.com>

* core/rawdb: backport from bnb-chain/bsc#543

Signed-off-by: Delweng <delweng@gmail.com>

* eth,ethdb,node,core/state: backport from bnb-chain/bsc#543

Signed-off-by: Delweng <delweng@gmail.com>

* eth,core: backport from bnb-chain/bsc#543

Signed-off-by: Delweng <delweng@gmail.com>

* cmd: open db with freeze disabled

Signed-off-by: Delweng <delweng@gmail.com>

* cli: snapshot prune-block

Signed-off-by: Delweng <delweng@gmail.com>

* fix typo

Signed-off-by: Delweng <delweng@gmail.com>

* cli/snapshot: fix the issue of dup open db error

Signed-off-by: Delweng <delweng@gmail.com>

* cli/snapshot: resolve datadir and ancient before backup

Signed-off-by: Delweng <delweng@gmail.com>

* core: more prune-block log

Signed-off-by: Delweng <delweng@gmail.com>

* core: truncatetail missing f.offset

Signed-off-by: Delweng <delweng@gmail.com>

* core/rawdb: indextx adjust offset of pruned block

Signed-off-by: Delweng <delweng@gmail.com>

* core/rawdb: freezer batch should implement the offset commit, ref bnb-chain/bsc#1005

Signed-off-by: Delweng <delweng@gmail.com>

* core: check of ancientdb, backport bnb-chain/bsc#817

Signed-off-by: Delweng <delweng@gmail.com>

* core/state: read raw borReceipt to backup

Signed-off-by: Delweng <delweng@gmail.com>

* core/rawdb: bor receipt maybe in []Receipt or Receipt RLP format

Signed-off-by: Delweng <delweng@gmail.com>

* core/state: typo and error msg

Signed-off-by: Delweng <delweng@gmail.com>

* core/rawdb: offSet -> offset

Signed-off-by: Delweng <delweng@gmail.com>

* cli/snapshot: comment

Signed-off-by: Delweng <delweng@gmail.com>

* cli/snapshot: add prune-block doc

Signed-off-by: Delweng <delweng@gmail.com>

* docs: add prune-block document

Signed-off-by: Delweng <delweng@gmail.com>

* core/rawdb: print wrong bor-receipt length

Signed-off-by: Delweng <delweng@gmail.com>

* internal/cli: add snapshot prune block tests (referenced from bsc's PR)

* improve errors

* cmd, core, eth, internal: fix lint

* internal/cli: refactor snapshot prune block test

* fix linters in tests

* internal/cli: add inspect-ancient-db command, update docs

* pruner: use a generic function for simplification

* internal/cli: fixes for inspect-db command

* internal/cli: improve pruning tests

* core/rawdb: update end block calculation logic in inspect command

* core/rawdb: improve checks db initialisation

* core/rawdb: remove offset check

* update mocks for span, ethdb and add command in makefile

* docs/cli: update docs with inspect command

* go mod tidy

* refactor and resolve conflicts

* resolve more conflicts

* refactor

* explicitly read node for hash scheme

* add check for hash scheme, fix tests

* fix typo

* update docs and add warning

* raise error if pbss is enabled

* revert read raw bor receipt change

* consensus/bor: handle nil header case in get root hash

* address comments

* core/rawdb: check chain continuity by matching parent hash

* core/rawdb: account for pruned ancient blocks

* go mod tidy

* fix tests

* fix tests

---------

Signed-off-by: Delweng <delweng@gmail.com>
Co-authored-by: Delweng <delweng@gmail.com>
  • Loading branch information
manav2401 and jsvisa authored May 9, 2024
1 parent 902c1ce commit d95c05b
Show file tree
Hide file tree
Showing 50 changed files with 1,461 additions and 144 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ protoc:

generate-mocks:
go generate mockgen -destination=./tests/bor/mocks/IHeimdallClient.go -package=mocks ./consensus/bor IHeimdallClient
go generate mockgen -destination=./eth/filters/IDatabase.go -package=filters ./ethdb Database
go generate mockgen -destination=./eth/filters/IBackend.go -package=filters ./eth/filters Backend
go generate mockgen -destination=../eth/filters/IDatabase.go -package=filters ./ethdb Database

Expand Down
7 changes: 3 additions & 4 deletions cmd/geth/chaincmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ func initGenesis(ctx *cli.Context) error {
overrides.OverrideVerkle = new(big.Int).SetInt64(v)
}
for _, name := range []string{"chaindata", "lightchaindata"} {
chaindb, err := stack.OpenDatabaseWithFreezer(name, 0, 0, ctx.String(utils.AncientFlag.Name), "", false)
chaindb, err := stack.OpenDatabaseWithFreezer(name, 0, 0, ctx.String(utils.AncientFlag.Name), "", false, false, false)
if err != nil {
utils.Fatalf("Failed to open database: %v", err)
}
Expand Down Expand Up @@ -413,7 +413,7 @@ func importPreimages(ctx *cli.Context) error {
stack, _ := makeConfigNode(ctx)
defer stack.Close()

db := utils.MakeChainDatabase(ctx, stack, false)
db := utils.MakeChainDatabase(ctx, stack, false, false)
defer db.Close()
start := time.Now()

Expand All @@ -427,9 +427,8 @@ func importPreimages(ctx *cli.Context) error {
}

func parseDumpConfig(ctx *cli.Context, stack *node.Node) (*state.DumpConfig, ethdb.Database, common.Hash, error) {
db := utils.MakeChainDatabase(ctx, stack, true)
db := utils.MakeChainDatabase(ctx, stack, true, false)
defer db.Close()

var header *types.Header

if ctx.NArg() > 1 {
Expand Down
25 changes: 11 additions & 14 deletions cmd/geth/dbcmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ func inspect(ctx *cli.Context) error {
stack, _ := makeConfigNode(ctx)
defer stack.Close()

db := utils.MakeChainDatabase(ctx, stack, true)
db := utils.MakeChainDatabase(ctx, stack, true, false)
defer db.Close()

return rawdb.InspectDatabase(db, prefix, start)
Expand All @@ -317,7 +317,7 @@ func checkStateContent(ctx *cli.Context) error {
stack, _ := makeConfigNode(ctx)
defer stack.Close()

db := utils.MakeChainDatabase(ctx, stack, true)
db := utils.MakeChainDatabase(ctx, stack, true, false)
defer db.Close()

var (
Expand Down Expand Up @@ -381,7 +381,7 @@ func dbStats(ctx *cli.Context) error {
stack, _ := makeConfigNode(ctx)
defer stack.Close()

db := utils.MakeChainDatabase(ctx, stack, true)
db := utils.MakeChainDatabase(ctx, stack, true, false)
defer db.Close()

showLeveldbStats(db)
Expand All @@ -393,7 +393,7 @@ func dbCompact(ctx *cli.Context) error {
stack, _ := makeConfigNode(ctx)
defer stack.Close()

db := utils.MakeChainDatabase(ctx, stack, false)
db := utils.MakeChainDatabase(ctx, stack, false, false)
defer db.Close()

log.Info("Stats before compaction")
Expand Down Expand Up @@ -421,7 +421,7 @@ func dbGet(ctx *cli.Context) error {
stack, _ := makeConfigNode(ctx)
defer stack.Close()

db := utils.MakeChainDatabase(ctx, stack, true)
db := utils.MakeChainDatabase(ctx, stack, true, false)
defer db.Close()

key, err := common.ParseHexOrString(ctx.Args().Get(0))
Expand Down Expand Up @@ -450,7 +450,7 @@ func dbDelete(ctx *cli.Context) error {
stack, _ := makeConfigNode(ctx)
defer stack.Close()

db := utils.MakeChainDatabase(ctx, stack, false)
db := utils.MakeChainDatabase(ctx, stack, false, false)
defer db.Close()

key, err := common.ParseHexOrString(ctx.Args().Get(0))
Expand Down Expand Up @@ -481,7 +481,7 @@ func dbPut(ctx *cli.Context) error {
stack, _ := makeConfigNode(ctx)
defer stack.Close()

db := utils.MakeChainDatabase(ctx, stack, false)
db := utils.MakeChainDatabase(ctx, stack, false, false)
defer db.Close()

var (
Expand Down Expand Up @@ -520,7 +520,7 @@ func dbDumpTrie(ctx *cli.Context) error {
stack, _ := makeConfigNode(ctx)
defer stack.Close()

db := utils.MakeChainDatabase(ctx, stack, true)
db := utils.MakeChainDatabase(ctx, stack, true, false)
defer db.Close()

triedb := utils.MakeTrieDatabase(ctx, db, false, true, false)
Expand Down Expand Up @@ -658,7 +658,7 @@ func importLDBdata(ctx *cli.Context) error {
close(stop)
}()

db := utils.MakeChainDatabase(ctx, stack, false)
db := utils.MakeChainDatabase(ctx, stack, false, false)
defer db.Close()
return utils.ImportLDBData(db, fName, int64(start), stop)
}
Expand Down Expand Up @@ -767,17 +767,15 @@ func exportChaindata(ctx *cli.Context) error {
close(stop)
}()

db := utils.MakeChainDatabase(ctx, stack, true)
db := utils.MakeChainDatabase(ctx, stack, true, false)
defer db.Close()
return utils.ExportChaindata(ctx.Args().Get(1), kind, exporter(db), stop)
}

func showMetaData(ctx *cli.Context) error {
stack, _ := makeConfigNode(ctx)
defer stack.Close()
db := utils.MakeChainDatabase(ctx, stack, true)
defer db.Close()

db := utils.MakeChainDatabase(ctx, stack, true, false)
ancients, err := db.Ancients()
if err != nil {
fmt.Fprintf(os.Stderr, "Error accessing ancients: %v", err)
Expand All @@ -803,6 +801,5 @@ func showMetaData(ctx *cli.Context) error {
table.SetHeader([]string{"Field", "Value"})
table.AppendBulk(data)
table.Render()

return nil
}
15 changes: 7 additions & 8 deletions cmd/geth/snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ func pruneState(ctx *cli.Context) error {
stack, _ := makeConfigNode(ctx)
defer stack.Close()

chaindb := utils.MakeChainDatabase(ctx, stack, false)
chaindb := utils.MakeChainDatabase(ctx, stack, false, false)
defer chaindb.Close()

if rawdb.ReadStateScheme(chaindb) != rawdb.HashScheme {
Expand Down Expand Up @@ -215,9 +215,8 @@ func verifyState(ctx *cli.Context) error {
stack, _ := makeConfigNode(ctx)
defer stack.Close()

chaindb := utils.MakeChainDatabase(ctx, stack, true)
chaindb := utils.MakeChainDatabase(ctx, stack, true, false)
defer chaindb.Close()

headBlock := rawdb.ReadHeadBlock(chaindb)
if headBlock == nil {
log.Error("Failed to load head block")
Expand Down Expand Up @@ -268,7 +267,7 @@ func checkDanglingStorage(ctx *cli.Context) error {
stack, _ := makeConfigNode(ctx)
defer stack.Close()

db := utils.MakeChainDatabase(ctx, stack, true)
db := utils.MakeChainDatabase(ctx, stack, true, false)
defer db.Close()
return snapshot.CheckDanglingStorage(db)
}
Expand All @@ -280,7 +279,7 @@ func traverseState(ctx *cli.Context) error {
stack, _ := makeConfigNode(ctx)
defer stack.Close()

chaindb := utils.MakeChainDatabase(ctx, stack, true)
chaindb := utils.MakeChainDatabase(ctx, stack, true, false)
defer chaindb.Close()

triedb := utils.MakeTrieDatabase(ctx, chaindb, false, true, false)
Expand Down Expand Up @@ -404,7 +403,7 @@ func traverseRawState(ctx *cli.Context) error {
stack, _ := makeConfigNode(ctx)
defer stack.Close()

chaindb := utils.MakeChainDatabase(ctx, stack, true)
chaindb := utils.MakeChainDatabase(ctx, stack, true, false)
defer chaindb.Close()

triedb := utils.MakeTrieDatabase(ctx, chaindb, false, true, false)
Expand Down Expand Up @@ -684,7 +683,7 @@ func snapshotExportPreimages(ctx *cli.Context) error {
stack, _ := makeConfigNode(ctx)
defer stack.Close()

chaindb := utils.MakeChainDatabase(ctx, stack, true)
chaindb := utils.MakeChainDatabase(ctx, stack, true, false)
defer chaindb.Close()

triedb := utils.MakeTrieDatabase(ctx, chaindb, false, true, false)
Expand Down Expand Up @@ -743,7 +742,7 @@ func checkAccount(ctx *cli.Context) error {
stack, _ := makeConfigNode(ctx)
defer stack.Close()

chaindb := utils.MakeChainDatabase(ctx, stack, true)
chaindb := utils.MakeChainDatabase(ctx, stack, true, false)
defer chaindb.Close()

start := time.Now()
Expand Down
4 changes: 2 additions & 2 deletions cmd/geth/verkle.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func verifyVerkle(ctx *cli.Context) error {
stack, _ := makeConfigNode(ctx)
defer stack.Close()

chaindb := utils.MakeChainDatabase(ctx, stack, true)
chaindb := utils.MakeChainDatabase(ctx, stack, true, false)
defer chaindb.Close()
headBlock := rawdb.ReadHeadBlock(chaindb)

Expand Down Expand Up @@ -172,7 +172,7 @@ func expandVerkle(ctx *cli.Context) error {
stack, _ := makeConfigNode(ctx)
defer stack.Close()

chaindb := utils.MakeChainDatabase(ctx, stack, true)
chaindb := utils.MakeChainDatabase(ctx, stack, true, false)
defer chaindb.Close()
var (
rootC common.Hash
Expand Down
10 changes: 5 additions & 5 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -2112,8 +2112,8 @@ func SplitTagsFlag(tagsFlag string) map[string]string {
return tagsMap
}

// MakeChainDatabase opens a database using the flags passed to the client and will hard crash if it fails.
func MakeChainDatabase(ctx *cli.Context, stack *node.Node, readonly bool) ethdb.Database {
// MakeChainDatabase opens a LevelDB using the flags passed to the client and will hard crash if it fails.
func MakeChainDatabase(ctx *cli.Context, stack *node.Node, readonly, disableFreeze bool) ethdb.Database {
var (
cache = ctx.Int(CacheFlag.Name) * ctx.Int(CacheDatabaseFlag.Name) / 100
handles = MakeDatabaseHandles(ctx.Int(FDLimitFlag.Name))
Expand All @@ -2134,7 +2134,7 @@ func MakeChainDatabase(ctx *cli.Context, stack *node.Node, readonly bool) ethdb.
case ctx.String(SyncModeFlag.Name) == "light":
chainDb, err = stack.OpenDatabase("lightchaindata", cache, handles, "", readonly)
default:
chainDb, err = stack.OpenDatabaseWithFreezer("chaindata", cache, handles, ctx.String(AncientFlag.Name), "", readonly)
chainDb, err = stack.OpenDatabaseWithFreezer("chaindata", cache, handles, ctx.String(AncientFlag.Name), "", readonly, disableFreeze, false)
}

if err != nil {
Expand All @@ -2153,7 +2153,7 @@ func tryMakeReadOnlyDatabase(ctx *cli.Context, stack *node.Node) ethdb.Database
if rawdb.PreexistingDatabase(stack.ResolvePath("chaindata")) == "" {
readonly = false
}
return MakeChainDatabase(ctx, stack, readonly)
return MakeChainDatabase(ctx, stack, readonly, false)
}

func IsNetworkPreset(ctx *cli.Context) bool {
Expand Down Expand Up @@ -2218,7 +2218,7 @@ func MakeGenesis(ctx *cli.Context) *core.Genesis {
func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockChain, ethdb.Database) {
var (
gspec = MakeGenesis(ctx)
chainDb = MakeChainDatabase(ctx, stack, readonly)
chainDb = MakeChainDatabase(ctx, stack, readonly, false)
)

config, err := core.LoadChainConfig(chainDb, gspec)
Expand Down
4 changes: 4 additions & 0 deletions consensus/bor/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,10 @@ func (api *API) GetRootHash(start uint64, end uint64) (string, error) {

for i := 0; i < len(blockHeaders); i++ {
blockHeader := blockHeaders[i]
// Handle no header case, which is possible if ancient pruning was done
if blockHeader == nil {
return "", errUnknownBlock
}
header := crypto.Keccak256(appendBytes32(
blockHeader.Number.Bytes(),
new(big.Int).SetUint64(blockHeader.Time).Bytes(),
Expand Down
7 changes: 6 additions & 1 deletion core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,12 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis
}
}
// Ensure that a previous crash in SetHead doesn't leave extra ancients
if frozen, err := bc.db.Ancients(); err == nil && frozen > 0 {
//nolint:nestif
if frozen, err := bc.db.ItemAmountInAncient(); err == nil && frozen > 0 {
frozen, err = bc.db.Ancients()
if err != nil {
return nil, err
}
var (
needRewind bool
low uint64
Expand Down
8 changes: 8 additions & 0 deletions core/blockchain_repair_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1768,6 +1768,8 @@ func testRepairWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme s
Directory: datadir,
AncientsDirectory: ancient,
Ephemeral: true,
IsLastOffset: false,
DisableFreeze: false,
})
if err != nil {
t.Fatalf("Failed to create persistent database: %v", err)
Expand Down Expand Up @@ -1849,6 +1851,8 @@ func testRepairWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme s
Directory: datadir,
AncientsDirectory: ancient,
Ephemeral: true,
IsLastOffset: false,
DisableFreeze: false,
})
if err != nil {
t.Fatalf("Failed to reopen persistent database: %v", err)
Expand Down Expand Up @@ -1913,6 +1917,8 @@ func testIssue23496(t *testing.T, scheme string) {
db, err := rawdb.Open(rawdb.OpenOptions{
Directory: datadir,
AncientsDirectory: ancient,
IsLastOffset: false,
DisableFreeze: false,
})
if err != nil {
t.Fatalf("Failed to create persistent database: %v", err)
Expand Down Expand Up @@ -1971,6 +1977,8 @@ func testIssue23496(t *testing.T, scheme string) {
Directory: datadir,
AncientsDirectory: ancient,
Ephemeral: true,
IsLastOffset: false,
DisableFreeze: false,
})
if err != nil {
t.Fatalf("Failed to reopen persistent database: %v", err)
Expand Down
2 changes: 2 additions & 0 deletions core/blockchain_sethead_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1972,6 +1972,8 @@ func testSetHeadWithScheme(t *testing.T, tt *rewindTest, snapshots bool, scheme
Directory: datadir,
AncientsDirectory: ancient,
Ephemeral: true,
IsLastOffset: false,
DisableFreeze: false,
})
if err != nil {
t.Fatalf("Failed to create persistent database: %v", err)
Expand Down
4 changes: 4 additions & 0 deletions core/blockchain_snapshot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ func (basic *snapshotTestBasic) prepare(t *testing.T) (*BlockChain, []*types.Blo
Directory: datadir,
AncientsDirectory: ancient,
Ephemeral: true,
IsLastOffset: false,
DisableFreeze: false,
})
if err != nil {
t.Fatalf("Failed to create persistent database: %v", err)
Expand Down Expand Up @@ -262,6 +264,8 @@ func (snaptest *crashSnapshotTest) test(t *testing.T) {
Directory: snaptest.datadir,
AncientsDirectory: snaptest.ancient,
Ephemeral: true,
IsLastOffset: false,
DisableFreeze: false,
})
if err != nil {
t.Fatalf("Failed to reopen persistent database: %v", err)
Expand Down
Loading

0 comments on commit d95c05b

Please sign in to comment.