diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index db226c73d8..f24ca66581 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -961,12 +961,17 @@ var ( DataDirFlag, AncientFlag, RemoteDBFlag, - DBEngineFlag, StateSchemeFlag, HttpHeaderFlag, } ) +func init() { + if rawdb.PebbleEnabled { + DatabaseFlags = append(DatabaseFlags, DBEngineFlag) + } +} + // MakeDataDir retrieves the currently requested data directory, terminating // if none (or the empty string) is specified. If the node is starting a testnet, // then a subdirectory of the specified datadir will be used. diff --git a/core/rawdb/database.go b/core/rawdb/database.go index 1d7b7d1ca8..0c7cf9f11b 100644 --- a/core/rawdb/database.go +++ b/core/rawdb/database.go @@ -30,7 +30,6 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb/leveldb" "github.com/ethereum/go-ethereum/ethdb/memorydb" - "github.com/ethereum/go-ethereum/ethdb/pebble" "github.com/ethereum/go-ethereum/log" "github.com/olekukonko/tablewriter" ) @@ -322,16 +321,6 @@ func NewLevelDBDatabase(file string, cache int, handles int, namespace string, r return NewDatabase(db), nil } -// NewPebbleDBDatabase creates a persistent key-value database without a freezer -// moving immutable chain segments into cold storage. -func NewPebbleDBDatabase(file string, cache int, handles int, namespace string, readonly, ephemeral bool) (ethdb.Database, error) { - db, err := pebble.New(file, cache, handles, namespace, readonly, ephemeral) - if err != nil { - return nil, err - } - return NewDatabase(db), nil -} - const ( dbPebble = "pebble" dbLeveldb = "leveldb" @@ -386,16 +375,26 @@ func openKeyValueDatabase(o OpenOptions) (ethdb.Database, error) { return nil, fmt.Errorf("db.engine choice was %v but found pre-existing %v database in specified data directory", o.Type, existingDb) } if o.Type == dbPebble || existingDb == dbPebble { - log.Info("Using pebble as the backing database") - return NewPebbleDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly, o.Ephemeral) + if PebbleEnabled { + log.Info("Using pebble as the backing database") + return NewPebbleDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly, o.Ephemeral) + } else { + return nil, errors.New("db.engine 'pebble' not supported on this platform") + } } if o.Type == dbLeveldb || existingDb == dbLeveldb { log.Info("Using leveldb as the backing database") return NewLevelDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly) } - // No pre-existing database, no user-requested one either. Default to Pebble. - log.Info("Defaulting to pebble as the backing database") - return NewPebbleDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly, o.Ephemeral) + // No pre-existing database, no user-requested one either. Default to Pebble + // on supported platforms and LevelDB on anything else. + if PebbleEnabled { + log.Info("Defaulting to pebble as the backing database") + return NewPebbleDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly, o.Ephemeral) + } else { + log.Info("Defaulting to leveldb as the backing database") + return NewLevelDBDatabase(o.Directory, o.Cache, o.Handles, o.Namespace, o.ReadOnly) + } } // Open opens both a disk-based key-value database such as leveldb or pebble, but also diff --git a/core/rawdb/databases_64bit.go b/core/rawdb/databases_64bit.go new file mode 100644 index 0000000000..e9f9332ad0 --- /dev/null +++ b/core/rawdb/databases_64bit.go @@ -0,0 +1,37 @@ +// Copyright 2023 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see + +//go:build (arm64 || amd64) && !openbsd + +package rawdb + +import ( + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/ethdb/pebble" +) + +// Pebble is unsupported on 32bit architecture +const PebbleEnabled = true + +// NewPebbleDBDatabase creates a persistent key-value database without a freezer +// moving immutable chain segments into cold storage. +func NewPebbleDBDatabase(file string, cache int, handles int, namespace string, readonly, ephemeral bool) (ethdb.Database, error) { + db, err := pebble.New(file, cache, handles, namespace, readonly, ephemeral) + if err != nil { + return nil, err + } + return NewDatabase(db), nil +} diff --git a/core/rawdb/databases_non64bit.go b/core/rawdb/databases_non64bit.go new file mode 100644 index 0000000000..fb0777a5e6 --- /dev/null +++ b/core/rawdb/databases_non64bit.go @@ -0,0 +1,34 @@ +// Copyright 2023 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +//go:build !((arm64 || amd64) && !openbsd) + +package rawdb + +import ( + "errors" + + "github.com/ethereum/go-ethereum/ethdb" +) + +// Pebble is unsuported on 32bit architecture +const PebbleEnabled = false + +// NewPebbleDBDatabase creates a persistent key-value database without a freezer +// moving immutable chain segments into cold storage. +func NewPebbleDBDatabase(file string, cache int, handles int, namespace string, readonly, ephemeral bool) (ethdb.Database, error) { + return nil, errors.New("pebble is not supported on this platform") +} diff --git a/ethdb/pebble/pebble.go b/ethdb/pebble/pebble.go index 691aa73299..07dcf5933c 100644 --- a/ethdb/pebble/pebble.go +++ b/ethdb/pebble/pebble.go @@ -14,6 +14,8 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . +//go:build (arm64 || amd64) && !openbsd + // Package pebble implements the key-value database layer based on pebble. package pebble @@ -146,15 +148,8 @@ func New(file string, cache int, handles int, namespace string, readonly bool, e // The max memtable size is limited by the uint32 offsets stored in // internal/arenaskl.node, DeferredBatchOp, and flushableBatchEntry. - // - // - MaxUint32 on 64-bit platforms; - // - MaxInt on 32-bit platforms. - // - // It is used when slices are limited to Uint32 on 64-bit platforms (the - // length limit for slices is naturally MaxInt on 32-bit platforms). - // - // Taken from https://github.com/cockroachdb/pebble/blob/master/internal/constants/constants.go - maxMemTableSize := (1<<31)<<(^uint(0)>>63) - 1 + // Taken from https://github.com/cockroachdb/pebble/blob/master/open.go#L38 + maxMemTableSize := 4<<30 - 1 // Capped by 4 GB // Two memory tables is configured which is identical to leveldb, // including a frozen memory table and another live one. diff --git a/ethdb/pebble/pebble_test.go b/ethdb/pebble/pebble_test.go index 1d5611f211..590d5bf035 100644 --- a/ethdb/pebble/pebble_test.go +++ b/ethdb/pebble/pebble_test.go @@ -14,6 +14,8 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . +//go:build (arm64 || amd64) && !openbsd + package pebble import (