Merge pull request #4840 from halseth/anchors-zero-fee-secondlevel
[anchors] zero-fee HTLC secondlevel transactions
This commit is contained in:
commit
d289a6ff78
@ -36,6 +36,10 @@ const (
|
|||||||
// implicitly denotes that this channel uses the new anchor commitment
|
// implicitly denotes that this channel uses the new anchor commitment
|
||||||
// format.
|
// format.
|
||||||
AnchorsCommitVersion = 2
|
AnchorsCommitVersion = 2
|
||||||
|
|
||||||
|
// AnchorsZeroFeeHtlcTxCommitVersion is a version that denotes this
|
||||||
|
// channel is using the zero-fee second-level anchor commitment format.
|
||||||
|
AnchorsZeroFeeHtlcTxCommitVersion = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
// Single is a static description of an existing channel that can be used for
|
// Single is a static description of an existing channel that can be used for
|
||||||
@ -163,6 +167,9 @@ func NewSingle(channel *channeldb.OpenChannel,
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
|
case channel.ChanType.ZeroHtlcTxFee():
|
||||||
|
single.Version = AnchorsZeroFeeHtlcTxCommitVersion
|
||||||
|
|
||||||
case channel.ChanType.HasAnchors():
|
case channel.ChanType.HasAnchors():
|
||||||
single.Version = AnchorsCommitVersion
|
single.Version = AnchorsCommitVersion
|
||||||
|
|
||||||
@ -185,6 +192,7 @@ func (s *Single) Serialize(w io.Writer) error {
|
|||||||
case DefaultSingleVersion:
|
case DefaultSingleVersion:
|
||||||
case TweaklessCommitVersion:
|
case TweaklessCommitVersion:
|
||||||
case AnchorsCommitVersion:
|
case AnchorsCommitVersion:
|
||||||
|
case AnchorsZeroFeeHtlcTxCommitVersion:
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unable to serialize w/ unknown "+
|
return fmt.Errorf("unable to serialize w/ unknown "+
|
||||||
"version: %v", s.Version)
|
"version: %v", s.Version)
|
||||||
@ -344,6 +352,7 @@ func (s *Single) Deserialize(r io.Reader) error {
|
|||||||
case DefaultSingleVersion:
|
case DefaultSingleVersion:
|
||||||
case TweaklessCommitVersion:
|
case TweaklessCommitVersion:
|
||||||
case AnchorsCommitVersion:
|
case AnchorsCommitVersion:
|
||||||
|
case AnchorsZeroFeeHtlcTxCommitVersion:
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unable to de-serialize w/ unknown "+
|
return fmt.Errorf("unable to de-serialize w/ unknown "+
|
||||||
"version: %v", s.Version)
|
"version: %v", s.Version)
|
||||||
|
@ -244,6 +244,10 @@ const (
|
|||||||
// that only the responder can decide to cooperatively close the
|
// that only the responder can decide to cooperatively close the
|
||||||
// channel.
|
// channel.
|
||||||
FrozenBit ChannelType = 1 << 4
|
FrozenBit ChannelType = 1 << 4
|
||||||
|
|
||||||
|
// ZeroHtlcTxFeeBit indicates that the channel should use zero-fee
|
||||||
|
// second-level HTLC transactions.
|
||||||
|
ZeroHtlcTxFeeBit ChannelType = 1 << 5
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsSingleFunder returns true if the channel type if one of the known single
|
// IsSingleFunder returns true if the channel type if one of the known single
|
||||||
@ -275,6 +279,12 @@ func (c ChannelType) HasAnchors() bool {
|
|||||||
return c&AnchorOutputsBit == AnchorOutputsBit
|
return c&AnchorOutputsBit == AnchorOutputsBit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ZeroHtlcTxFee returns true if this channel type uses second-level HTLC
|
||||||
|
// transactions signed with zero-fee.
|
||||||
|
func (c ChannelType) ZeroHtlcTxFee() bool {
|
||||||
|
return c&ZeroHtlcTxFeeBit == ZeroHtlcTxFeeBit
|
||||||
|
}
|
||||||
|
|
||||||
// IsFrozen returns true if the channel is considered to be "frozen". A frozen
|
// IsFrozen returns true if the channel is considered to be "frozen". A frozen
|
||||||
// channel means that only the responder can initiate a cooperative channel
|
// channel means that only the responder can initiate a cooperative channel
|
||||||
// closure.
|
// closure.
|
||||||
|
@ -110,6 +110,11 @@ func (c *chanDBRestorer) openChannelShell(backup chanbackup.Single) (
|
|||||||
chanType = channeldb.AnchorOutputsBit
|
chanType = channeldb.AnchorOutputsBit
|
||||||
chanType |= channeldb.SingleFunderTweaklessBit
|
chanType |= channeldb.SingleFunderTweaklessBit
|
||||||
|
|
||||||
|
case chanbackup.AnchorsZeroFeeHtlcTxCommitVersion:
|
||||||
|
chanType = channeldb.ZeroHtlcTxFeeBit
|
||||||
|
chanType |= channeldb.AnchorOutputsBit
|
||||||
|
chanType |= channeldb.SingleFunderTweaklessBit
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unknown Single version: %v", err)
|
return nil, fmt.Errorf("unknown Single version: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ var defaultSetDesc = setDesc{
|
|||||||
SetNodeAnn: {}, // N
|
SetNodeAnn: {}, // N
|
||||||
SetInvoice: {}, // 9
|
SetInvoice: {}, // 9
|
||||||
},
|
},
|
||||||
lnwire.AnchorsOptional: {
|
lnwire.AnchorsZeroFeeHtlcTxOptional: {
|
||||||
SetInit: {}, // I
|
SetInit: {}, // I
|
||||||
SetNodeAnn: {}, // N
|
SetNodeAnn: {}, // N
|
||||||
},
|
},
|
||||||
|
@ -83,8 +83,8 @@ func newManager(cfg Config, desc setDesc) (*Manager, error) {
|
|||||||
raw.Unset(lnwire.StaticRemoteKeyRequired)
|
raw.Unset(lnwire.StaticRemoteKeyRequired)
|
||||||
}
|
}
|
||||||
if cfg.NoAnchors {
|
if cfg.NoAnchors {
|
||||||
raw.Unset(lnwire.AnchorsOptional)
|
raw.Unset(lnwire.AnchorsZeroFeeHtlcTxOptional)
|
||||||
raw.Unset(lnwire.AnchorsRequired)
|
raw.Unset(lnwire.AnchorsZeroFeeHtlcTxRequired)
|
||||||
}
|
}
|
||||||
if cfg.NoWumbo {
|
if cfg.NoWumbo {
|
||||||
raw.Unset(lnwire.WumboChannelsOptional)
|
raw.Unset(lnwire.WumboChannelsOptional)
|
||||||
|
@ -1137,20 +1137,21 @@ func (f *fundingManager) ProcessFundingMsg(msg lnwire.Message, peer lnpeer.Peer)
|
|||||||
func commitmentType(localFeatures,
|
func commitmentType(localFeatures,
|
||||||
remoteFeatures *lnwire.FeatureVector) lnwallet.CommitmentType {
|
remoteFeatures *lnwire.FeatureVector) lnwallet.CommitmentType {
|
||||||
|
|
||||||
// If both peers are signalling support for anchor commitments, this
|
// If both peers are signalling support for anchor commitments with
|
||||||
// implicitly mean we'll create the channel of this type. Note that
|
// zero-fee HTLC transactions, we'll use this type.
|
||||||
// this also enables tweakless commitments, as anchor commitments are
|
localZeroFee := localFeatures.HasFeature(
|
||||||
// always tweakless.
|
lnwire.AnchorsZeroFeeHtlcTxOptional,
|
||||||
localAnchors := localFeatures.HasFeature(
|
|
||||||
lnwire.AnchorsOptional,
|
|
||||||
)
|
)
|
||||||
remoteAnchors := remoteFeatures.HasFeature(
|
remoteZeroFee := remoteFeatures.HasFeature(
|
||||||
lnwire.AnchorsOptional,
|
lnwire.AnchorsZeroFeeHtlcTxOptional,
|
||||||
)
|
)
|
||||||
if localAnchors && remoteAnchors {
|
if localZeroFee && remoteZeroFee {
|
||||||
return lnwallet.CommitmentTypeAnchors
|
return lnwallet.CommitmentTypeAnchorsZeroFeeHtlcTx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Since we don't want to support the "legacy" anchor type, we will
|
||||||
|
// fall back to static remote key if the nodes don't support the zero
|
||||||
|
// fee HTLC tx anchor type.
|
||||||
localTweakless := localFeatures.HasFeature(
|
localTweakless := localFeatures.HasFeature(
|
||||||
lnwire.StaticRemoteKeyOptional,
|
lnwire.StaticRemoteKeyOptional,
|
||||||
)
|
)
|
||||||
@ -1306,10 +1307,9 @@ func (f *fundingManager) handleFundingOpen(peer lnpeer.Peer,
|
|||||||
// responding side of a single funder workflow, we don't commit any
|
// responding side of a single funder workflow, we don't commit any
|
||||||
// funds to the channel ourselves.
|
// funds to the channel ourselves.
|
||||||
//
|
//
|
||||||
// Before we init the channel, we'll also check to see if we've
|
// Before we init the channel, we'll also check to see what commitment
|
||||||
// negotiated the new tweakless commitment format. This is only the
|
// format we can use with this peer. This is dependent on *both* us and
|
||||||
// case if *both* us and the remote peer are signaling the proper
|
// the remote peer are signaling the proper feature bit.
|
||||||
// feature bit.
|
|
||||||
commitType := commitmentType(
|
commitType := commitmentType(
|
||||||
peer.LocalFeatures(), peer.RemoteFeatures(),
|
peer.LocalFeatures(), peer.RemoteFeatures(),
|
||||||
)
|
)
|
||||||
@ -3116,7 +3116,6 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) {
|
|||||||
case chainreg.LitecoinChain:
|
case chainreg.LitecoinChain:
|
||||||
ourDustLimit = chainreg.DefaultLitecoinDustLimit
|
ourDustLimit = chainreg.DefaultLitecoinDustLimit
|
||||||
}
|
}
|
||||||
|
|
||||||
fndgLog.Infof("Initiating fundingRequest(local_amt=%v "+
|
fndgLog.Infof("Initiating fundingRequest(local_amt=%v "+
|
||||||
"(subtract_fees=%v), push_amt=%v, chain_hash=%v, peer=%x, "+
|
"(subtract_fees=%v), push_amt=%v, chain_hash=%v, peer=%x, "+
|
||||||
"dust_limit=%v, min_confs=%v)", localAmt, msg.subtractFees,
|
"dust_limit=%v, min_confs=%v)", localAmt, msg.subtractFees,
|
||||||
@ -3185,10 +3184,9 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) {
|
|||||||
// wallet doesn't have enough funds to commit to this channel, then the
|
// wallet doesn't have enough funds to commit to this channel, then the
|
||||||
// request will fail, and be aborted.
|
// request will fail, and be aborted.
|
||||||
//
|
//
|
||||||
// Before we init the channel, we'll also check to see if we've
|
// Before we init the channel, we'll also check to see what commitment
|
||||||
// negotiated the new tweakless commitment format. This is only the
|
// format we can use with this peer. This is dependent on *both* us and
|
||||||
// case if *both* us and the remote peer are signaling the proper
|
// the remote peer are signaling the proper feature bit.
|
||||||
// feature bit.
|
|
||||||
commitType := commitmentType(
|
commitType := commitmentType(
|
||||||
msg.peer.LocalFeatures(), msg.peer.RemoteFeatures(),
|
msg.peer.LocalFeatures(), msg.peer.RemoteFeatures(),
|
||||||
)
|
)
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// +build !rpctest
|
||||||
|
|
||||||
package lncfg
|
package lncfg
|
||||||
|
|
||||||
// ProtocolOptions is a struct that we use to be able to test backwards
|
// ProtocolOptions is a struct that we use to be able to test backwards
|
||||||
@ -17,6 +19,10 @@ type ProtocolOptions struct {
|
|||||||
// (channels larger than 0.16 BTC) channels, which is the opposite of
|
// (channels larger than 0.16 BTC) channels, which is the opposite of
|
||||||
// mini.
|
// mini.
|
||||||
WumboChans bool `long:"wumbo-channels" description:"if set, then lnd will create and accept requests for channels larger chan 0.16 BTC"`
|
WumboChans bool `long:"wumbo-channels" description:"if set, then lnd will create and accept requests for channels larger chan 0.16 BTC"`
|
||||||
|
|
||||||
|
// NoAnchors should be set if we don't want to support opening or accepting
|
||||||
|
// channels having the anchor commitment type.
|
||||||
|
NoAnchors bool `long:"no-anchors" description:"disable support for anchor commitments"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wumbo returns true if lnd should permit the creation and acceptance of wumbo
|
// Wumbo returns true if lnd should permit the creation and acceptance of wumbo
|
||||||
@ -24,3 +30,9 @@ type ProtocolOptions struct {
|
|||||||
func (l *ProtocolOptions) Wumbo() bool {
|
func (l *ProtocolOptions) Wumbo() bool {
|
||||||
return l.WumboChans
|
return l.WumboChans
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NoAnchorCommitments returns true if we have disabled support for the anchor
|
||||||
|
// commitment type.
|
||||||
|
func (l *ProtocolOptions) NoAnchorCommitments() bool {
|
||||||
|
return l.NoAnchors
|
||||||
|
}
|
||||||
|
@ -6,9 +6,3 @@ package lncfg
|
|||||||
// features that also require a build-tag to activate.
|
// features that also require a build-tag to activate.
|
||||||
type ExperimentalProtocol struct {
|
type ExperimentalProtocol struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// AnchorCommitments returns true if support for the anchor commitment type
|
|
||||||
// should be signaled.
|
|
||||||
func (l *ExperimentalProtocol) AnchorCommitments() bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
@ -5,13 +5,4 @@ package lncfg
|
|||||||
// ExperimentalProtocol is a sub-config that houses any experimental protocol
|
// ExperimentalProtocol is a sub-config that houses any experimental protocol
|
||||||
// features that also require a build-tag to activate.
|
// features that also require a build-tag to activate.
|
||||||
type ExperimentalProtocol struct {
|
type ExperimentalProtocol struct {
|
||||||
// Anchors should be set if we want to support opening or accepting
|
|
||||||
// channels having the anchor commitment type.
|
|
||||||
Anchors bool `long:"anchors" description:"EXPERIMENTAL: enable experimental support for anchor commitments, won't work with watchtowers"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// AnchorCommitments returns true if support for the anchor commitment type
|
|
||||||
// should be signaled.
|
|
||||||
func (l *ExperimentalProtocol) AnchorCommitments() bool {
|
|
||||||
return l.Anchors
|
|
||||||
}
|
}
|
||||||
|
38
lncfg/protocol_rpctest.go
Normal file
38
lncfg/protocol_rpctest.go
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// +build rpctest
|
||||||
|
|
||||||
|
package lncfg
|
||||||
|
|
||||||
|
// ProtocolOptions is a struct that we use to be able to test backwards
|
||||||
|
// compatibility of protocol additions, while defaulting to the latest within
|
||||||
|
// lnd, or to enable experimental protocol changes.
|
||||||
|
type ProtocolOptions struct {
|
||||||
|
// LegacyProtocol is a sub-config that houses all the legacy protocol
|
||||||
|
// options. These are mostly used for integration tests as most modern
|
||||||
|
// nodes shuld always run with them on by default.
|
||||||
|
LegacyProtocol `group:"legacy" namespace:"legacy"`
|
||||||
|
|
||||||
|
// ExperimentalProtocol is a sub-config that houses any experimental
|
||||||
|
// protocol features that also require a build-tag to activate.
|
||||||
|
ExperimentalProtocol
|
||||||
|
|
||||||
|
// WumboChans should be set if we want to enable support for wumbo
|
||||||
|
// (channels larger than 0.16 BTC) channels, which is the opposite of
|
||||||
|
// mini.
|
||||||
|
WumboChans bool `long:"wumbo-channels" description:"if set, then lnd will create and accept requests for channels larger chan 0.16 BTC"`
|
||||||
|
|
||||||
|
// Anchors enables anchor commitments.
|
||||||
|
// TODO(halseth): transition itests to anchors instead!
|
||||||
|
Anchors bool `long:"anchors" description:"enable support for anchor commitments"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wumbo returns true if lnd should permit the creation and acceptance of wumbo
|
||||||
|
// channels.
|
||||||
|
func (l *ProtocolOptions) Wumbo() bool {
|
||||||
|
return l.WumboChans
|
||||||
|
}
|
||||||
|
|
||||||
|
// NoAnchorCommitments returns true if we have disabled support for the anchor
|
||||||
|
// commitment type.
|
||||||
|
func (l *ProtocolOptions) NoAnchorCommitments() bool {
|
||||||
|
return !l.Anchors
|
||||||
|
}
|
@ -278,6 +278,12 @@ func CommitWeight(chanType channeldb.ChannelType) int64 {
|
|||||||
func HtlcTimeoutFee(chanType channeldb.ChannelType,
|
func HtlcTimeoutFee(chanType channeldb.ChannelType,
|
||||||
feePerKw chainfee.SatPerKWeight) btcutil.Amount {
|
feePerKw chainfee.SatPerKWeight) btcutil.Amount {
|
||||||
|
|
||||||
|
// For zero-fee HTLC channels, this will always be zero, regardless of
|
||||||
|
// feerate.
|
||||||
|
if chanType.ZeroHtlcTxFee() {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
if chanType.HasAnchors() {
|
if chanType.HasAnchors() {
|
||||||
return feePerKw.FeeForWeight(input.HtlcTimeoutWeightConfirmed)
|
return feePerKw.FeeForWeight(input.HtlcTimeoutWeightConfirmed)
|
||||||
}
|
}
|
||||||
@ -290,6 +296,12 @@ func HtlcTimeoutFee(chanType channeldb.ChannelType,
|
|||||||
func HtlcSuccessFee(chanType channeldb.ChannelType,
|
func HtlcSuccessFee(chanType channeldb.ChannelType,
|
||||||
feePerKw chainfee.SatPerKWeight) btcutil.Amount {
|
feePerKw chainfee.SatPerKWeight) btcutil.Amount {
|
||||||
|
|
||||||
|
// For zero-fee HTLC channels, this will always be zero, regardless of
|
||||||
|
// feerate.
|
||||||
|
if chanType.ZeroHtlcTxFee() {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
if chanType.HasAnchors() {
|
if chanType.HasAnchors() {
|
||||||
return feePerKw.FeeForWeight(input.HtlcSuccessWeightConfirmed)
|
return feePerKw.FeeForWeight(input.HtlcSuccessWeightConfirmed)
|
||||||
}
|
}
|
||||||
|
@ -28,10 +28,11 @@ const (
|
|||||||
// to_remote key is static.
|
// to_remote key is static.
|
||||||
CommitmentTypeTweakless
|
CommitmentTypeTweakless
|
||||||
|
|
||||||
// CommitmentTypeAnchors is a commitment type that is tweakless, and
|
// CommitmentTypeAnchorsZeroFeeHtlcTx is a commitment type that is an
|
||||||
// has extra anchor ouputs in order to bump the fee of the commitment
|
// extension of the outdated CommitmentTypeAnchors, which in addition
|
||||||
// transaction.
|
// requires second-level HTLC transactions to be signed using a
|
||||||
CommitmentTypeAnchors
|
// zero-fee.
|
||||||
|
CommitmentTypeAnchorsZeroFeeHtlcTx
|
||||||
)
|
)
|
||||||
|
|
||||||
// String returns the name of the CommitmentType.
|
// String returns the name of the CommitmentType.
|
||||||
@ -41,8 +42,8 @@ func (c CommitmentType) String() string {
|
|||||||
return "legacy"
|
return "legacy"
|
||||||
case CommitmentTypeTweakless:
|
case CommitmentTypeTweakless:
|
||||||
return "tweakless"
|
return "tweakless"
|
||||||
case CommitmentTypeAnchors:
|
case CommitmentTypeAnchorsZeroFeeHtlcTx:
|
||||||
return "anchors"
|
return "anchors-zero-fee-second-level"
|
||||||
default:
|
default:
|
||||||
return "invalid"
|
return "invalid"
|
||||||
}
|
}
|
||||||
@ -182,7 +183,7 @@ func NewChannelReservation(capacity, localFundingAmt btcutil.Amount,
|
|||||||
// Based on the channel type, we determine the initial commit weight
|
// Based on the channel type, we determine the initial commit weight
|
||||||
// and fee.
|
// and fee.
|
||||||
commitWeight := int64(input.CommitWeight)
|
commitWeight := int64(input.CommitWeight)
|
||||||
if commitType == CommitmentTypeAnchors {
|
if commitType == CommitmentTypeAnchorsZeroFeeHtlcTx {
|
||||||
commitWeight = input.AnchorCommitWeight
|
commitWeight = input.AnchorCommitWeight
|
||||||
}
|
}
|
||||||
commitFee := commitFeePerKw.FeeForWeight(commitWeight)
|
commitFee := commitFeePerKw.FeeForWeight(commitWeight)
|
||||||
@ -195,7 +196,7 @@ func NewChannelReservation(capacity, localFundingAmt btcutil.Amount,
|
|||||||
// The total fee paid by the initiator will be the commitment fee in
|
// The total fee paid by the initiator will be the commitment fee in
|
||||||
// addition to the two anchor outputs.
|
// addition to the two anchor outputs.
|
||||||
feeMSat := lnwire.NewMSatFromSatoshis(commitFee)
|
feeMSat := lnwire.NewMSatFromSatoshis(commitFee)
|
||||||
if commitType == CommitmentTypeAnchors {
|
if commitType == CommitmentTypeAnchorsZeroFeeHtlcTx {
|
||||||
feeMSat += 2 * lnwire.NewMSatFromSatoshis(anchorSize)
|
feeMSat += 2 * lnwire.NewMSatFromSatoshis(anchorSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,8 +281,7 @@ func NewChannelReservation(capacity, localFundingAmt btcutil.Amount,
|
|||||||
// Both the tweakless type and the anchor type is tweakless,
|
// Both the tweakless type and the anchor type is tweakless,
|
||||||
// hence set the bit.
|
// hence set the bit.
|
||||||
if commitType == CommitmentTypeTweakless ||
|
if commitType == CommitmentTypeTweakless ||
|
||||||
commitType == CommitmentTypeAnchors {
|
commitType == CommitmentTypeAnchorsZeroFeeHtlcTx {
|
||||||
|
|
||||||
chanType |= channeldb.SingleFunderTweaklessBit
|
chanType |= channeldb.SingleFunderTweaklessBit
|
||||||
} else {
|
} else {
|
||||||
chanType |= channeldb.SingleFunderBit
|
chanType |= channeldb.SingleFunderBit
|
||||||
@ -315,9 +315,11 @@ func NewChannelReservation(capacity, localFundingAmt btcutil.Amount,
|
|||||||
chanType |= channeldb.DualFunderBit
|
chanType |= channeldb.DualFunderBit
|
||||||
}
|
}
|
||||||
|
|
||||||
// We are adding anchor outputs to our commitment.
|
// We are adding anchor outputs to our commitment. We only support this
|
||||||
if commitType == CommitmentTypeAnchors {
|
// in combination with zero-fee second-levels HTLCs.
|
||||||
|
if commitType == CommitmentTypeAnchorsZeroFeeHtlcTx {
|
||||||
chanType |= channeldb.AnchorOutputsBit
|
chanType |= channeldb.AnchorOutputsBit
|
||||||
|
chanType |= channeldb.ZeroHtlcTxFeeBit
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the channel is meant to be frozen, then we'll set the frozen bit
|
// If the channel is meant to be frozen, then we'll set the frozen bit
|
||||||
|
@ -119,6 +119,16 @@ const (
|
|||||||
// outputs.
|
// outputs.
|
||||||
AnchorsOptional FeatureBit = 21
|
AnchorsOptional FeatureBit = 21
|
||||||
|
|
||||||
|
// AnchorsZeroFeeHtlcTxRequired is a required feature bit that signals
|
||||||
|
// that the node requires channels having zero-fee second-level HTLC
|
||||||
|
// transactions, which also imply anchor commitments.
|
||||||
|
AnchorsZeroFeeHtlcTxRequired FeatureBit = 22
|
||||||
|
|
||||||
|
// AnchorsZeroFeeHtlcTxRequired is an optional feature bit that signals
|
||||||
|
// that the node supports channels having zero-fee second-level HTLC
|
||||||
|
// transactions, which also imply anchor commitments.
|
||||||
|
AnchorsZeroFeeHtlcTxOptional FeatureBit = 23
|
||||||
|
|
||||||
// maxAllowedSize is a maximum allowed size of feature vector.
|
// maxAllowedSize is a maximum allowed size of feature vector.
|
||||||
//
|
//
|
||||||
// NOTE: Within the protocol, the maximum allowed message size is 65535
|
// NOTE: Within the protocol, the maximum allowed message size is 65535
|
||||||
@ -158,6 +168,8 @@ var Features = map[FeatureBit]string{
|
|||||||
MPPRequired: "multi-path-payments",
|
MPPRequired: "multi-path-payments",
|
||||||
AnchorsRequired: "anchor-commitments",
|
AnchorsRequired: "anchor-commitments",
|
||||||
AnchorsOptional: "anchor-commitments",
|
AnchorsOptional: "anchor-commitments",
|
||||||
|
AnchorsZeroFeeHtlcTxRequired: "anchors-zero-fee-htlc-tx",
|
||||||
|
AnchorsZeroFeeHtlcTxOptional: "anchors-zero-fee-htlc-tx",
|
||||||
WumboChannelsRequired: "wumbo-channels",
|
WumboChannelsRequired: "wumbo-channels",
|
||||||
WumboChannelsOptional: "wumbo-channels",
|
WumboChannelsOptional: "wumbo-channels",
|
||||||
}
|
}
|
||||||
|
@ -938,8 +938,8 @@ litecoin.node=ltcd
|
|||||||
; BTC
|
; BTC
|
||||||
; protocol.wumbo-channels=true
|
; protocol.wumbo-channels=true
|
||||||
|
|
||||||
; Set to enable experimental support for anchor commitments, won't work with watchtowers yet.
|
; Set to disable support for anchor commitments
|
||||||
; protocol.anchors=true
|
; protocol.no-anchors=true
|
||||||
|
|
||||||
[db]
|
[db]
|
||||||
; The selected database backend. The current default backend is "bolt". lnd
|
; The selected database backend. The current default backend is "bolt". lnd
|
||||||
|
@ -404,7 +404,7 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
|
|||||||
featureMgr, err := feature.NewManager(feature.Config{
|
featureMgr, err := feature.NewManager(feature.Config{
|
||||||
NoTLVOnion: cfg.ProtocolOptions.LegacyOnion(),
|
NoTLVOnion: cfg.ProtocolOptions.LegacyOnion(),
|
||||||
NoStaticRemoteKey: cfg.ProtocolOptions.NoStaticRemoteKey(),
|
NoStaticRemoteKey: cfg.ProtocolOptions.NoStaticRemoteKey(),
|
||||||
NoAnchors: !cfg.ProtocolOptions.AnchorCommitments(),
|
NoAnchors: cfg.ProtocolOptions.NoAnchorCommitments(),
|
||||||
NoWumbo: !cfg.ProtocolOptions.Wumbo(),
|
NoWumbo: !cfg.ProtocolOptions.Wumbo(),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user