lnwallet+funding: create CommitmentType enum

This commit is contained in:
Johan T. Halseth 2020-03-06 16:11:48 +01:00
parent 8741b93723
commit f95a82bf5f
No known key found for this signature in database
GPG Key ID: 15BAADA29DA20D26
4 changed files with 76 additions and 32 deletions

@ -1106,6 +1106,28 @@ func (f *fundingManager) processFundingOpen(msg *lnwire.OpenChannel,
}
}
// commitmentType returns the commitment type to use for the channel, based on
// the features the two peers have available.
func commitmentType(localFeatures,
remoteFeatures *lnwire.FeatureVector) lnwallet.CommitmentType {
localTweakless := localFeatures.HasFeature(
lnwire.StaticRemoteKeyOptional,
)
remoteTweakless := remoteFeatures.HasFeature(
lnwire.StaticRemoteKeyOptional,
)
// If both nodes are signaling the proper feature bit for tweakless
// copmmitments, we'll use that.
if localTweakless && remoteTweakless {
return lnwallet.CommitmentTypeTweakless
}
// Otherwise we'll fall back to the legacy type.
return lnwallet.CommitmentTypeLegacy
}
// handleFundingOpen creates an initial 'ChannelReservation' within the wallet,
// then responds to the source peer with an accept channel message progressing
// the funding workflow.
@ -1228,13 +1250,9 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) {
// negotiated the new tweakless commitment format. This is only the
// case if *both* us and the remote peer are signaling the proper
// feature bit.
localTweakless := fmsg.peer.LocalFeatures().HasFeature(
lnwire.StaticRemoteKeyOptional,
commitType := commitmentType(
fmsg.peer.LocalFeatures(), fmsg.peer.RemoteFeatures(),
)
remoteTweakless := fmsg.peer.RemoteFeatures().HasFeature(
lnwire.StaticRemoteKeyOptional,
)
tweaklessCommitment := localTweakless && remoteTweakless
chainHash := chainhash.Hash(msg.ChainHash)
req := &lnwallet.InitFundingReserveMsg{
ChainHash: &chainHash,
@ -1248,7 +1266,7 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) {
PushMSat: msg.PushAmount,
Flags: msg.ChannelFlags,
MinConfs: 1,
Tweakless: tweaklessCommitment,
CommitType: commitType,
}
reservation, err := f.cfg.Wallet.InitChannelReservation(req)
@ -1307,9 +1325,9 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) {
reservation.SetOurUpfrontShutdown(shutdown)
fndgLog.Infof("Requiring %v confirmations for pendingChan(%x): "+
"amt=%v, push_amt=%v, tweakless=%v, upfrontShutdown=%x", numConfsReq,
"amt=%v, push_amt=%v, committype=%v, upfrontShutdown=%x", numConfsReq,
fmsg.msg.PendingChannelID, amt, msg.PushAmount,
tweaklessCommitment, msg.UpfrontShutdownScript)
commitType, msg.UpfrontShutdownScript)
// Generate our required constraints for the remote party.
remoteCsvDelay := f.cfg.RequiredRemoteDelay(amt)
@ -2904,13 +2922,9 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) {
// negotiated the new tweakless commitment format. This is only the
// case if *both* us and the remote peer are signaling the proper
// feature bit.
localTweakless := msg.peer.LocalFeatures().HasFeature(
lnwire.StaticRemoteKeyOptional,
commitType := commitmentType(
msg.peer.LocalFeatures(), msg.peer.RemoteFeatures(),
)
remoteTweakless := msg.peer.RemoteFeatures().HasFeature(
lnwire.StaticRemoteKeyOptional,
)
tweaklessCommitment := localTweakless && remoteTweakless
req := &lnwallet.InitFundingReserveMsg{
ChainHash: &msg.chainHash,
PendingChanID: chanID,
@ -2924,7 +2938,7 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) {
PushMSat: msg.pushAmt,
Flags: channelFlags,
MinConfs: msg.minConfs,
Tweakless: tweaklessCommitment,
CommitType: commitType,
ChanFunder: msg.chanFunder,
}
@ -3012,7 +3026,7 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) {
maxHtlcs := f.cfg.RequiredRemoteMaxHTLCs(capacity)
fndgLog.Infof("Starting funding workflow with %v for pending_id(%x), "+
"tweakless=%v", msg.peer.Address(), chanID, tweaklessCommitment)
"committype=%v", msg.peer.Address(), chanID, commitType)
fundingOpen := lnwire.OpenChannel{
ChainHash: *f.cfg.Wallet.Cfg.NetParams.GenesisHash,

@ -700,7 +700,8 @@ func testCancelNonExistentReservation(miner *rpctest.Harness,
// Create our own reservation, give it some ID.
res, err := lnwallet.NewChannelReservation(
10000, 10000, feePerKw, alice, 22, 10, &testHdSeed,
lnwire.FFAnnounceChannel, true, nil, [32]byte{},
lnwire.FFAnnounceChannel, lnwallet.CommitmentTypeTweakless,
nil, [32]byte{},
)
if err != nil {
t.Fatalf("unable to create res: %v", err)
@ -738,7 +739,7 @@ func testReservationInitiatorBalanceBelowDustCancel(miner *rpctest.Harness,
FundingFeePerKw: 1000,
PushMSat: 0,
Flags: lnwire.FFAnnounceChannel,
Tweakless: true,
CommitType: lnwallet.CommitmentTypeTweakless,
}
_, err = alice.InitChannelReservation(req)
switch {
@ -793,7 +794,8 @@ func assertContributionInitPopulated(t *testing.T, c *lnwallet.ChannelContributi
}
func testSingleFunderReservationWorkflow(miner *rpctest.Harness,
alice, bob *lnwallet.LightningWallet, t *testing.T, tweakless bool,
alice, bob *lnwallet.LightningWallet, t *testing.T,
commitType lnwallet.CommitmentType,
aliceChanFunder chanfunding.Assembler,
fetchFundingTx func() *wire.MsgTx, pendingChanID [32]byte) {
@ -823,7 +825,7 @@ func testSingleFunderReservationWorkflow(miner *rpctest.Harness,
FundingFeePerKw: feePerKw,
PushMSat: pushAmt,
Flags: lnwire.FFAnnounceChannel,
Tweakless: tweakless,
CommitType: commitType,
ChanFunder: aliceChanFunder,
}
aliceChanReservation, err := alice.InitChannelReservation(aliceReq)
@ -874,7 +876,7 @@ func testSingleFunderReservationWorkflow(miner *rpctest.Harness,
FundingFeePerKw: feePerKw,
PushMSat: pushAmt,
Flags: lnwire.FFAnnounceChannel,
Tweakless: tweakless,
CommitType: commitType,
}
bobChanReservation, err := bob.InitChannelReservation(bobReq)
if err != nil {
@ -2543,7 +2545,8 @@ var walletTests = []walletTestCase{
bob *lnwallet.LightningWallet, t *testing.T) {
testSingleFunderReservationWorkflow(
miner, alice, bob, t, false, nil, nil,
miner, alice, bob, t,
lnwallet.CommitmentTypeLegacy, nil, nil,
[32]byte{},
)
},
@ -2554,7 +2557,8 @@ var walletTests = []walletTestCase{
bob *lnwallet.LightningWallet, t *testing.T) {
testSingleFunderReservationWorkflow(
miner, alice, bob, t, true, nil, nil,
miner, alice, bob, t,
lnwallet.CommitmentTypeTweakless, nil, nil,
[32]byte{},
)
},
@ -2809,8 +2813,8 @@ func testSingleFunderExternalFundingTx(miner *rpctest.Harness,
// pending channel ID generated above to allow Alice and Bob to track
// the funding flow externally.
testSingleFunderReservationWorkflow(
miner, alice, bob, t, true, aliceExternalFunder,
func() *wire.MsgTx {
miner, alice, bob, t, lnwallet.CommitmentTypeTweakless,
aliceExternalFunder, func() *wire.MsgTx {
return fundingTx
}, pendingChanID,
)

@ -15,6 +15,32 @@ import (
"github.com/lightningnetwork/lnd/lnwire"
)
// CommitmentType is an enum indicating the commitment type we should use for
// the channel we are opening.
type CommitmentType int
const (
// CommitmentTypeLegacy is the legacy commitment format with a tweaked
// to_remote key.
CommitmentTypeLegacy = iota
// CommitmentTypeTweakless is a newer commitment format where the
// to_remote key is static.
CommitmentTypeTweakless
)
// String returns the name of the CommitmentType.
func (c CommitmentType) String() string {
switch c {
case CommitmentTypeLegacy:
return "legacy"
case CommitmentTypeTweakless:
return "tweakless"
default:
return "invalid"
}
}
// ChannelContribution is the primary constituent of the funding workflow
// within lnwallet. Each side first exchanges their respective contributions
// along with channel specific parameters like the min fee/KB. Once
@ -136,7 +162,7 @@ type ChannelReservation struct {
func NewChannelReservation(capacity, localFundingAmt btcutil.Amount,
commitFeePerKw chainfee.SatPerKWeight, wallet *LightningWallet,
id uint64, pushMSat lnwire.MilliSatoshi, chainHash *chainhash.Hash,
flags lnwire.FundingFlag, tweaklessCommit bool,
flags lnwire.FundingFlag, commitType CommitmentType,
fundingAssembler chanfunding.Assembler,
pendingChanID [32]byte) (*ChannelReservation, error) {
@ -231,7 +257,7 @@ func NewChannelReservation(capacity, localFundingAmt btcutil.Amount,
// non-zero push amt (there's no pushing for dual funder), then this is
// a single-funder channel.
if ourBalance == 0 || theirBalance == 0 || pushMSat != 0 {
if tweaklessCommit {
if commitType == CommitmentTypeTweakless {
chanType |= channeldb.SingleFunderTweaklessBit
} else {
chanType |= channeldb.SingleFunderBit

@ -98,9 +98,9 @@ type InitFundingReserveMsg struct {
// output selected to fund the channel should satisfy.
MinConfs int32
// Tweakless indicates if the channel should use the new tweakless
// commitment format or not.
Tweakless bool
// CommitType indicates what type of commitment type the channel should
// be using, like tweakless or anchors.
CommitType CommitmentType
// ChanFunder is an optional channel funder that allows the caller to
// control exactly how the channel funding is carried out. If not
@ -568,7 +568,7 @@ func (l *LightningWallet) handleFundingReserveRequest(req *InitFundingReserveMsg
reservation, err := NewChannelReservation(
capacity, localFundingAmt, req.CommitFeePerKw, l, id,
req.PushMSat, l.Cfg.NetParams.GenesisHash, req.Flags,
req.Tweakless, req.ChanFunder, req.PendingChanID,
req.CommitType, req.ChanFunder, req.PendingChanID,
)
if err != nil {
if fundingIntent != nil {