Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Storage Refactor] Init pebble DB in scaffold. #6949

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion cmd/node_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"time"

"github.com/cockroachdb/pebble"
"github.com/dgraph-io/badger/v2"
madns "github.com/multiformats/go-multiaddr-dns"
"github.com/onflow/crypto"
Expand Down Expand Up @@ -151,6 +152,7 @@ type BaseConfig struct {
DynamicStartupEpoch string
DynamicStartupSleepInterval time.Duration
datadir string
pebbleDir string
secretsdir string
secretsDBEnabled bool
InsecureSecretsDB bool
Expand All @@ -164,7 +166,6 @@ type BaseConfig struct {
MetricsEnabled bool
guaranteesCacheSize uint
receiptsCacheSize uint
db *badger.DB
HeroCacheMetricsEnable bool
SyncCoreConfig chainsync.Config
CodecFactory func() network.Codec
Expand Down Expand Up @@ -198,6 +199,7 @@ type NodeConfig struct {
MetricsRegisterer prometheus.Registerer
Metrics Metrics
DB *badger.DB
PebbleDB *pebble.DB
SecretsDB *badger.DB
Storage Storage
ProtocolEvents *events.Distributor
Expand Down Expand Up @@ -253,6 +255,7 @@ type StateExcerptAtBoot struct {

func DefaultBaseConfig() *BaseConfig {
datadir := "/data/protocol"
pebbleDir := "/data/protocol-pebble"

// NOTE: if the codec used in the network component is ever changed any code relying on
// the message format specific to the codec must be updated. i.e: the AuthorizedSenderValidator.
Expand All @@ -269,6 +272,7 @@ func DefaultBaseConfig() *BaseConfig {
ObserverMode: false,
BootstrapDir: "bootstrap",
datadir: datadir,
pebbleDir: pebbleDir,
secretsdir: NotSet,
secretsDBEnabled: true,
level: "info",
Expand Down
39 changes: 20 additions & 19 deletions cmd/scaffold.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/onflow/flow-go/admin/commands/common"
storageCommands "github.com/onflow/flow-go/admin/commands/storage"
"github.com/onflow/flow-go/cmd/build"
"github.com/onflow/flow-go/cmd/scaffold"
"github.com/onflow/flow-go/config"
"github.com/onflow/flow-go/consensus/hotstuff/persister"
"github.com/onflow/flow-go/fvm/initialize"
Expand Down Expand Up @@ -164,6 +165,7 @@ func (fnb *FlowNodeBuilder) BaseFlags() {
fnb.flags.StringVar(&fnb.BaseConfig.BindAddr, "bind", defaultConfig.BindAddr, "address to bind on")
fnb.flags.StringVarP(&fnb.BaseConfig.BootstrapDir, "bootstrapdir", "b", defaultConfig.BootstrapDir, "path to the bootstrap directory")
fnb.flags.StringVarP(&fnb.BaseConfig.datadir, "datadir", "d", defaultConfig.datadir, "directory to store the public database (protocol state)")
fnb.flags.StringVar(&fnb.BaseConfig.pebbleDir, "pebble-dir", defaultConfig.pebbleDir, "directory to store the public pebble database (protocol state)")
fnb.flags.StringVar(&fnb.BaseConfig.secretsdir, "secretsdir", defaultConfig.secretsdir, "directory to store private database (secrets)")
fnb.flags.StringVarP(&fnb.BaseConfig.level, "loglevel", "l", defaultConfig.level, "level for logging output")
fnb.flags.Uint32Var(&fnb.BaseConfig.debugLogLimit, "debug-log-limit", defaultConfig.debugLogLimit, "max number of debug/trace log events per second")
Expand Down Expand Up @@ -1056,13 +1058,7 @@ func (fnb *FlowNodeBuilder) initProfiler() error {
return nil
}

func (fnb *FlowNodeBuilder) initDB() error {

// if a db has been passed in, use that instead of creating one
if fnb.BaseConfig.db != nil {
fnb.DB = fnb.BaseConfig.db
return nil
}
func (fnb *FlowNodeBuilder) initBadgerDB() error {

// Pre-create DB path (Badger creates only one-level dirs)
err := os.MkdirAll(fnb.BaseConfig.datadir, 0700)
Expand Down Expand Up @@ -1110,6 +1106,17 @@ func (fnb *FlowNodeBuilder) initDB() error {
return nil
}

func (fnb *FlowNodeBuilder) initPebbleDB() error {
db, closer, err := scaffold.InitPebbleDB(fnb.BaseConfig.pebbleDir)
if err != nil {
return err
}

fnb.PebbleDB = db
fnb.ShutdownFunc(closer.Close)
return nil
}

func (fnb *FlowNodeBuilder) initSecretsDB() error {

// if the secrets DB is disabled (only applicable for Consensus Follower,
Expand Down Expand Up @@ -1889,9 +1896,7 @@ func WithBindAddress(bindAddress string) Option {

func WithDataDir(dataDir string) Option {
return func(config *BaseConfig) {
if config.db == nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this was used for the consensus follower

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why we need both WithDB and WithDataDir. I think we should keep only one, no?

config.datadir = dataDir
}
config.datadir = dataDir
}
}

Expand Down Expand Up @@ -1925,14 +1930,6 @@ func WithLogLevel(level string) Option {
}
}

// WithDB takes precedence over WithDataDir and datadir will be set to empty if DB is set using this option
func WithDB(db *badger.DB) Option {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not being used anywhere

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this was added to support the consensus follower

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you explain it a bit more? I can't find anywhere using it.

I deleted it, and tested localnet, it ran fine.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you use a consensus follower as a library, you may want to use the same database for the blocks/etc and you app. so there's an option to provide your own db instead of the scaffold always creating one

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. We need to discuss this, because it creates extra complexity, as we are transitioning to pebble DB.

return func(config *BaseConfig) {
config.db = db
config.datadir = ""
}
}

// FlowNode creates a new Flow node builder with the given name.
func FlowNode(role string, opts ...Option) *FlowNodeBuilder {
config := DefaultBaseConfig()
Expand Down Expand Up @@ -2038,7 +2035,11 @@ func (fnb *FlowNodeBuilder) onStart() error {
return err
}

if err := fnb.initDB(); err != nil {
if err := fnb.initBadgerDB(); err != nil {
return err
}

if err := fnb.initPebbleDB(); err != nil {
return err
}

Expand Down
26 changes: 26 additions & 0 deletions cmd/scaffold/pebble_db.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package scaffold

import (
"fmt"
"io"
"os"

"github.com/cockroachdb/pebble"

pebblestorage "github.com/onflow/flow-go/storage/pebble"
)

func InitPebbleDB(dir string) (*pebble.DB, io.Closer, error) {
// Pre-create DB path
err := os.MkdirAll(dir, 0700)
if err != nil {
return nil, nil, fmt.Errorf("could not create pebble db (path: %s): %w", dir, err)
}

db, err := pebblestorage.OpenDefaultPebbleDB(dir)
if err != nil {
return nil, nil, err
}

return db, db, nil
}
17 changes: 17 additions & 0 deletions cmd/scaffold/pebble_db_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package scaffold

import (
"testing"

"github.com/stretchr/testify/require"

"github.com/onflow/flow-go/utils/unittest"
)

func TestInitPebbleDB(t *testing.T) {
unittest.RunWithTempDir(t, func(dir string) {
_, closer, err := InitPebbleDB(dir)
require.NoError(t, err)
require.NoError(t, closer.Close())
})
}
12 changes: 0 additions & 12 deletions follower/consensus_follower.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,6 @@ func WithLogLevel(level string) Option {
}
}

// WithDB sets the underlying database that will be used to store the chain state
// WithDB takes precedence over WithDataDir and datadir will be set to empty if DB is set using this option
func WithDB(db *badger.DB) Option {
return func(cf *Config) {
cf.db = db
cf.dataDir = ""
}
}

func WithExposeMetrics(expose bool) Option {
return func(c *Config) {
c.exposeMetrics = expose
Expand Down Expand Up @@ -142,9 +133,6 @@ func getBaseOptions(config *Config) []cmd.Option {
if config.logLevel != "" {
options = append(options, cmd.WithLogLevel(config.logLevel))
}
if config.db != nil {
options = append(options, cmd.WithDB(config.db))
}
if config.exposeMetrics {
options = append(options, cmd.WithMetricsEnabled(config.exposeMetrics))
}
Expand Down
2 changes: 2 additions & 0 deletions storage/pebble/open.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ func MustOpenDefaultPebbleDB(dir string) (*pebble.DB, error) {
}

// IsPebbleInitialized checks if the given folder contains a valid Pebble DB.
// return error if the folder does not exist, is not a directory, or is missing required files
// return nil if the folder contains a valid Pebble DB
func IsPebbleInitialized(folderPath string) error {
// Check if the folder exists
info, err := os.Stat(folderPath)
Expand Down
Loading