Merge pull request #1673 from cfromknecht/prevent-db-reversions
channeldb: fail Open on db reversion
This commit is contained in:
commit
8379bbaa9b
@ -663,12 +663,24 @@ func (d *DB) syncVersions(versions []version) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the current database version matches the latest version number,
|
|
||||||
// then we don't need to perform any migrations.
|
|
||||||
latestVersion := getLatestDBVersion(versions)
|
latestVersion := getLatestDBVersion(versions)
|
||||||
log.Infof("Checking for schema update: latest_version=%v, "+
|
log.Infof("Checking for schema update: latest_version=%v, "+
|
||||||
"db_version=%v", latestVersion, meta.DbVersionNumber)
|
"db_version=%v", latestVersion, meta.DbVersionNumber)
|
||||||
if meta.DbVersionNumber == latestVersion {
|
|
||||||
|
switch {
|
||||||
|
|
||||||
|
// If the database reports a higher version that we are aware of, the
|
||||||
|
// user is probably trying to revert to a prior version of lnd. We fail
|
||||||
|
// here to prevent reversions and unintended corruption.
|
||||||
|
case meta.DbVersionNumber > latestVersion:
|
||||||
|
log.Errorf("Refusing to revert from db_version=%d to "+
|
||||||
|
"lower version=%d", meta.DbVersionNumber,
|
||||||
|
latestVersion)
|
||||||
|
return ErrDBReversion
|
||||||
|
|
||||||
|
// If the current database version matches the latest version number,
|
||||||
|
// then we don't need to perform any migrations.
|
||||||
|
case meta.DbVersionNumber == latestVersion:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,10 @@ var (
|
|||||||
// created.
|
// created.
|
||||||
ErrNoChanDBExists = fmt.Errorf("channel db has not yet been created")
|
ErrNoChanDBExists = fmt.Errorf("channel db has not yet been created")
|
||||||
|
|
||||||
|
// ErrDBReversion is returned when detecting an attempt to revert to a
|
||||||
|
// prior database version.
|
||||||
|
ErrDBReversion = fmt.Errorf("channel db cannot revert to prior version")
|
||||||
|
|
||||||
// ErrLinkNodesNotFound is returned when node info bucket hasn't been
|
// ErrLinkNodesNotFound is returned when node info bucket hasn't been
|
||||||
// created.
|
// created.
|
||||||
ErrLinkNodesNotFound = fmt.Errorf("no link nodes exist")
|
ErrLinkNodesNotFound = fmt.Errorf("no link nodes exist")
|
||||||
|
@ -2,6 +2,7 @@ package channeldb
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"io/ioutil"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/coreos/bbolt"
|
"github.com/coreos/bbolt"
|
||||||
@ -380,3 +381,43 @@ func TestMigrationWithoutErrors(t *testing.T) {
|
|||||||
migrationWithoutErrors,
|
migrationWithoutErrors,
|
||||||
false)
|
false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestMigrationReversion tests after performing a migration to a higher
|
||||||
|
// database version, opening the database with a lower latest db version returns
|
||||||
|
// ErrDBReversion.
|
||||||
|
func TestMigrationReversion(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tempDirName, err := ioutil.TempDir("", "channeldb")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to create temp dir: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cdb, err := Open(tempDirName)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to open channeldb: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the database metadata to point to one more than the highest
|
||||||
|
// known version.
|
||||||
|
err = cdb.Update(func(tx *bolt.Tx) error {
|
||||||
|
newMeta := &Meta{
|
||||||
|
DbVersionNumber: getLatestDBVersion(dbVersions) + 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
return putMeta(newMeta, tx)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Close the database. Even if we succeeded, our next step is to reopen.
|
||||||
|
cdb.Close()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unable to increase db version: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = Open(tempDirName)
|
||||||
|
if err != ErrDBReversion {
|
||||||
|
t.Fatalf("unexpected error when opening channeldb, "+
|
||||||
|
"want: %v, got: %v", ErrDBReversion, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user