mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-03-04 09:48:19 +01:00
192 lines
4.6 KiB
Go
192 lines
4.6 KiB
Go
|
package migration7
|
||
|
|
||
|
import (
|
||
|
"testing"
|
||
|
|
||
|
"github.com/lightningnetwork/lnd/channeldb/migtest"
|
||
|
"github.com/lightningnetwork/lnd/kvdb"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
// preDetails is the expected data of the channel details bucket before
|
||
|
// the migration.
|
||
|
preDetails = map[string]interface{}{
|
||
|
channelIDString(100): map[string]interface{}{
|
||
|
string(cChannelSummary): string([]byte{1, 2, 3}),
|
||
|
},
|
||
|
channelIDString(222): map[string]interface{}{
|
||
|
string(cChannelSummary): string([]byte{4, 5, 6}),
|
||
|
},
|
||
|
}
|
||
|
|
||
|
// preFailCorruptDB should fail the migration due to no channel summary
|
||
|
// being found for a given channel ID.
|
||
|
preFailCorruptDB = map[string]interface{}{
|
||
|
channelIDString(30): map[string]interface{}{},
|
||
|
}
|
||
|
|
||
|
// channelIDIndex is the data in the channelID index that is used to
|
||
|
// find the mapping between the db-assigned channel ID and the real
|
||
|
// channel ID.
|
||
|
channelIDIndex = map[string]interface{}{
|
||
|
uint64ToStr(10): channelIDString(100),
|
||
|
uint64ToStr(20): channelIDString(222),
|
||
|
}
|
||
|
|
||
|
// sessions is the expected data in the sessions bucket before and
|
||
|
// after the migration.
|
||
|
sessions = map[string]interface{}{
|
||
|
sessionIDString("1"): map[string]interface{}{
|
||
|
string(cSessionAckRangeIndex): map[string]interface{}{
|
||
|
uint64ToStr(10): map[string]interface{}{
|
||
|
uint64ToStr(30): uint64ToStr(32),
|
||
|
uint64ToStr(34): uint64ToStr(34),
|
||
|
},
|
||
|
uint64ToStr(20): map[string]interface{}{
|
||
|
uint64ToStr(30): uint64ToStr(30),
|
||
|
},
|
||
|
},
|
||
|
string(cSessionDBID): uint64ToStr(66),
|
||
|
},
|
||
|
sessionIDString("2"): map[string]interface{}{
|
||
|
string(cSessionAckRangeIndex): map[string]interface{}{
|
||
|
uint64ToStr(10): map[string]interface{}{
|
||
|
uint64ToStr(33): uint64ToStr(33),
|
||
|
},
|
||
|
},
|
||
|
string(cSessionDBID): uint64ToStr(77),
|
||
|
},
|
||
|
}
|
||
|
|
||
|
// postDetails is the expected data in the channel details bucket after
|
||
|
// the migration.
|
||
|
postDetails = map[string]interface{}{
|
||
|
channelIDString(100): map[string]interface{}{
|
||
|
string(cChannelSummary): string([]byte{1, 2, 3}),
|
||
|
string(cChanSessions): map[string]interface{}{
|
||
|
uint64ToStr(66): string([]byte{1}),
|
||
|
uint64ToStr(77): string([]byte{1}),
|
||
|
},
|
||
|
},
|
||
|
channelIDString(222): map[string]interface{}{
|
||
|
string(cChannelSummary): string([]byte{4, 5, 6}),
|
||
|
string(cChanSessions): map[string]interface{}{
|
||
|
uint64ToStr(66): string([]byte{1}),
|
||
|
},
|
||
|
},
|
||
|
}
|
||
|
)
|
||
|
|
||
|
// TestMigrateChannelToSessionIndex tests that the MigrateChannelToSessionIndex
|
||
|
// function correctly builds the new channel-to-sessionID index to the tower
|
||
|
// client DB.
|
||
|
func TestMigrateChannelToSessionIndex(t *testing.T) {
|
||
|
t.Parallel()
|
||
|
|
||
|
tests := []struct {
|
||
|
name string
|
||
|
shouldFail bool
|
||
|
preDetails map[string]interface{}
|
||
|
preSessions map[string]interface{}
|
||
|
preChanIndex map[string]interface{}
|
||
|
postDetails map[string]interface{}
|
||
|
}{
|
||
|
{
|
||
|
name: "migration ok",
|
||
|
shouldFail: false,
|
||
|
preDetails: preDetails,
|
||
|
preSessions: sessions,
|
||
|
preChanIndex: channelIDIndex,
|
||
|
postDetails: postDetails,
|
||
|
},
|
||
|
{
|
||
|
name: "fail due to corrupt db",
|
||
|
shouldFail: true,
|
||
|
preDetails: preFailCorruptDB,
|
||
|
preSessions: sessions,
|
||
|
},
|
||
|
{
|
||
|
name: "no sessions",
|
||
|
shouldFail: false,
|
||
|
},
|
||
|
}
|
||
|
|
||
|
for _, test := range tests {
|
||
|
test := test
|
||
|
|
||
|
t.Run(test.name, func(t *testing.T) {
|
||
|
t.Parallel()
|
||
|
|
||
|
// Before the migration we have a channel details
|
||
|
// bucket, a sessions bucket, a session ID index bucket
|
||
|
// and a channel ID index bucket.
|
||
|
before := func(tx kvdb.RwTx) error {
|
||
|
err := migtest.RestoreDB(
|
||
|
tx, cChanDetailsBkt, test.preDetails,
|
||
|
)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
err = migtest.RestoreDB(
|
||
|
tx, cSessionBkt, test.preSessions,
|
||
|
)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return migtest.RestoreDB(
|
||
|
tx, cChanIDIndexBkt, test.preChanIndex,
|
||
|
)
|
||
|
}
|
||
|
|
||
|
after := func(tx kvdb.RwTx) error {
|
||
|
// If the migration fails, the details bucket
|
||
|
// should be untouched.
|
||
|
if test.shouldFail {
|
||
|
if err := migtest.VerifyDB(
|
||
|
tx, cChanDetailsBkt,
|
||
|
test.preDetails,
|
||
|
); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// Else, we expect an updated details bucket
|
||
|
// and a new index bucket.
|
||
|
return migtest.VerifyDB(
|
||
|
tx, cChanDetailsBkt, test.postDetails,
|
||
|
)
|
||
|
}
|
||
|
|
||
|
migtest.ApplyMigration(
|
||
|
t, before, after, MigrateChannelToSessionIndex,
|
||
|
test.shouldFail,
|
||
|
)
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func sessionIDString(id string) string {
|
||
|
var sessID SessionID
|
||
|
copy(sessID[:], id)
|
||
|
return sessID.String()
|
||
|
}
|
||
|
|
||
|
func channelIDString(id uint64) string {
|
||
|
var chanID ChannelID
|
||
|
byteOrder.PutUint64(chanID[:], id)
|
||
|
return string(chanID[:])
|
||
|
}
|
||
|
|
||
|
func uint64ToStr(id uint64) string {
|
||
|
b, err := writeUint64(id)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
|
||
|
return string(b)
|
||
|
}
|