diff --git a/breacharbiter_test.go b/breacharbiter_test.go index 7f471ea2e..724643aef 100644 --- a/breacharbiter_test.go +++ b/breacharbiter_test.go @@ -1865,7 +1865,7 @@ func createInitChannels(revocationWindow int) (*lnwallet.LightningChannel, *lnwa IdentityPub: aliceKeyPub, FundingOutpoint: *prevOut, ShortChannelID: shortChanID, - ChanType: channeldb.SingleFunderTweakless, + ChanType: channeldb.SingleFunderTweaklessBit, IsInitiator: true, Capacity: channelCapacity, RemoteCurrentRevocation: bobCommitPoint, @@ -1883,7 +1883,7 @@ func createInitChannels(revocationWindow int) (*lnwallet.LightningChannel, *lnwa IdentityPub: bobKeyPub, FundingOutpoint: *prevOut, ShortChannelID: shortChanID, - ChanType: channeldb.SingleFunderTweakless, + ChanType: channeldb.SingleFunderTweaklessBit, IsInitiator: false, Capacity: channelCapacity, RemoteCurrentRevocation: aliceCommitPoint, diff --git a/chanbackup/single_test.go b/chanbackup/single_test.go index ba56ece76..776ce0bc8 100644 --- a/chanbackup/single_test.go +++ b/chanbackup/single_test.go @@ -124,9 +124,9 @@ func genRandomOpenChannelShell() (*channeldb.OpenChannel, error) { isInitiator = true } - chanType := channeldb.SingleFunder + chanType := channeldb.SingleFunderBit if rand.Int63()%2 == 0 { - chanType = channeldb.SingleFunderTweakless + chanType = channeldb.SingleFunderTweaklessBit } return &channeldb.OpenChannel{ diff --git a/channeldb/channel.go b/channeldb/channel.go index 7bc9e4806..1fdd97e9d 100644 --- a/channeldb/channel.go +++ b/channeldb/channel.go @@ -125,39 +125,45 @@ var ( // ChannelType is an enum-like type that describes one of several possible // channel types. Each open channel is associated with a particular type as the // channel type may determine how higher level operations are conducted such as -// fee negotiation, channel closing, the format of HTLCs, etc. -// TODO(roasbeef): split up per-chain? +// fee negotiation, channel closing, the format of HTLCs, etc. Structure-wise, +// a ChannelType is a bit field, with each bit denoting a modification from the +// base channel type of single funder. type ChannelType uint8 const ( // NOTE: iota isn't used here for this enum needs to be stable // long-term as it will be persisted to the database. - // SingleFunder represents a channel wherein one party solely funds the - // entire capacity of the channel. - SingleFunder ChannelType = 0 + // SingleFunderBit represents a channel wherein one party solely funds + // the entire capacity of the channel. + SingleFunderBit ChannelType = 0 - // DualFunder represents a channel wherein both parties contribute + // DualFunderBit represents a channel wherein both parties contribute // funds towards the total capacity of the channel. The channel may be // funded symmetrically or asymmetrically. - DualFunder ChannelType = 1 + DualFunderBit ChannelType = 1 << 0 // SingleFunderTweakless is similar to the basic SingleFunder channel // type, but it omits the tweak for one's key in the commitment // transaction of the remote party. - SingleFunderTweakless ChannelType = 2 + SingleFunderTweaklessBit ChannelType = 1 << 1 ) // IsSingleFunder returns true if the channel type if one of the known single // funder variants. func (c ChannelType) IsSingleFunder() bool { - return c == SingleFunder || c == SingleFunderTweakless + return c&DualFunderBit == 0 +} + +// IsDualFunder returns true if the ChannelType has the DualFunderBit set. +func (c ChannelType) IsDualFunder() bool { + return c&DualFunderBit == DualFunderBit } // IsTweakless returns true if the target channel uses a commitment that // doesn't tweak the key for the remote party. func (c ChannelType) IsTweakless() bool { - return c == SingleFunderTweakless + return c&SingleFunderTweaklessBit == SingleFunderTweaklessBit } // ChannelConstraints represents a set of constraints meant to allow a node to diff --git a/channeldb/channel_test.go b/channeldb/channel_test.go index 21bb738cf..6d34c2f97 100644 --- a/channeldb/channel_test.go +++ b/channeldb/channel_test.go @@ -187,7 +187,7 @@ func createTestChannelState(cdb *DB) (*OpenChannel, error) { chanID := lnwire.NewShortChanIDFromInt(uint64(rand.Int63())) return &OpenChannel{ - ChanType: SingleFunder, + ChanType: SingleFunderBit, ChainHash: key, FundingOutpoint: wire.OutPoint{Hash: key, Index: rand.Uint32()}, ShortChannelID: chanID, diff --git a/chanrestore.go b/chanrestore.go index 6196aed58..5586ab920 100644 --- a/chanrestore.go +++ b/chanrestore.go @@ -87,10 +87,10 @@ func (c *chanDBRestorer) openChannelShell(backup chanbackup.Single) ( switch backup.Version { case chanbackup.DefaultSingleVersion: - chanType = channeldb.SingleFunder + chanType = channeldb.SingleFunderBit case chanbackup.TweaklessCommitVersion: - chanType = channeldb.SingleFunderTweakless + chanType = channeldb.SingleFunderTweaklessBit default: return nil, fmt.Errorf("unknown Single version: %v", err) diff --git a/fundingmanager.go b/fundingmanager.go index c18df5ab5..4275338c8 100644 --- a/fundingmanager.go +++ b/fundingmanager.go @@ -521,7 +521,7 @@ func (f *fundingManager) start() error { // Rebroadcast the funding transaction for any pending // channel that we initiated. No error will be returned // if the transaction already has been broadcasted. - if channel.ChanType == channeldb.SingleFunder && + if channel.ChanType.IsSingleFunder() && channel.IsInitiator { err := f.cfg.PublishTransaction( diff --git a/htlcswitch/link.go b/htlcswitch/link.go index c0b62633c..b2ffe87c9 100644 --- a/htlcswitch/link.go +++ b/htlcswitch/link.go @@ -1860,11 +1860,9 @@ func (l *channelLink) handleUpstreamMsg(msg lnwire.Message) { } chanType := l.channel.State().ChanType - isTweakless := chanType == channeldb.SingleFunderTweakless - chanID := l.ChanID() err = l.cfg.TowerClient.BackupState( - &chanID, breachInfo, isTweakless, + &chanID, breachInfo, chanType.IsTweakless(), ) if err != nil { l.fail(LinkFailureError{code: ErrInternalError}, diff --git a/htlcswitch/test_utils.go b/htlcswitch/test_utils.go index 3c11c3fd6..5ff595663 100644 --- a/htlcswitch/test_utils.go +++ b/htlcswitch/test_utils.go @@ -328,7 +328,7 @@ func createTestChannel(alicePrivKey, bobPrivKey []byte, RemoteChanCfg: bobCfg, IdentityPub: aliceKeyPub, FundingOutpoint: *prevOut, - ChanType: channeldb.SingleFunderTweakless, + ChanType: channeldb.SingleFunderTweaklessBit, IsInitiator: true, Capacity: channelCapacity, RemoteCurrentRevocation: bobCommitPoint, @@ -347,7 +347,7 @@ func createTestChannel(alicePrivKey, bobPrivKey []byte, RemoteChanCfg: aliceCfg, IdentityPub: bobKeyPub, FundingOutpoint: *prevOut, - ChanType: channeldb.SingleFunderTweakless, + ChanType: channeldb.SingleFunderTweaklessBit, IsInitiator: false, Capacity: channelCapacity, RemoteCurrentRevocation: aliceCommitPoint, diff --git a/lnwallet/channel.go b/lnwallet/channel.go index f9d077875..b199efe53 100644 --- a/lnwallet/channel.go +++ b/lnwallet/channel.go @@ -868,8 +868,7 @@ func (lc *LightningChannel) diskCommitToMemCommit(isLocal bool, // If this commit is tweakless, then it'll affect the way we derive our // keys, which will affect the commitment transaction reconstruction. // So we'll determine this first, before we do anything else. - tweaklessCommit := (lc.channelState.ChanType == - channeldb.SingleFunderTweakless) + tweaklessCommit := lc.channelState.ChanType.IsTweakless() // First, we'll need to re-derive the commitment key ring for each // party used within this particular state. If this is a pending commit diff --git a/lnwallet/interface_test.go b/lnwallet/interface_test.go index 04af443fa..d998c0a04 100644 --- a/lnwallet/interface_test.go +++ b/lnwallet/interface_test.go @@ -511,7 +511,7 @@ func testDualFundingReservationWorkflow(miner *rpctest.Harness, if !bytes.Equal(aliceChannels[0].FundingOutpoint.Hash[:], fundingSha[:]) { t.Fatalf("channel state not properly saved") } - if aliceChannels[0].ChanType != channeldb.DualFunder { + if !aliceChannels[0].ChanType.IsDualFunder() { t.Fatalf("channel not detected as dual funder") } bobChannels, err := bob.Cfg.Database.FetchOpenChannels(alicePub) @@ -521,7 +521,7 @@ func testDualFundingReservationWorkflow(miner *rpctest.Harness, if !bytes.Equal(bobChannels[0].FundingOutpoint.Hash[:], fundingSha[:]) { t.Fatalf("channel state not properly saved") } - if bobChannels[0].ChanType != channeldb.DualFunder { + if !bobChannels[0].ChanType.IsDualFunder() { t.Fatalf("channel not detected as dual funder") } @@ -971,7 +971,7 @@ func testSingleFunderReservationWorkflow(miner *rpctest.Harness, } if !aliceChannels[0].ChanType.IsSingleFunder() { t.Fatalf("channel type is incorrect, expected %v instead got %v", - channeldb.SingleFunder, aliceChannels[0].ChanType) + channeldb.SingleFunderBit, aliceChannels[0].ChanType) } bobChannels, err := bob.Cfg.Database.FetchOpenChannels(alicePub) @@ -991,7 +991,7 @@ func testSingleFunderReservationWorkflow(miner *rpctest.Harness, } if !bobChannels[0].ChanType.IsSingleFunder() { t.Fatalf("channel type is incorrect, expected %v instead got %v", - channeldb.SingleFunder, bobChannels[0].ChanType) + channeldb.SingleFunderBit, bobChannels[0].ChanType) } // Let Alice publish the funding transaction. diff --git a/lnwallet/reservation.go b/lnwallet/reservation.go index b96651ff0..465a9b41f 100644 --- a/lnwallet/reservation.go +++ b/lnwallet/reservation.go @@ -215,15 +215,15 @@ func NewChannelReservation(capacity, localFundingAmt btcutil.Amount, // a single-funder channel. if ourBalance == 0 || theirBalance == 0 || pushMSat != 0 { if tweaklessCommit { - chanType = channeldb.SingleFunderTweakless + chanType |= channeldb.SingleFunderTweaklessBit } else { - chanType = channeldb.SingleFunder + chanType |= channeldb.SingleFunderBit } } else { // Otherwise, this is a dual funder channel, and no side is // technically the "initiator" initiator = false - chanType = channeldb.DualFunder + chanType |= channeldb.DualFunderBit } return &ChannelReservation{ diff --git a/lnwallet/test_utils.go b/lnwallet/test_utils.go index efb30ac1d..324064ffb 100644 --- a/lnwallet/test_utils.go +++ b/lnwallet/test_utils.go @@ -274,7 +274,7 @@ func CreateTestChannels(tweaklessCommits bool) ( IdentityPub: aliceKeys[0].PubKey(), FundingOutpoint: *prevOut, ShortChannelID: shortChanID, - ChanType: channeldb.SingleFunderTweakless, + ChanType: channeldb.SingleFunderTweaklessBit, IsInitiator: true, Capacity: channelCapacity, RemoteCurrentRevocation: bobCommitPoint, @@ -292,7 +292,7 @@ func CreateTestChannels(tweaklessCommits bool) ( IdentityPub: bobKeys[0].PubKey(), FundingOutpoint: *prevOut, ShortChannelID: shortChanID, - ChanType: channeldb.SingleFunderTweakless, + ChanType: channeldb.SingleFunderTweaklessBit, IsInitiator: false, Capacity: channelCapacity, RemoteCurrentRevocation: aliceCommitPoint, @@ -305,8 +305,8 @@ func CreateTestChannels(tweaklessCommits bool) ( } if !tweaklessCommits { - aliceChannelState.ChanType = channeldb.SingleFunder - bobChannelState.ChanType = channeldb.SingleFunder + aliceChannelState.ChanType = channeldb.SingleFunderBit + bobChannelState.ChanType = channeldb.SingleFunderBit } aliceSigner := &input.MockSigner{Privkeys: aliceKeys} diff --git a/lnwallet/transactions_test.go b/lnwallet/transactions_test.go index ed4c533db..9fdacc071 100644 --- a/lnwallet/transactions_test.go +++ b/lnwallet/transactions_test.go @@ -370,7 +370,7 @@ func TestCommitmentAndHTLCTransactions(t *testing.T) { // Manually construct a new LightningChannel. channelState := channeldb.OpenChannel{ - ChanType: channeldb.SingleFunderTweakless, + ChanType: channeldb.SingleFunderTweaklessBit, ChainHash: *tc.netParams.GenesisHash, FundingOutpoint: tc.fundingOutpoint, ShortChannelID: tc.shortChanID, diff --git a/test_utils.go b/test_utils.go index 671bc0f46..06f3767dd 100644 --- a/test_utils.go +++ b/test_utils.go @@ -255,7 +255,7 @@ func createTestPeer(notifier chainntnfs.ChainNotifier, IdentityPub: aliceKeyPub, FundingOutpoint: *prevOut, ShortChannelID: shortChanID, - ChanType: channeldb.SingleFunderTweakless, + ChanType: channeldb.SingleFunderTweaklessBit, IsInitiator: true, Capacity: channelCapacity, RemoteCurrentRevocation: bobCommitPoint, @@ -272,7 +272,7 @@ func createTestPeer(notifier chainntnfs.ChainNotifier, RemoteChanCfg: aliceCfg, IdentityPub: bobKeyPub, FundingOutpoint: *prevOut, - ChanType: channeldb.SingleFunderTweakless, + ChanType: channeldb.SingleFunderTweaklessBit, IsInitiator: false, Capacity: channelCapacity, RemoteCurrentRevocation: aliceCommitPoint,