mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-09-06 17:47:01 +02:00
lnwallet: extend Reservation with alias chan-type, feature-bit flags
This extends the Reservation arguments to include whether a pending channel open has negotiated the zero-conf channel type, the scid-alias channel type, and/or the scid-alias feature bit. The result of those negotiates are stored in the OpenChannel's ChanType. The arguments to NewChannelReservation have also been simplified.
This commit is contained in:
@@ -12,7 +12,6 @@ import (
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/input"
|
||||
"github.com/lightningnetwork/lnd/keychain"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
|
||||
"github.com/lightningnetwork/lnd/lnwallet/chanfunding"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
@@ -208,11 +207,9 @@ type ChannelReservation struct {
|
||||
// creation of all channel reservations should be carried out via the
|
||||
// lnwallet.InitChannelReservation interface.
|
||||
func NewChannelReservation(capacity, localFundingAmt btcutil.Amount,
|
||||
commitFeePerKw chainfee.SatPerKWeight, wallet *LightningWallet,
|
||||
id uint64, pushMSat lnwire.MilliSatoshi, chainHash *chainhash.Hash,
|
||||
flags lnwire.FundingFlag, commitType CommitmentType,
|
||||
fundingAssembler chanfunding.Assembler,
|
||||
pendingChanID [32]byte, thawHeight uint32) (*ChannelReservation, error) {
|
||||
wallet *LightningWallet, id uint64, chainHash *chainhash.Hash,
|
||||
thawHeight uint32, req *InitFundingReserveMsg) (*ChannelReservation,
|
||||
error) {
|
||||
|
||||
var (
|
||||
ourBalance lnwire.MilliSatoshi
|
||||
@@ -223,10 +220,10 @@ func NewChannelReservation(capacity, localFundingAmt btcutil.Amount,
|
||||
// Based on the channel type, we determine the initial commit weight
|
||||
// and fee.
|
||||
commitWeight := int64(input.CommitWeight)
|
||||
if commitType.HasAnchors() {
|
||||
if req.CommitType.HasAnchors() {
|
||||
commitWeight = int64(input.AnchorCommitWeight)
|
||||
}
|
||||
commitFee := commitFeePerKw.FeeForWeight(commitWeight)
|
||||
commitFee := req.CommitFeePerKw.FeeForWeight(commitWeight)
|
||||
|
||||
localFundingMSat := lnwire.NewMSatFromSatoshis(localFundingAmt)
|
||||
// TODO(halseth): make method take remote funding amount directly
|
||||
@@ -236,7 +233,7 @@ func NewChannelReservation(capacity, localFundingAmt btcutil.Amount,
|
||||
// The total fee paid by the initiator will be the commitment fee in
|
||||
// addition to the two anchor outputs.
|
||||
feeMSat := lnwire.NewMSatFromSatoshis(commitFee)
|
||||
if commitType.HasAnchors() {
|
||||
if req.CommitType.HasAnchors() {
|
||||
feeMSat += 2 * lnwire.NewMSatFromSatoshis(anchorSize)
|
||||
}
|
||||
|
||||
@@ -247,8 +244,8 @@ func NewChannelReservation(capacity, localFundingAmt btcutil.Amount,
|
||||
// no initial balance in the channel unless the remote party is pushing
|
||||
// some funds to us within the first commitment state.
|
||||
if localFundingAmt == 0 {
|
||||
ourBalance = pushMSat
|
||||
theirBalance = capacityMSat - feeMSat - pushMSat
|
||||
ourBalance = req.PushMSat
|
||||
theirBalance = capacityMSat - feeMSat - req.PushMSat
|
||||
initiator = false
|
||||
|
||||
// If the responder doesn't have enough funds to actually pay
|
||||
@@ -268,14 +265,14 @@ func NewChannelReservation(capacity, localFundingAmt btcutil.Amount,
|
||||
// we pay all the initial fees within the commitment
|
||||
// transaction. We also deduct our balance by the
|
||||
// amount pushed as part of the initial state.
|
||||
ourBalance = capacityMSat - feeMSat - pushMSat
|
||||
theirBalance = pushMSat
|
||||
ourBalance = capacityMSat - feeMSat - req.PushMSat
|
||||
theirBalance = req.PushMSat
|
||||
} else {
|
||||
// Otherwise, this is a dual funder workflow where both
|
||||
// slides split the amount funded and the commitment
|
||||
// fee.
|
||||
ourBalance = localFundingMSat - (feeMSat / 2)
|
||||
theirBalance = capacityMSat - localFundingMSat - (feeMSat / 2) + pushMSat
|
||||
theirBalance = capacityMSat - localFundingMSat - (feeMSat / 2) + req.PushMSat
|
||||
}
|
||||
|
||||
initiator = true
|
||||
@@ -320,16 +317,16 @@ func NewChannelReservation(capacity, localFundingAmt btcutil.Amount,
|
||||
// If either of the balances are zero at this point, or we have a
|
||||
// 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 ourBalance == 0 || theirBalance == 0 || req.PushMSat != 0 {
|
||||
// Both the tweakless type and the anchor type is tweakless,
|
||||
// hence set the bit.
|
||||
if commitType.HasStaticRemoteKey() {
|
||||
if req.CommitType.HasStaticRemoteKey() {
|
||||
chanType |= channeldb.SingleFunderTweaklessBit
|
||||
} else {
|
||||
chanType |= channeldb.SingleFunderBit
|
||||
}
|
||||
|
||||
switch a := fundingAssembler.(type) {
|
||||
switch a := req.ChanFunder.(type) {
|
||||
// The first channels of a batch shouldn't publish the batch TX
|
||||
// to avoid problems if some of the funding flows can't be
|
||||
// completed. Only the last channel of a batch should publish.
|
||||
@@ -358,14 +355,14 @@ func NewChannelReservation(capacity, localFundingAmt btcutil.Amount,
|
||||
|
||||
// We are adding anchor outputs to our commitment. We only support this
|
||||
// in combination with zero-fee second-levels HTLCs.
|
||||
if commitType.HasAnchors() {
|
||||
if req.CommitType.HasAnchors() {
|
||||
chanType |= channeldb.AnchorOutputsBit
|
||||
chanType |= channeldb.ZeroHtlcTxFeeBit
|
||||
}
|
||||
|
||||
// Set the appropriate LeaseExpiration/Frozen bit based on the
|
||||
// reservation parameters.
|
||||
if commitType == CommitmentTypeScriptEnforcedLease {
|
||||
if req.CommitType == CommitmentTypeScriptEnforcedLease {
|
||||
if thawHeight == 0 {
|
||||
return nil, errors.New("missing absolute expiration " +
|
||||
"for script enforced lease commitment type")
|
||||
@@ -375,6 +372,18 @@ func NewChannelReservation(capacity, localFundingAmt btcutil.Amount,
|
||||
chanType |= channeldb.FrozenBit
|
||||
}
|
||||
|
||||
if req.ZeroConf {
|
||||
chanType |= channeldb.ZeroConfBit
|
||||
}
|
||||
|
||||
if req.OptionScidAlias {
|
||||
chanType |= channeldb.ScidAliasChanBit
|
||||
}
|
||||
|
||||
if req.ScidAliasFeature {
|
||||
chanType |= channeldb.ScidAliasFeatureBit
|
||||
}
|
||||
|
||||
return &ChannelReservation{
|
||||
ourContribution: &ChannelContribution{
|
||||
FundingAmount: ourBalance.ToSatoshis(),
|
||||
@@ -389,18 +398,18 @@ func NewChannelReservation(capacity, localFundingAmt btcutil.Amount,
|
||||
ChainHash: *chainHash,
|
||||
IsPending: true,
|
||||
IsInitiator: initiator,
|
||||
ChannelFlags: flags,
|
||||
ChannelFlags: req.Flags,
|
||||
Capacity: capacity,
|
||||
LocalCommitment: channeldb.ChannelCommitment{
|
||||
LocalBalance: ourBalance,
|
||||
RemoteBalance: theirBalance,
|
||||
FeePerKw: btcutil.Amount(commitFeePerKw),
|
||||
FeePerKw: btcutil.Amount(req.CommitFeePerKw),
|
||||
CommitFee: commitFee,
|
||||
},
|
||||
RemoteCommitment: channeldb.ChannelCommitment{
|
||||
LocalBalance: ourBalance,
|
||||
RemoteBalance: theirBalance,
|
||||
FeePerKw: btcutil.Amount(commitFeePerKw),
|
||||
FeePerKw: btcutil.Amount(req.CommitFeePerKw),
|
||||
CommitFee: commitFee,
|
||||
},
|
||||
ThawHeight: thawHeight,
|
||||
@@ -408,14 +417,22 @@ func NewChannelReservation(capacity, localFundingAmt btcutil.Amount,
|
||||
InitialLocalBalance: ourBalance,
|
||||
InitialRemoteBalance: theirBalance,
|
||||
},
|
||||
pushMSat: pushMSat,
|
||||
pendingChanID: pendingChanID,
|
||||
pushMSat: req.PushMSat,
|
||||
pendingChanID: req.PendingChanID,
|
||||
reservationID: id,
|
||||
wallet: wallet,
|
||||
chanFunder: fundingAssembler,
|
||||
chanFunder: req.ChanFunder,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// AddAlias stores the first alias for zero-conf channels.
|
||||
func (r *ChannelReservation) AddAlias(scid lnwire.ShortChannelID) {
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
|
||||
r.partialState.ShortChannelID = scid
|
||||
}
|
||||
|
||||
// SetNumConfsRequired sets the number of confirmations that are required for
|
||||
// the ultimate funding transaction before the channel can be considered open.
|
||||
// This is distinct from the main reservation workflow as it allows
|
||||
@@ -428,6 +445,15 @@ func (r *ChannelReservation) SetNumConfsRequired(numConfs uint16) {
|
||||
r.partialState.NumConfsRequired = numConfs
|
||||
}
|
||||
|
||||
// IsZeroConf returns if the reservation's underlying partial channel state is
|
||||
// a zero-conf channel.
|
||||
func (r *ChannelReservation) IsZeroConf() bool {
|
||||
r.RLock()
|
||||
defer r.RUnlock()
|
||||
|
||||
return r.partialState.IsZeroConf()
|
||||
}
|
||||
|
||||
// CommitConstraints takes the constraints that the remote party specifies for
|
||||
// the type of commitments that we can generate for them. These constraints
|
||||
// include several parameters that serve as flow control restricting the amount
|
||||
|
@@ -728,11 +728,17 @@ func testCancelNonExistentReservation(miner *rpctest.Harness,
|
||||
feePerKw, err := alice.Cfg.FeeEstimator.EstimateFeePerKW(1)
|
||||
require.NoError(t, err, "unable to query fee estimator")
|
||||
|
||||
req := &lnwallet.InitFundingReserveMsg{
|
||||
CommitFeePerKw: feePerKw,
|
||||
PushMSat: 10,
|
||||
Flags: lnwire.FFAnnounceChannel,
|
||||
CommitType: lnwallet.CommitmentTypeTweakless,
|
||||
PendingChanID: [32]byte{},
|
||||
}
|
||||
|
||||
// Create our own reservation, give it some ID.
|
||||
res, err := lnwallet.NewChannelReservation(
|
||||
10000, 10000, feePerKw, alice, 22, 10, &testHdSeed,
|
||||
lnwire.FFAnnounceChannel, lnwallet.CommitmentTypeTweakless,
|
||||
nil, [32]byte{}, 0,
|
||||
10000, 10000, alice, 22, &testHdSeed, 0, req,
|
||||
)
|
||||
require.NoError(t, err, "unable to create res")
|
||||
|
||||
|
@@ -153,6 +153,18 @@ type InitFundingReserveMsg struct {
|
||||
// used.
|
||||
ChanFunder chanfunding.Assembler
|
||||
|
||||
// ZeroConf is a boolean that is true if a zero-conf channel was
|
||||
// negotiated.
|
||||
ZeroConf bool
|
||||
|
||||
// OptionScidAlias is a boolean that is true if an option-scid-alias
|
||||
// channel type was explicitly negotiated.
|
||||
OptionScidAlias bool
|
||||
|
||||
// ScidAliasFeature is true if the option-scid-alias feature bit was
|
||||
// negotiated.
|
||||
ScidAliasFeature bool
|
||||
|
||||
// err is a channel in which all errors will be sent across. Will be
|
||||
// nil if this initial set is successful.
|
||||
//
|
||||
@@ -845,10 +857,8 @@ func (l *LightningWallet) handleFundingReserveRequest(req *InitFundingReserveMsg
|
||||
|
||||
id := atomic.AddUint64(&l.nextFundingID, 1)
|
||||
reservation, err := NewChannelReservation(
|
||||
capacity, localFundingAmt, req.CommitFeePerKw, l, id,
|
||||
req.PushMSat, l.Cfg.NetParams.GenesisHash, req.Flags,
|
||||
req.CommitType, req.ChanFunder, req.PendingChanID,
|
||||
thawHeight,
|
||||
capacity, localFundingAmt, l, id, l.Cfg.NetParams.GenesisHash,
|
||||
thawHeight, req,
|
||||
)
|
||||
if err != nil {
|
||||
fundingIntent.Cancel()
|
||||
|
Reference in New Issue
Block a user