You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
2.6 KiB
96 lines
2.6 KiB
package wtdb |
|
|
|
import ( |
|
"encoding/binary" |
|
"errors" |
|
"os" |
|
"path/filepath" |
|
|
|
"github.com/lightningnetwork/lnd/channeldb/kvdb" |
|
) |
|
|
|
const ( |
|
// dbFilePermission requests read+write access to the db file. |
|
dbFilePermission = 0600 |
|
) |
|
|
|
var ( |
|
// metadataBkt stores all the meta information concerning the state of |
|
// the database. |
|
metadataBkt = []byte("metadata-bucket") |
|
|
|
// dbVersionKey is a static key used to retrieve the database version |
|
// number from the metadataBkt. |
|
dbVersionKey = []byte("version") |
|
|
|
// ErrUninitializedDB signals that top-level buckets for the database |
|
// have not been initialized. |
|
ErrUninitializedDB = errors.New("db not initialized") |
|
|
|
// ErrNoDBVersion signals that the database contains no version info. |
|
ErrNoDBVersion = errors.New("db has no version") |
|
|
|
// byteOrder is the default endianness used when serializing integers. |
|
byteOrder = binary.BigEndian |
|
) |
|
|
|
// fileExists returns true if the file exists, and false otherwise. |
|
func fileExists(path string) bool { |
|
if _, err := os.Stat(path); err != nil { |
|
if os.IsNotExist(err) { |
|
return false |
|
} |
|
} |
|
|
|
return true |
|
} |
|
|
|
// createDBIfNotExist opens the boltdb database at dbPath/name, creating one if |
|
// one doesn't exist. The boolean returned indicates if the database did not |
|
// exist before, or if it has been created but no version metadata exists within |
|
// it. |
|
func createDBIfNotExist(dbPath, name string) (kvdb.Backend, bool, error) { |
|
path := filepath.Join(dbPath, name) |
|
|
|
// If the database file doesn't exist, this indicates we much initialize |
|
// a fresh database with the latest version. |
|
firstInit := !fileExists(path) |
|
if firstInit { |
|
// Ensure all parent directories are initialized. |
|
err := os.MkdirAll(dbPath, 0700) |
|
if err != nil { |
|
return nil, false, err |
|
} |
|
} |
|
|
|
// Specify bbolt freelist options to reduce heap pressure in case the |
|
// freelist grows to be very large. |
|
bdb, err := kvdb.Create(kvdb.BoltBackendName, path, true) |
|
if err != nil { |
|
return nil, false, err |
|
} |
|
|
|
// If the file existed previously, we'll now check to see that the |
|
// metadata bucket is properly initialized. It could be the case that |
|
// the database was created, but we failed to actually populate any |
|
// metadata. If the metadata bucket does not actually exist, we'll |
|
// set firstInit to true so that we can treat is initialize the bucket. |
|
if !firstInit { |
|
var metadataExists bool |
|
err = kvdb.View(bdb, func(tx kvdb.RTx) error { |
|
metadataExists = tx.ReadBucket(metadataBkt) != nil |
|
return nil |
|
}, func() { |
|
metadataExists = false |
|
}) |
|
if err != nil { |
|
return nil, false, err |
|
} |
|
|
|
if !metadataExists { |
|
firstInit = true |
|
} |
|
} |
|
|
|
return bdb, firstInit, nil |
|
}
|
|
|