mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-07-01 02:51:37 +02:00
Merge pull request #6563 from yyforyongyu/export-chanstatus
multi: export channel status field in migration25
This commit is contained in:
@ -277,9 +277,13 @@ type OpenChannel struct {
|
|||||||
// ChanType denotes which type of channel this is.
|
// ChanType denotes which type of channel this is.
|
||||||
ChanType ChannelType
|
ChanType ChannelType
|
||||||
|
|
||||||
// chanStatus is the current status of this channel. If it is not in
|
// ChanStatus is the current status of this channel. If it is not in
|
||||||
// the state Default, it should not be used for forwarding payments.
|
// the state Default, it should not be used for forwarding payments.
|
||||||
chanStatus ChannelStatus
|
//
|
||||||
|
// NOTE: In `channeldb.OpenChannel`, this field is private. We choose
|
||||||
|
// to export this private field such that following migrations can
|
||||||
|
// access this field directly.
|
||||||
|
ChanStatus ChannelStatus
|
||||||
|
|
||||||
// InitialLocalBalance is the balance we have during the channel
|
// InitialLocalBalance is the balance we have during the channel
|
||||||
// opening. When we are not the initiator, this value represents the
|
// opening. When we are not the initiator, this value represents the
|
||||||
@ -320,10 +324,10 @@ func (c *OpenChannel) hasChanStatus(status ChannelStatus) bool {
|
|||||||
// Special case ChanStatusDefualt since it isn't actually flag, but a
|
// Special case ChanStatusDefualt since it isn't actually flag, but a
|
||||||
// particular combination (or lack-there-of) of flags.
|
// particular combination (or lack-there-of) of flags.
|
||||||
if status == ChanStatusDefault {
|
if status == ChanStatusDefault {
|
||||||
return c.chanStatus == ChanStatusDefault
|
return c.ChanStatus == ChanStatusDefault
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.chanStatus&status == status
|
return c.ChanStatus&status == status
|
||||||
}
|
}
|
||||||
|
|
||||||
// FundingTxPresent returns true if expect the funding transcation to be found
|
// FundingTxPresent returns true if expect the funding transcation to be found
|
||||||
@ -361,7 +365,7 @@ func fetchChanInfo(chanBucket kvdb.RBucket, c *OpenChannel, legacy bool) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.ChanType = ChannelType(chanType)
|
c.ChanType = ChannelType(chanType)
|
||||||
c.chanStatus = ChannelStatus(chanStatus)
|
c.ChanStatus = ChannelStatus(chanStatus)
|
||||||
|
|
||||||
// If this is not the legacy format, we need to read the extra two new
|
// If this is not the legacy format, we need to read the extra two new
|
||||||
// fields.
|
// fields.
|
||||||
@ -432,7 +436,7 @@ func putChanInfo(chanBucket kvdb.RwBucket, c *OpenChannel, legacy bool) error {
|
|||||||
if err := mig.WriteElements(&w,
|
if err := mig.WriteElements(&w,
|
||||||
mig.ChannelType(c.ChanType), c.ChainHash, c.FundingOutpoint,
|
mig.ChannelType(c.ChanType), c.ChainHash, c.FundingOutpoint,
|
||||||
c.ShortChannelID, c.IsPending, c.IsInitiator,
|
c.ShortChannelID, c.IsPending, c.IsInitiator,
|
||||||
mig.ChannelStatus(c.chanStatus), c.FundingBroadcastHeight,
|
mig.ChannelStatus(c.ChanStatus), c.FundingBroadcastHeight,
|
||||||
c.NumConfsRequired, c.ChannelFlags,
|
c.NumConfsRequired, c.ChannelFlags,
|
||||||
c.IdentityPub, c.Capacity, c.TotalMSatSent,
|
c.IdentityPub, c.Capacity, c.TotalMSatSent,
|
||||||
c.TotalMSatReceived,
|
c.TotalMSatReceived,
|
||||||
|
@ -70,10 +70,6 @@ var (
|
|||||||
// NOTE: doesn't have the Packager field as it's not used in current migration.
|
// NOTE: doesn't have the Packager field as it's not used in current migration.
|
||||||
type OpenChannel struct {
|
type OpenChannel struct {
|
||||||
mig25.OpenChannel
|
mig25.OpenChannel
|
||||||
|
|
||||||
// chanStatus is the current status of this channel. If it is not in
|
|
||||||
// the state Default, it should not be used for forwarding payments.
|
|
||||||
chanStatus mig25.ChannelStatus
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FetchChanInfo deserializes the channel info based on the legacy boolean.
|
// FetchChanInfo deserializes the channel info based on the legacy boolean.
|
||||||
@ -104,7 +100,7 @@ func FetchChanInfo(chanBucket kvdb.RBucket, c *OpenChannel, legacy bool) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.ChanType = mig25.ChannelType(chanType)
|
c.ChanType = mig25.ChannelType(chanType)
|
||||||
c.chanStatus = mig25.ChannelStatus(chanStatus)
|
c.ChanStatus = mig25.ChannelStatus(chanStatus)
|
||||||
|
|
||||||
// If this is the legacy format, we need to read the extra two new
|
// If this is the legacy format, we need to read the extra two new
|
||||||
// fields.
|
// fields.
|
||||||
@ -239,7 +235,7 @@ func PutChanInfo(chanBucket kvdb.RwBucket, c *OpenChannel, legacy bool) error {
|
|||||||
if err := mig.WriteElements(&w,
|
if err := mig.WriteElements(&w,
|
||||||
mig.ChannelType(c.ChanType), c.ChainHash, c.FundingOutpoint,
|
mig.ChannelType(c.ChanType), c.ChainHash, c.FundingOutpoint,
|
||||||
c.ShortChannelID, c.IsPending, c.IsInitiator,
|
c.ShortChannelID, c.IsPending, c.IsInitiator,
|
||||||
mig.ChannelStatus(c.chanStatus), c.FundingBroadcastHeight,
|
mig.ChannelStatus(c.ChanStatus), c.FundingBroadcastHeight,
|
||||||
c.NumConfsRequired, c.ChannelFlags,
|
c.NumConfsRequired, c.ChannelFlags,
|
||||||
c.IdentityPub, c.Capacity, c.TotalMSatSent,
|
c.IdentityPub, c.Capacity, c.TotalMSatSent,
|
||||||
c.TotalMSatReceived,
|
c.TotalMSatReceived,
|
||||||
|
@ -59,10 +59,6 @@ var (
|
|||||||
// NOTE: doesn't have the Packager field as it's not used in current migration.
|
// NOTE: doesn't have the Packager field as it's not used in current migration.
|
||||||
type OpenChannel struct {
|
type OpenChannel struct {
|
||||||
mig26.OpenChannel
|
mig26.OpenChannel
|
||||||
|
|
||||||
// chanStatus is the current status of this channel. If it is not in
|
|
||||||
// the state Default, it should not be used for forwarding payments.
|
|
||||||
chanStatus mig25.ChannelStatus
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FetchChanInfo deserializes the channel info based on the legacy boolean.
|
// FetchChanInfo deserializes the channel info based on the legacy boolean.
|
||||||
@ -90,7 +86,7 @@ func FetchChanInfo(chanBucket kvdb.RBucket, c *OpenChannel, legacy bool) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.ChanType = mig25.ChannelType(chanType)
|
c.ChanType = mig25.ChannelType(chanType)
|
||||||
c.chanStatus = mig25.ChannelStatus(chanStatus)
|
c.ChanStatus = mig25.ChannelStatus(chanStatus)
|
||||||
|
|
||||||
// For single funder channels that we initiated and have the funding
|
// For single funder channels that we initiated and have the funding
|
||||||
// transaction to, read the funding txn.
|
// transaction to, read the funding txn.
|
||||||
@ -182,7 +178,7 @@ func PutChanInfo(chanBucket kvdb.RwBucket, c *OpenChannel, legacy bool) error {
|
|||||||
if err := mig.WriteElements(&w,
|
if err := mig.WriteElements(&w,
|
||||||
mig.ChannelType(c.ChanType), c.ChainHash, c.FundingOutpoint,
|
mig.ChannelType(c.ChanType), c.ChainHash, c.FundingOutpoint,
|
||||||
c.ShortChannelID, c.IsPending, c.IsInitiator,
|
c.ShortChannelID, c.IsPending, c.IsInitiator,
|
||||||
mig.ChannelStatus(c.chanStatus), c.FundingBroadcastHeight,
|
mig.ChannelStatus(c.ChanStatus), c.FundingBroadcastHeight,
|
||||||
c.NumConfsRequired, c.ChannelFlags,
|
c.NumConfsRequired, c.ChannelFlags,
|
||||||
c.IdentityPub, c.Capacity, c.TotalMSatSent,
|
c.IdentityPub, c.Capacity, c.TotalMSatSent,
|
||||||
c.TotalMSatReceived,
|
c.TotalMSatReceived,
|
||||||
|
@ -54,42 +54,80 @@ var (
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// testChannel is used to test the balance fields are correctly set.
|
// testChanStatus specifies the following channel status,
|
||||||
testChannel = &OpenChannel{
|
// ChanStatusLocalDataLoss|ChanStatusRestored|ChanStatusRemoteCloseInitiator
|
||||||
OpenChannel: mig26.OpenChannel{
|
testChanStatus = mig25.ChannelStatus(0x4c)
|
||||||
OpenChannel: mig25.OpenChannel{
|
|
||||||
OpenChannel: mig.OpenChannel{
|
|
||||||
IdentityPub: dummyPubKey,
|
|
||||||
FundingOutpoint: dummyOp,
|
|
||||||
FundingTxn: commitTx1,
|
|
||||||
IsInitiator: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// TestMigrateHistoricalBalances checks that the initial balances fields are
|
// TestMigrateHistoricalBalances checks that the initial balances fields are
|
||||||
// patched to the historical channel info.
|
// patched to the historical channel info.
|
||||||
func TestMigrateHistoricalBalances(t *testing.T) {
|
func TestMigrateHistoricalBalances(t *testing.T) {
|
||||||
// Test that when the historical channel doesn't have the two new
|
testCases := []struct {
|
||||||
// fields.
|
name string
|
||||||
migtest.ApplyMigration(
|
isAfterMigration25 bool
|
||||||
t,
|
isRestored bool
|
||||||
genBeforeMigration(testChannel, false),
|
}{
|
||||||
genAfterMigration(testChannel),
|
{
|
||||||
MigrateHistoricalBalances,
|
// Test that when the restored historical channel
|
||||||
false,
|
// doesn't have the two new fields.
|
||||||
)
|
name: "restored before migration25",
|
||||||
|
isAfterMigration25: false,
|
||||||
|
isRestored: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Test that when the restored historical channel have
|
||||||
|
// the two new fields.
|
||||||
|
name: "restored after migration25",
|
||||||
|
isAfterMigration25: true,
|
||||||
|
isRestored: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Test that when the historical channel with a default
|
||||||
|
// channel status flag doesn't have the two new fields.
|
||||||
|
name: "default before migration25",
|
||||||
|
isAfterMigration25: false,
|
||||||
|
isRestored: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Test that when the historical channel with a default
|
||||||
|
// channel status flag have the two new fields.
|
||||||
|
name: "default after migration25",
|
||||||
|
isAfterMigration25: true,
|
||||||
|
isRestored: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// Test that when the historical channel have the two new fields.
|
for _, tc := range testCases {
|
||||||
migtest.ApplyMigration(
|
tc := tc
|
||||||
t,
|
|
||||||
genBeforeMigration(testChannel, true),
|
// testChannel is used to test the balance fields are correctly
|
||||||
genAfterMigration(testChannel),
|
// set.
|
||||||
MigrateHistoricalBalances,
|
testChannel := &OpenChannel{}
|
||||||
false,
|
testChannel.IdentityPub = dummyPubKey
|
||||||
|
testChannel.FundingOutpoint = dummyOp
|
||||||
|
testChannel.FundingTxn = commitTx1
|
||||||
|
testChannel.IsInitiator = true
|
||||||
|
|
||||||
|
// Set the channel status flag is we are testing the restored
|
||||||
|
// case.
|
||||||
|
if tc.isRestored {
|
||||||
|
testChannel.ChanStatus = testChanStatus
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create before and after migration functions.
|
||||||
|
beforeFn := genBeforeMigration(
|
||||||
|
testChannel, tc.isAfterMigration25,
|
||||||
)
|
)
|
||||||
|
afterFn := genAfterMigration(testChannel, tc.isRestored)
|
||||||
|
|
||||||
|
// Run the test.
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
migtest.ApplyMigration(
|
||||||
|
t, beforeFn, afterFn,
|
||||||
|
MigrateHistoricalBalances, false,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func genBeforeMigration(c *OpenChannel, regression bool) func(kvdb.RwTx) error {
|
func genBeforeMigration(c *OpenChannel, regression bool) func(kvdb.RwTx) error {
|
||||||
@ -116,7 +154,7 @@ func genBeforeMigration(c *OpenChannel, regression bool) func(kvdb.RwTx) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func genAfterMigration(c *OpenChannel) func(kvdb.RwTx) error {
|
func genAfterMigration(c *OpenChannel, restored bool) func(kvdb.RwTx) error {
|
||||||
return func(tx kvdb.RwTx) error {
|
return func(tx kvdb.RwTx) error {
|
||||||
chanBucket, err := fetchHistoricalChanBucket(tx, c)
|
chanBucket, err := fetchHistoricalChanBucket(tx, c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -159,6 +197,16 @@ func genAfterMigration(c *OpenChannel) func(kvdb.RwTx) error {
|
|||||||
if !newChan.IsInitiator {
|
if !newChan.IsInitiator {
|
||||||
return fmt.Errorf("wrong IsInitiator")
|
return fmt.Errorf("wrong IsInitiator")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If it's restored, there should be no funding tx.
|
||||||
|
if restored {
|
||||||
|
if newChan.FundingTxn != nil {
|
||||||
|
return fmt.Errorf("expect nil FundingTxn")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise check the funding tx is read as expected.
|
||||||
if newChan.FundingTxn.TxHash() != commitTx1.TxHash() {
|
if newChan.FundingTxn.TxHash() != commitTx1.TxHash() {
|
||||||
return fmt.Errorf("wrong FundingTxn")
|
return fmt.Errorf("wrong FundingTxn")
|
||||||
}
|
}
|
||||||
@ -167,7 +215,9 @@ func genAfterMigration(c *OpenChannel) func(kvdb.RwTx) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func createHistoricalBucket(tx kvdb.RwTx, c *OpenChannel) (kvdb.RwBucket, error) {
|
func createHistoricalBucket(tx kvdb.RwTx,
|
||||||
|
c *OpenChannel) (kvdb.RwBucket, error) {
|
||||||
|
|
||||||
// First fetch the top level bucket which stores all data related to
|
// First fetch the top level bucket which stores all data related to
|
||||||
// historical channels.
|
// historical channels.
|
||||||
rootBucket, err := tx.CreateTopLevelBucket(historicalChannelBucket)
|
rootBucket, err := tx.CreateTopLevelBucket(historicalChannelBucket)
|
||||||
|
@ -172,6 +172,9 @@ from occurring that would result in an erroneous force close.](https://github.co
|
|||||||
* [Fixed an intermittent panic that would occur due to a violated assumption with our
|
* [Fixed an intermittent panic that would occur due to a violated assumption with our
|
||||||
underlying database.](https://github.com/lightningnetwork/lnd/pull/6547)
|
underlying database.](https://github.com/lightningnetwork/lnd/pull/6547)
|
||||||
|
|
||||||
|
* [Fixed a wrong channel status inheritance used in `migration26` and
|
||||||
|
`migration27`](https://github.com/lightningnetwork/lnd/pull/6563).
|
||||||
|
|
||||||
## Routing
|
## Routing
|
||||||
|
|
||||||
* [Add a new `time_pref` parameter to the QueryRoutes and SendPayment APIs](https://github.com/lightningnetwork/lnd/pull/6024) that
|
* [Add a new `time_pref` parameter to the QueryRoutes and SendPayment APIs](https://github.com/lightningnetwork/lnd/pull/6024) that
|
||||||
|
Reference in New Issue
Block a user