@@ -12,6 +12,7 @@ import (
12
12
"time"
13
13
14
14
gcemd "cloud.google.com/go/compute/metadata"
15
+ "github.com/cockroachdb/pebble"
15
16
"github.com/dgraph-io/badger/v2"
16
17
"github.com/hashicorp/go-multierror"
17
18
dht "github.com/libp2p/go-libp2p-kad-dht"
@@ -20,6 +21,7 @@ import (
20
21
"github.com/libp2p/go-libp2p/core/routing"
21
22
"github.com/prometheus/client_golang/prometheus"
22
23
"github.com/rs/zerolog"
24
+ "github.com/rs/zerolog/log"
23
25
"github.com/spf13/pflag"
24
26
"golang.org/x/time/rate"
25
27
"google.golang.org/api/option"
@@ -31,6 +33,7 @@ import (
31
33
"github.com/onflow/flow-go/admin/commands/common"
32
34
storageCommands "github.com/onflow/flow-go/admin/commands/storage"
33
35
"github.com/onflow/flow-go/cmd/build"
36
+ "github.com/onflow/flow-go/cmd/scaffold"
34
37
"github.com/onflow/flow-go/config"
35
38
"github.com/onflow/flow-go/consensus/hotstuff/persister"
36
39
"github.com/onflow/flow-go/fvm/initialize"
@@ -164,6 +167,7 @@ func (fnb *FlowNodeBuilder) BaseFlags() {
164
167
fnb .flags .StringVar (& fnb .BaseConfig .BindAddr , "bind" , defaultConfig .BindAddr , "address to bind on" )
165
168
fnb .flags .StringVarP (& fnb .BaseConfig .BootstrapDir , "bootstrapdir" , "b" , defaultConfig .BootstrapDir , "path to the bootstrap directory" )
166
169
fnb .flags .StringVarP (& fnb .BaseConfig .datadir , "datadir" , "d" , defaultConfig .datadir , "directory to store the public database (protocol state)" )
170
+ fnb .flags .StringVar (& fnb .BaseConfig .pebbleDir , "pebble-dir" , defaultConfig .pebbleDir , "directory to store the public pebble database (protocol state)" )
167
171
fnb .flags .StringVar (& fnb .BaseConfig .secretsdir , "secretsdir" , defaultConfig .secretsdir , "directory to store private database (secrets)" )
168
172
fnb .flags .StringVarP (& fnb .BaseConfig .level , "loglevel" , "l" , defaultConfig .level , "level for logging output" )
169
173
fnb .flags .Uint32Var (& fnb .BaseConfig .debugLogLimit , "debug-log-limit" , defaultConfig .debugLogLimit , "max number of debug/trace log events per second" )
@@ -1057,14 +1061,22 @@ func (fnb *FlowNodeBuilder) initProfiler() error {
1057
1061
return nil
1058
1062
}
1059
1063
1060
- func (fnb * FlowNodeBuilder ) initDB () error {
1061
-
1062
- // if a db has been passed in, use that instead of creating one
1063
- if fnb .BaseConfig .db != nil {
1064
- fnb .DB = fnb .BaseConfig .db
1064
+ func (fnb * FlowNodeBuilder ) initBadgerDB () error {
1065
+ // if the badger DB is already set, use it.
1066
+ // the badger DB might be set by the follower engine
1067
+ if fnb .BaseConfig .badgerDB != nil {
1068
+ fnb .DB = fnb .BaseConfig .badgerDB
1065
1069
return nil
1066
1070
}
1067
1071
1072
+ // if the badger DB is not set, then the datadir must be provided to initialize
1073
+ // the badger DB
1074
+ // since we've set an default directory for the badger DB, this check
1075
+ // is not necessary, but rather a sanity check
1076
+ if fnb .BaseConfig .datadir == NotSet {
1077
+ return fmt .Errorf ("missing required flag '--datadir'" )
1078
+ }
1079
+
1068
1080
// Pre-create DB path (Badger creates only one-level dirs)
1069
1081
err := os .MkdirAll (fnb .BaseConfig .datadir , 0700 )
1070
1082
if err != nil {
@@ -1111,6 +1123,24 @@ func (fnb *FlowNodeBuilder) initDB() error {
1111
1123
return nil
1112
1124
}
1113
1125
1126
+ func (fnb * FlowNodeBuilder ) initPebbleDB () error {
1127
+ // if the pebble DB is already set, use it
1128
+ // the pebble DB might be set by the follower engine
1129
+ if fnb .BaseConfig .pebbleDB != nil {
1130
+ fnb .PebbleDB = fnb .BaseConfig .pebbleDB
1131
+ return nil
1132
+ }
1133
+
1134
+ db , closer , err := scaffold .InitPebbleDB (fnb .BaseConfig .pebbleDir )
1135
+ if err != nil {
1136
+ return err
1137
+ }
1138
+
1139
+ fnb .PebbleDB = db
1140
+ fnb .ShutdownFunc (closer .Close )
1141
+ return nil
1142
+ }
1143
+
1114
1144
func (fnb * FlowNodeBuilder ) initSecretsDB () error {
1115
1145
1116
1146
// if the secrets DB is disabled (only applicable for Consensus Follower,
@@ -1888,11 +1918,55 @@ func WithBindAddress(bindAddress string) Option {
1888
1918
}
1889
1919
}
1890
1920
1921
+ // WithDataDir set the data directory for the badger database
1922
+ // It will be ignored if WithBadgerDB is used
1891
1923
func WithDataDir (dataDir string ) Option {
1892
1924
return func (config * BaseConfig ) {
1893
- if config .db == nil {
1894
- config .datadir = dataDir
1925
+ if config .badgerDB != nil {
1926
+ log .Warn ().Msgf ("ignoring data directory %s as badger database is already set" , dataDir )
1927
+ return
1928
+ }
1929
+
1930
+ config .datadir = dataDir
1931
+ }
1932
+ }
1933
+
1934
+ // WithBadgerDB sets the badger database instance
1935
+ // If used, then WithDataDir method will be ignored
1936
+ func WithBadgerDB (db * badger.DB ) Option {
1937
+ return func (config * BaseConfig ) {
1938
+ if config .datadir != "" && config .datadir != NotSet {
1939
+ log .Warn ().Msgf ("ignoring data directory is already set for badger %v" , config .datadir )
1940
+ config .datadir = ""
1895
1941
}
1942
+
1943
+ config .badgerDB = db
1944
+ }
1945
+ }
1946
+
1947
+ // WithPebbleDir set the data directory for the pebble database
1948
+ // It will be ignored if WithPebbleDB is used
1949
+ func WithPebbleDir (dataDir string ) Option {
1950
+ return func (config * BaseConfig ) {
1951
+ if config .pebbleDB != nil {
1952
+ log .Warn ().Msgf ("ignoring data directory %s as pebble database is already set" , dataDir )
1953
+ return
1954
+ }
1955
+
1956
+ config .pebbleDir = dataDir
1957
+ }
1958
+ }
1959
+
1960
+ // WithPebbleDB sets the pebble database instance
1961
+ // If used, then WithPebbleDir method will be ignored
1962
+ func WithPebbleDB (db * pebble.DB ) Option {
1963
+ return func (config * BaseConfig ) {
1964
+ if config .pebbleDir != "" && config .pebbleDir != NotSet {
1965
+ log .Warn ().Msgf ("ignoring data directory is already set for pebble %v" , config .pebbleDir )
1966
+ config .pebbleDir = ""
1967
+ }
1968
+
1969
+ config .pebbleDB = db
1896
1970
}
1897
1971
}
1898
1972
@@ -1926,14 +2000,6 @@ func WithLogLevel(level string) Option {
1926
2000
}
1927
2001
}
1928
2002
1929
- // WithDB takes precedence over WithDataDir and datadir will be set to empty if DB is set using this option
1930
- func WithDB (db * badger.DB ) Option {
1931
- return func (config * BaseConfig ) {
1932
- config .db = db
1933
- config .datadir = ""
1934
- }
1935
- }
1936
-
1937
2003
// FlowNode creates a new Flow node builder with the given name.
1938
2004
func FlowNode (role string , opts ... Option ) * FlowNodeBuilder {
1939
2005
config := DefaultBaseConfig ()
@@ -2039,7 +2105,13 @@ func (fnb *FlowNodeBuilder) onStart() error {
2039
2105
return err
2040
2106
}
2041
2107
2042
- if err := fnb .initDB (); err != nil {
2108
+ // we always initialize both badger and pebble databases
2109
+ // even if we only use one of them, this simplify the code and checks
2110
+ if err := fnb .initBadgerDB (); err != nil {
2111
+ return err
2112
+ }
2113
+
2114
+ if err := fnb .initPebbleDB (); err != nil {
2043
2115
return err
2044
2116
}
2045
2117
0 commit comments