Merge pull request #10367 from elnosh/rename-endorsement-accountable

multi: rename experimental endorsement signal to accountable
This commit is contained in:
ziggieXXX authored and GitHub committed 2026-01-06 18:02:22 +01:00
commit 99d07fdb78
22 files changed
+222 -272

No files matched your search

@@ -75,6 +75,10 @@
This applies to both funders and fundees, with the ability to override the This applies to both funders and fundees, with the ability to override the
value during channel opening or acceptance. value during channel opening or acceptance.
* Rename [experimental endorsement signal](https://github.com/lightning/blips/blob/a833e7b49f224e1240b5d669e78fa950160f5a06/blip-0004.md)
to [accountable](https://github.com/lightningnetwork/lnd/pull/10367) to match
the latest [proposal](https://github.com/lightning/blips/pull/67).
## RPC Updates ## RPC Updates
## lncli Updates ## lncli Updates
+1 -1
View File
@@ -100,7 +100,7 @@ var defaultSetDesc = setDesc{
SetInit: {}, // I SetInit: {}, // I
SetNodeAnn: {}, // N SetNodeAnn: {}, // N
}, },
lnwire.ExperimentalEndorsementOptional: { lnwire.ExperimentalAccountabilityOptional: {
SetNodeAnn: {}, // N SetNodeAnn: {}, // N
}, },
lnwire.RbfCoopCloseOptionalStaging: { lnwire.RbfCoopCloseOptionalStaging: {
+6 -6
View File
@@ -69,9 +69,9 @@ type Config struct {
// NoTaprootOverlay unsets the taproot overlay channel feature bits. // NoTaprootOverlay unsets the taproot overlay channel feature bits.
NoTaprootOverlay bool NoTaprootOverlay bool
// NoExperimentalEndorsement unsets any bits that signal support for // NoExperimentalAccountability unsets any bits that signal support for
// forwarding experimental endorsement. // forwarding experimental accountability.
NoExperimentalEndorsement bool NoExperimentalAccountability bool
// NoRbfCoopClose unsets any bits that signal support for using RBF for // NoRbfCoopClose unsets any bits that signal support for using RBF for
// coop close. // coop close.
@@ -213,9 +213,9 @@ func newManager(cfg Config, desc setDesc) (*Manager, error) {
raw.Unset(lnwire.SimpleTaprootOverlayChansOptional) raw.Unset(lnwire.SimpleTaprootOverlayChansOptional)
raw.Unset(lnwire.SimpleTaprootOverlayChansRequired) raw.Unset(lnwire.SimpleTaprootOverlayChansRequired)
} }
if cfg.NoExperimentalEndorsement { if cfg.NoExperimentalAccountability {
raw.Unset(lnwire.ExperimentalEndorsementOptional) raw.Unset(lnwire.ExperimentalAccountabilityOptional)
raw.Unset(lnwire.ExperimentalEndorsementRequired) raw.Unset(lnwire.ExperimentalAccountabilityRequired)
} }
if cfg.NoRbfCoopClose { if cfg.NoRbfCoopClose {
raw.Unset(lnwire.RbfCoopCloseOptionalStaging) raw.Unset(lnwire.RbfCoopCloseOptionalStaging)
+24 -26
View File
@@ -290,9 +290,9 @@ type ChannelLinkConfig struct {
// restrict the flow of HTLCs and fee updates. // restrict the flow of HTLCs and fee updates.
MaxFeeExposure lnwire.MilliSatoshi MaxFeeExposure lnwire.MilliSatoshi
// ShouldFwdExpEndorsement is a closure that indicates whether the link // ShouldFwdExpAccountability is a closure that indicates whether the
// should forward experimental endorsement signals. // link should forward experimental accountability signals.
ShouldFwdExpEndorsement func() bool ShouldFwdExpAccountability func() bool
// AuxTrafficShaper is an optional auxiliary traffic shaper that can be // AuxTrafficShaper is an optional auxiliary traffic shaper that can be
// used to manage the bandwidth of the link. // used to manage the bandwidth of the link.
@@ -3163,11 +3163,11 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg) {
continue continue
} }
endorseValue := l.experimentalEndorsement( accountableValue := l.experimentalAccountability(
record.CustomSet(add.CustomRecords), record.CustomSet(add.CustomRecords),
) )
endorseType := uint64( accountableType := uint64(
lnwire.ExperimentalEndorsementType, lnwire.ExperimentalAccountableType,
) )
switch fwdPkg.State { switch fwdPkg.State {
@@ -3191,9 +3191,9 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg) {
BlindingPoint: fwdInfo.NextBlinding, BlindingPoint: fwdInfo.NextBlinding,
} }
endorseValue.WhenSome(func(e byte) { accountableValue.WhenSome(func(e byte) {
custRecords := map[uint64][]byte{ custRecords := map[uint64][]byte{
endorseType: {e}, accountableType: {e},
} }
outgoingAdd.CustomRecords = custRecords outgoingAdd.CustomRecords = custRecords
@@ -3249,9 +3249,9 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg) {
BlindingPoint: fwdInfo.NextBlinding, BlindingPoint: fwdInfo.NextBlinding,
} }
endorseValue.WhenSome(func(e byte) { accountableValue.WhenSome(func(e byte) {
addMsg.CustomRecords = map[uint64][]byte{ addMsg.CustomRecords = map[uint64][]byte{
endorseType: {e}, accountableType: {e},
} }
}) })
@@ -3340,44 +3340,42 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg) {
l.forwardBatch(reforward, switchPackets...) l.forwardBatch(reforward, switchPackets...)
} }
// experimentalEndorsement returns the value to set for our outgoing // experimentalAccountability returns the value to set for our outgoing
// experimental endorsement field, and a boolean indicating whether it should // experimental accountable field. It only considers the accountability bit,
// be populated on the outgoing htlc. // other custom records present are not considered for forwarding.
func (l *channelLink) experimentalEndorsement( func (l *channelLink) experimentalAccountability(
customUpdateAdd record.CustomSet) fn.Option[byte] { customUpdateAdd record.CustomSet) fn.Option[byte] {
// Only relay experimental signal if we are within the experiment if !l.cfg.ShouldFwdExpAccountability() {
// period.
if !l.cfg.ShouldFwdExpEndorsement() {
return fn.None[byte]() return fn.None[byte]()
} }
// If we don't have any custom records or the experimental field is // If we don't have any custom records or the experimental field is
// not set, just forward a zero value. // not set, just forward a zero value.
if len(customUpdateAdd) == 0 { if len(customUpdateAdd) == 0 {
return fn.Some[byte](lnwire.ExperimentalUnendorsed) return fn.Some[byte](lnwire.ExperimentalUnaccountable)
} }
t := uint64(lnwire.ExperimentalEndorsementType) t := uint64(lnwire.ExperimentalAccountableType)
value, set := customUpdateAdd[t] value, set := customUpdateAdd[t]
if !set { if !set {
return fn.Some[byte](lnwire.ExperimentalUnendorsed) return fn.Some[byte](lnwire.ExperimentalUnaccountable)
} }
// We expect at least one byte for this field, consider it invalid if // We expect at least one byte for this field, consider it invalid if
// it has no data and just forward a zero value. // it has no data and just forward a zero value.
if len(value) == 0 { if len(value) == 0 {
return fn.Some[byte](lnwire.ExperimentalUnendorsed) return fn.Some[byte](lnwire.ExperimentalUnaccountable)
} }
// Only forward endorsed if the incoming link is endorsed. // Only forward accountable if the incoming link is accountable.
if value[0] == lnwire.ExperimentalEndorsed { if value[0] == lnwire.ExperimentalAccountable {
return fn.Some[byte](lnwire.ExperimentalEndorsed) return fn.Some[byte](lnwire.ExperimentalAccountable)
} }
// Forward as unendorsed otherwise, including cases where we've // Forward as unaccountable otherwise, including cases where we've
// received an invalid value that uses more than 3 bits of information. // received an invalid value that uses more than 3 bits of information.
return fn.Some[byte](lnwire.ExperimentalUnendorsed) return fn.Some[byte](lnwire.ExperimentalUnaccountable)
} }
// processExitHop handles an htlc for which this link is the exit hop. It // processExitHop handles an htlc for which this link is the exit hop. It
+23 -23
View File
@@ -2234,18 +2234,18 @@ func newSingleLinkTestHarness(t *testing.T, chanAmt,
PendingCommitTicker: ticker.New(time.Minute), PendingCommitTicker: ticker.New(time.Minute),
// Make the BatchSize and Min/MaxUpdateTimeout large enough // Make the BatchSize and Min/MaxUpdateTimeout large enough
// to not trigger commit updates automatically during tests. // to not trigger commit updates automatically during tests.
BatchSize: 10000, BatchSize: 10000,
MinUpdateTimeout: 30 * time.Minute, MinUpdateTimeout: 30 * time.Minute,
MaxUpdateTimeout: 40 * time.Minute, MaxUpdateTimeout: 40 * time.Minute,
MaxOutgoingCltvExpiry: DefaultMaxOutgoingCltvExpiry, MaxOutgoingCltvExpiry: DefaultMaxOutgoingCltvExpiry,
MaxFeeAllocation: DefaultMaxLinkFeeAllocation, MaxFeeAllocation: DefaultMaxLinkFeeAllocation,
NotifyActiveLink: func(wire.OutPoint) {}, NotifyActiveLink: func(wire.OutPoint) {},
NotifyActiveChannel: func(wire.OutPoint) {}, NotifyActiveChannel: func(wire.OutPoint) {},
NotifyInactiveChannel: func(wire.OutPoint) {}, NotifyInactiveChannel: func(wire.OutPoint) {},
NotifyInactiveLinkEvent: func(wire.OutPoint) {}, NotifyInactiveLinkEvent: func(wire.OutPoint) {},
HtlcNotifier: aliceSwitch.cfg.HtlcNotifier, HtlcNotifier: aliceSwitch.cfg.HtlcNotifier,
GetAliases: getAliases, GetAliases: getAliases,
ShouldFwdExpEndorsement: func() bool { return true }, ShouldFwdExpAccountability: func() bool { return true },
} }
aliceLink := NewChannelLink(aliceCfg, aliceLc.channel) aliceLink := NewChannelLink(aliceCfg, aliceLc.channel)
@@ -4924,17 +4924,17 @@ func (h *persistentLinkHarness) restartLink(
MinUpdateTimeout: 30 * time.Minute, MinUpdateTimeout: 30 * time.Minute,
MaxUpdateTimeout: 40 * time.Minute, MaxUpdateTimeout: 40 * time.Minute,
// Set any hodl flags requested for the new link. // Set any hodl flags requested for the new link.
HodlMask: hodl.MaskFromFlags(hodlFlags...), HodlMask: hodl.MaskFromFlags(hodlFlags...),
MaxOutgoingCltvExpiry: DefaultMaxOutgoingCltvExpiry, MaxOutgoingCltvExpiry: DefaultMaxOutgoingCltvExpiry,
MaxFeeAllocation: DefaultMaxLinkFeeAllocation, MaxFeeAllocation: DefaultMaxLinkFeeAllocation,
NotifyActiveLink: func(wire.OutPoint) {}, NotifyActiveLink: func(wire.OutPoint) {},
NotifyActiveChannel: func(wire.OutPoint) {}, NotifyActiveChannel: func(wire.OutPoint) {},
NotifyInactiveChannel: func(wire.OutPoint) {}, NotifyInactiveChannel: func(wire.OutPoint) {},
NotifyInactiveLinkEvent: func(wire.OutPoint) {}, NotifyInactiveLinkEvent: func(wire.OutPoint) {},
HtlcNotifier: h.hSwitch.cfg.HtlcNotifier, HtlcNotifier: h.hSwitch.cfg.HtlcNotifier,
SyncStates: syncStates, SyncStates: syncStates,
GetAliases: getAliases, GetAliases: getAliases,
ShouldFwdExpEndorsement: func() bool { return true }, ShouldFwdExpAccountability: func() bool { return true },
} }
aliceLink := NewChannelLink(aliceCfg, aliceChannel) aliceLink := NewChannelLink(aliceCfg, aliceChannel)
+21 -21
View File
@@ -1157,27 +1157,27 @@ func (h *hopNetwork) createChannelLink(server, peer *mockServer,
UpdateContractSignals: func(*contractcourt.ContractSignals) error { UpdateContractSignals: func(*contractcourt.ContractSignals) error {
return nil return nil
}, },
NotifyContractUpdate: notifyContractUpdate, NotifyContractUpdate: notifyContractUpdate,
ChainEvents: &contractcourt.ChainEventSubscription{}, ChainEvents: &contractcourt.ChainEventSubscription{},
SyncStates: true, SyncStates: true,
BatchSize: 10, BatchSize: 10,
BatchTicker: ticker.NewForce(testBatchTimeout), BatchTicker: ticker.NewForce(testBatchTimeout),
FwdPkgGCTicker: ticker.NewForce(fwdPkgTimeout), FwdPkgGCTicker: ticker.NewForce(fwdPkgTimeout),
PendingCommitTicker: ticker.New(2 * time.Minute), PendingCommitTicker: ticker.New(2 * time.Minute),
MinUpdateTimeout: minFeeUpdateTimeout, MinUpdateTimeout: minFeeUpdateTimeout,
MaxUpdateTimeout: maxFeeUpdateTimeout, MaxUpdateTimeout: maxFeeUpdateTimeout,
OnChannelFailure: func(lnwire.ChannelID, lnwire.ShortChannelID, LinkFailureError) {}, OnChannelFailure: func(lnwire.ChannelID, lnwire.ShortChannelID, LinkFailureError) {},
OutgoingCltvRejectDelta: 3, OutgoingCltvRejectDelta: 3,
MaxOutgoingCltvExpiry: DefaultMaxOutgoingCltvExpiry, MaxOutgoingCltvExpiry: DefaultMaxOutgoingCltvExpiry,
MaxFeeAllocation: DefaultMaxLinkFeeAllocation, MaxFeeAllocation: DefaultMaxLinkFeeAllocation,
MaxAnchorsCommitFeeRate: chainfee.SatPerKVByte(10 * 1000).FeePerKWeight(), MaxAnchorsCommitFeeRate: chainfee.SatPerKVByte(10 * 1000).FeePerKWeight(),
NotifyActiveLink: func(wire.OutPoint) {}, NotifyActiveLink: func(wire.OutPoint) {},
NotifyActiveChannel: func(wire.OutPoint) {}, NotifyActiveChannel: func(wire.OutPoint) {},
NotifyInactiveChannel: func(wire.OutPoint) {}, NotifyInactiveChannel: func(wire.OutPoint) {},
NotifyInactiveLinkEvent: func(wire.OutPoint) {}, NotifyInactiveLinkEvent: func(wire.OutPoint) {},
HtlcNotifier: server.htlcSwitch.cfg.HtlcNotifier, HtlcNotifier: server.htlcSwitch.cfg.HtlcNotifier,
GetAliases: getAliases, GetAliases: getAliases,
ShouldFwdExpEndorsement: func() bool { return true }, ShouldFwdExpAccountability: func() bool { return true },
}, },
channel, channel,
) )
+2 -2
View File
@@ -700,8 +700,8 @@ var allTestCases = []*lntest.TestCase{
TestFunc: testDebuglevelShow, TestFunc: testDebuglevelShow,
}, },
{ {
Name: "experimental endorsement", Name: "experimental accountability",
TestFunc: testExperimentalEndorsement, TestFunc: testExperimentalAccountability,
}, },
{ {
Name: "quiescence", Name: "quiescence",
@@ -15,19 +15,19 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
// testExperimentalEndorsement tests setting of positive and negative // testExperimentalAccountability tests setting of positive and negative
// experimental endorsement signals. // experimental accountable signals.
func testExperimentalEndorsement(ht *lntest.HarnessTest) { func testExperimentalAccountability(ht *lntest.HarnessTest) {
testEndorsement(ht, true) testAccountability(ht, true)
testEndorsement(ht, false) testAccountability(ht, false)
} }
// testEndorsement sets up a 5 hop network and tests propagation of // testAccountability sets up a 5 hop network and tests propagation of
// experimental endorsement signals. // experimental accountable signals.
func testEndorsement(ht *lntest.HarnessTest, aliceEndorse bool) { func testAccountability(ht *lntest.HarnessTest, aliceAccountable bool) {
cfg := node.CfgAnchor cfg := node.CfgAnchor
carolCfg := append( carolCfg := append(
[]string{"--protocol.no-experimental-endorsement"}, cfg..., []string{"--protocol.no-experimental-accountability"}, cfg...,
) )
cfgs := [][]string{cfg, cfg, carolCfg, cfg, cfg} cfgs := [][]string{cfg, cfg, carolCfg, cfg, cfg}
@@ -57,18 +57,12 @@ func testEndorsement(ht *lntest.HarnessTest, aliceEndorse bool) {
FeeLimitMsat: math.MaxInt64, FeeLimitMsat: math.MaxInt64,
} }
var expectedValue []byte expectedValue := []byte{lnwire.ExperimentalUnaccountable}
hasEndorsement := lntest.ExperimentalEndorsementActive() if aliceAccountable {
expectedValue = []byte{lnwire.ExperimentalAccountable}
if hasEndorsement { t := uint64(lnwire.ExperimentalAccountableType)
if aliceEndorse { sendReq.FirstHopCustomRecords = map[uint64][]byte{
expectedValue = []byte{lnwire.ExperimentalEndorsed} t: expectedValue,
t := uint64(lnwire.ExperimentalEndorsementType)
sendReq.FirstHopCustomRecords = map[uint64][]byte{
t: expectedValue,
}
} else {
expectedValue = []byte{lnwire.ExperimentalUnendorsed}
} }
} }
@@ -76,29 +70,28 @@ func testEndorsement(ht *lntest.HarnessTest, aliceEndorse bool) {
// Validate that our signal (positive or zero) propagates until carol // Validate that our signal (positive or zero) propagates until carol
// and then is dropped because she has disabled the feature. // and then is dropped because she has disabled the feature.
// When the endorsement experiment is not active, no signal is sent. validateAccountableAndResume(
validateEndorsedAndResume( ht, bobIntercept, true, expectedValue,
ht, bobIntercept, hasEndorsement, expectedValue,
) )
validateEndorsedAndResume( validateAccountableAndResume(
ht, carolIntercept, hasEndorsement, expectedValue, ht, carolIntercept, true, expectedValue,
) )
validateEndorsedAndResume(ht, daveIntercept, false, nil) validateAccountableAndResume(ht, daveIntercept, false, nil)
var preimage lntypes.Preimage var preimage lntypes.Preimage
copy(preimage[:], invoice.RPreimage) copy(preimage[:], invoice.RPreimage)
ht.AssertPaymentStatus(alice, preimage.Hash(), lnrpc.Payment_SUCCEEDED) ht.AssertPaymentStatus(alice, preimage.Hash(), lnrpc.Payment_SUCCEEDED)
} }
func validateEndorsedAndResume(ht *lntest.HarnessTest, func validateAccountableAndResume(ht *lntest.HarnessTest,
interceptor rpc.InterceptorClient, hasEndorsement bool, interceptor rpc.InterceptorClient, hasAccountable bool,
expectedValue []byte) { expectedValue []byte) {
packet := ht.ReceiveHtlcInterceptor(interceptor) packet := ht.ReceiveHtlcInterceptor(interceptor)
var expectedRecords map[uint64][]byte var expectedRecords map[uint64][]byte
if hasEndorsement { if hasAccountable {
u64Type := uint64(lnwire.ExperimentalEndorsementType) u64Type := uint64(lnwire.ExperimentalAccountableType)
expectedRecords = map[uint64][]byte{ expectedRecords = map[uint64][]byte{
u64Type: expectedValue, u64Type: expectedValue,
} }
+6 -17
View File
@@ -387,7 +387,7 @@ func testForwardInterceptorRestart(ht *lntest.HarnessTest) {
// all intercepted packets. These packets are held to simulate a // all intercepted packets. These packets are held to simulate a
// pending payment. // pending payment.
packet := ht.ReceiveHtlcInterceptor(bobInterceptor) packet := ht.ReceiveHtlcInterceptor(bobInterceptor)
require.Equal(ht, lntest.CustomRecordsWithUnendorsed( require.Equal(ht, lntest.CustomRecordsWithUnaccountable(
customRecords, customRecords,
), packet.InWireCustomRecords) ), packet.InWireCustomRecords)
@@ -432,25 +432,14 @@ func testForwardInterceptorRestart(ht *lntest.HarnessTest) {
// We should get another notification about the held HTLC. // We should get another notification about the held HTLC.
packet = ht.ReceiveHtlcInterceptor(bobInterceptor) packet = ht.ReceiveHtlcInterceptor(bobInterceptor)
// Check the expected number of custom records based on whether the require.Len(ht, packet.InWireCustomRecords, 2)
// endorsement experiment is still active. require.Equal(ht, lntest.CustomRecordsWithUnaccountable(customRecords),
expectedLen := 1
if lntest.ExperimentalEndorsementActive() {
expectedLen = 2
}
require.Len(ht, packet.InWireCustomRecords, expectedLen)
require.Equal(ht, lntest.CustomRecordsWithUnendorsed(customRecords),
packet.InWireCustomRecords) packet.InWireCustomRecords)
// And now we forward the payment at Carol, expecting only an // And now we forward the payment at Carol, expecting only an
// endorsement signal in our incoming custom records (if the experiment // accountability signal in our incoming custom records.
// is still active).
packet = ht.ReceiveHtlcInterceptor(carolInterceptor) packet = ht.ReceiveHtlcInterceptor(carolInterceptor)
expectedCarolLen := 0 require.Len(ht, packet.InWireCustomRecords, 1)
if lntest.ExperimentalEndorsementActive() {
expectedCarolLen = 1
}
require.Len(ht, packet.InWireCustomRecords, expectedCarolLen)
err = carolInterceptor.Send(&routerrpc.ForwardHtlcInterceptResponse{ err = carolInterceptor.Send(&routerrpc.ForwardHtlcInterceptResponse{
IncomingCircuitKey: packet.IncomingCircuitKey, IncomingCircuitKey: packet.IncomingCircuitKey,
Action: actionResume, Action: actionResume,
@@ -462,7 +451,7 @@ func testForwardInterceptorRestart(ht *lntest.HarnessTest) {
alice, preimage.Hash(), lnrpc.Payment_SUCCEEDED, alice, preimage.Hash(), lnrpc.Payment_SUCCEEDED,
func(p *lnrpc.Payment) error { func(p *lnrpc.Payment) error {
recordsEqual := reflect.DeepEqual( recordsEqual := reflect.DeepEqual(
lntest.CustomRecordsWithUnendorsed( lntest.CustomRecordsWithUnaccountable(
sendReq.FirstHopCustomRecords, sendReq.FirstHopCustomRecords,
), p.FirstHopCustomRecords, ), p.FirstHopCustomRecords,
) )
+3 -3
View File
@@ -102,9 +102,9 @@ func testInvoiceHtlcModifierBasic(ht *lntest.HarnessTest) {
ht, tc.sendAmountMsat, modifierRequest.ExitHtlcAmt, ht, tc.sendAmountMsat, modifierRequest.ExitHtlcAmt,
) )
// Expect custom records plus endorsement signal. // Expect custom records plus accountable signal.
require.Equal( require.Equal(
ht, lntest.CustomRecordsWithUnendorsed( ht, lntest.CustomRecordsWithUnaccountable(
tc.lastHopCustomRecords, tc.lastHopCustomRecords,
), modifierRequest.ExitHtlcWireCustomRecords, ), modifierRequest.ExitHtlcWireCustomRecords,
) )
@@ -152,7 +152,7 @@ func testInvoiceHtlcModifierBasic(ht *lntest.HarnessTest) {
require.Len(ht, updatedInvoice.Htlcs, 1) require.Len(ht, updatedInvoice.Htlcs, 1)
require.Equal( require.Equal(
ht, lntest.CustomRecordsWithUnendorsed( ht, lntest.CustomRecordsWithUnaccountable(
tc.lastHopCustomRecords, tc.lastHopCustomRecords,
), updatedInvoice.Htlcs[0].CustomRecords, ), updatedInvoice.Htlcs[0].CustomRecords,
) )
+6 -6
View File
@@ -71,8 +71,8 @@ type ProtocolOptions struct {
// NoRouteBlindingOption disables forwarding of payments in blinded routes. // NoRouteBlindingOption disables forwarding of payments in blinded routes.
NoRouteBlindingOption bool `long:"no-route-blinding" description:"do not forward payments that are a part of a blinded route"` NoRouteBlindingOption bool `long:"no-route-blinding" description:"do not forward payments that are a part of a blinded route"`
// NoExperimentalEndorsementOption disables experimental endorsement. // NoExperimentalAccountabilityOption disables experimental accountability.
NoExperimentalEndorsementOption bool `long:"no-experimental-endorsement" description:"do not forward experimental endorsement signals"` NoExperimentalAccountabilityOption bool `long:"no-experimental-accountability" description:"do not forward experimental accountability signals"`
// CustomMessage allows the custom message APIs to handle messages with // CustomMessage allows the custom message APIs to handle messages with
// the provided protocol numbers, which fall outside the custom message // the provided protocol numbers, which fall outside the custom message
@@ -139,10 +139,10 @@ func (l *ProtocolOptions) NoRouteBlinding() bool {
return l.NoRouteBlindingOption return l.NoRouteBlindingOption
} }
// NoExperimentalEndorsement returns true if experimental endorsement should // NoExpAccountability returns true if experimental accountability should be
// be disabled. // disabled.
func (l *ProtocolOptions) NoExperimentalEndorsement() bool { func (l *ProtocolOptions) NoExpAccountability() bool {
return l.NoExperimentalEndorsementOption return l.NoExperimentalAccountabilityOption
} }
// NoQuiescence returns true if quiescence is disabled. // NoQuiescence returns true if quiescence is disabled.
+6 -6
View File
@@ -74,8 +74,8 @@ type ProtocolOptions struct {
// NoRouteBlindingOption disables forwarding of payments in blinded routes. // NoRouteBlindingOption disables forwarding of payments in blinded routes.
NoRouteBlindingOption bool `long:"no-route-blinding" description:"do not forward payments that are a part of a blinded route"` NoRouteBlindingOption bool `long:"no-route-blinding" description:"do not forward payments that are a part of a blinded route"`
// NoExperimentalEndorsementOption disables experimental endorsement. // NoExperimentalAccountabilityOption disables experimental accountability.
NoExperimentalEndorsementOption bool `long:"no-experimental-endorsement" description:"do not forward experimental endorsement signals"` NoExperimentalAccountabilityOption bool `long:"no-experimental-accountability" description:"do not forward experimental accountability signals"`
// NoQuiescenceOption disables quiescence for all channels. // NoQuiescenceOption disables quiescence for all channels.
NoQuiescenceOption bool `long:"no-quiescence" description:"do not allow or advertise quiescence for any channel"` NoQuiescenceOption bool `long:"no-quiescence" description:"do not allow or advertise quiescence for any channel"`
@@ -137,10 +137,10 @@ func (l *ProtocolOptions) NoRouteBlinding() bool {
return l.NoRouteBlindingOption return l.NoRouteBlindingOption
} }
// NoExperimentalEndorsement returns true if experimental endorsement should // NoExpAccountability returns true if experimental accountability should be
// be disabled. // disabled.
func (l *ProtocolOptions) NoExperimentalEndorsement() bool { func (l *ProtocolOptions) NoExpAccountability() bool {
return l.NoExperimentalEndorsementOption return l.NoExperimentalAccountabilityOption
} }
// NoQuiescence returns true if quiescence is disabled. // NoQuiescence returns true if quiescence is disabled.
+7 -7
View File
@@ -122,9 +122,9 @@ type RouterBackend struct {
// channel data from the first hop of a route. // channel data from the first hop of a route.
ParseCustomChannelData func(message proto.Message) error ParseCustomChannelData func(message proto.Message) error
// ShouldSetExpEndorsement returns a boolean indicating whether the // ShouldSetExpAccountability returns a boolean indicating whether the
// experimental endorsement bit should be set. // experimental accountability bit should be set.
ShouldSetExpEndorsement func() bool ShouldSetExpAccountability func() bool
// Clock is the clock used to validate payment requests expiry. // Clock is the clock used to validate payment requests expiry.
// It is useful for testing. // It is useful for testing.
@@ -947,19 +947,19 @@ func (r *RouterBackend) extractIntentFromSendRequest(
} }
payIntent.FirstHopCustomRecords = firstHopRecords payIntent.FirstHopCustomRecords = firstHopRecords
// If the experimental endorsement signal is not already set, propagate // If the experimental accountable signal is not already set, propagate
// a zero value field if configured to set this signal. // a zero value field if configured to set this signal.
if r.ShouldSetExpEndorsement() { if r.ShouldSetExpAccountability() {
if payIntent.FirstHopCustomRecords == nil { if payIntent.FirstHopCustomRecords == nil {
payIntent.FirstHopCustomRecords = make( payIntent.FirstHopCustomRecords = make(
map[uint64][]byte, map[uint64][]byte,
) )
} }
t := uint64(lnwire.ExperimentalEndorsementType) t := uint64(lnwire.ExperimentalAccountableType)
if _, set := payIntent.FirstHopCustomRecords[t]; !set { if _, set := payIntent.FirstHopCustomRecords[t]; !set {
payIntent.FirstHopCustomRecords[t] = []byte{ payIntent.FirstHopCustomRecords[t] = []byte{
lnwire.ExperimentalUnendorsed, lnwire.ExperimentalUnaccountable,
} }
} }
} }
+15 -15
View File
@@ -677,7 +677,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) {
{ {
name: "Amount conflict, both sat and msat specified", name: "Amount conflict, both sat and msat specified",
backend: &RouterBackend{ backend: &RouterBackend{
ShouldSetExpEndorsement: func() bool { ShouldSetExpAccountability: func() bool {
return true return true
}, },
}, },
@@ -692,7 +692,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) {
{ {
name: "Both dest and payment_request provided", name: "Both dest and payment_request provided",
backend: &RouterBackend{ backend: &RouterBackend{
ShouldSetExpEndorsement: func() bool { ShouldSetExpAccountability: func() bool {
return false return false
}, },
}, },
@@ -708,7 +708,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) {
{ {
name: "Both payment_hash and payment_request provided", name: "Both payment_hash and payment_request provided",
backend: &RouterBackend{ backend: &RouterBackend{
ShouldSetExpEndorsement: func() bool { ShouldSetExpAccountability: func() bool {
return false return false
}, },
}, },
@@ -725,7 +725,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) {
name: "Both final_cltv_delta and payment_request " + name: "Both final_cltv_delta and payment_request " +
"provided", "provided",
backend: &RouterBackend{ backend: &RouterBackend{
ShouldSetExpEndorsement: func() bool { ShouldSetExpAccountability: func() bool {
return false return false
}, },
}, },
@@ -741,7 +741,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) {
{ {
name: "Invalid payment request length", name: "Invalid payment request length",
backend: &RouterBackend{ backend: &RouterBackend{
ShouldSetExpEndorsement: func() bool { ShouldSetExpAccountability: func() bool {
return false return false
}, },
ActiveNetParams: &chaincfg.RegressionNetParams, ActiveNetParams: &chaincfg.RegressionNetParams,
@@ -756,7 +756,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) {
{ {
name: "Expired invoice payment request", name: "Expired invoice payment request",
backend: &RouterBackend{ backend: &RouterBackend{
ShouldSetExpEndorsement: func() bool { ShouldSetExpAccountability: func() bool {
return false return false
}, },
ActiveNetParams: &chaincfg.RegressionNetParams, ActiveNetParams: &chaincfg.RegressionNetParams,
@@ -772,7 +772,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) {
{ {
name: "Invoice missing payment address", name: "Invoice missing payment address",
backend: &RouterBackend{ backend: &RouterBackend{
ShouldSetExpEndorsement: func() bool { ShouldSetExpAccountability: func() bool {
return false return false
}, },
ActiveNetParams: &chaincfg.RegressionNetParams, ActiveNetParams: &chaincfg.RegressionNetParams,
@@ -789,7 +789,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) {
{ {
name: "Invalid dest vertex length", name: "Invalid dest vertex length",
backend: &RouterBackend{ backend: &RouterBackend{
ShouldSetExpEndorsement: func() bool { ShouldSetExpAccountability: func() bool {
return false return false
}, },
}, },
@@ -803,7 +803,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) {
{ {
name: "Payment request with missing amount", name: "Payment request with missing amount",
backend: &RouterBackend{ backend: &RouterBackend{
ShouldSetExpEndorsement: func() bool { ShouldSetExpAccountability: func() bool {
return false return false
}, },
}, },
@@ -817,7 +817,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) {
{ {
name: "Destination lacks AMP support", name: "Destination lacks AMP support",
backend: &RouterBackend{ backend: &RouterBackend{
ShouldSetExpEndorsement: func() bool { ShouldSetExpAccountability: func() bool {
return false return false
}, },
}, },
@@ -834,7 +834,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) {
{ {
name: "Invalid payment hash length", name: "Invalid payment hash length",
backend: &RouterBackend{ backend: &RouterBackend{
ShouldSetExpEndorsement: func() bool { ShouldSetExpAccountability: func() bool {
return false return false
}, },
}, },
@@ -849,7 +849,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) {
{ {
name: "Payment amount exceeds maximum possible amount", name: "Payment amount exceeds maximum possible amount",
backend: &RouterBackend{ backend: &RouterBackend{
ShouldSetExpEndorsement: func() bool { ShouldSetExpAccountability: func() bool {
return false return false
}, },
}, },
@@ -868,7 +868,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) {
name: "Reject self-payments if not permitted", name: "Reject self-payments if not permitted",
backend: &RouterBackend{ backend: &RouterBackend{
MaxTotalTimelock: 1000, MaxTotalTimelock: 1000,
ShouldSetExpEndorsement: func() bool { ShouldSetExpAccountability: func() bool {
return false return false
}, },
SelfNode: target, SelfNode: target,
@@ -885,7 +885,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) {
name: "Required and optional feature bits set", name: "Required and optional feature bits set",
backend: &RouterBackend{ backend: &RouterBackend{
MaxTotalTimelock: 1000, MaxTotalTimelock: 1000,
ShouldSetExpEndorsement: func() bool { ShouldSetExpAccountability: func() bool {
return false return false
}, },
}, },
@@ -906,7 +906,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) {
name: "Valid send req parameters, payment settled", name: "Valid send req parameters, payment settled",
backend: &RouterBackend{ backend: &RouterBackend{
MaxTotalTimelock: 1000, MaxTotalTimelock: 1000,
ShouldSetExpEndorsement: func() bool { ShouldSetExpAccountability: func() bool {
return false return false
}, },
}, },
+6 -23
View File
@@ -7,11 +7,9 @@ import (
"os" "os"
"strconv" "strconv"
"strings" "strings"
"time"
"github.com/btcsuite/btcd/btcutil" "github.com/btcsuite/btcd/btcutil"
"github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd"
"github.com/lightningnetwork/lnd/input" "github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc"
"github.com/lightningnetwork/lnd/lntest/wait" "github.com/lightningnetwork/lnd/lntest/wait"
@@ -285,33 +283,18 @@ func CalcStaticFeeBuffer(c lnrpc.CommitmentType, numHTLCs int) btcutil.Amount {
return feeBuffer.ToSatoshis() return feeBuffer.ToSatoshis()
} }
// CustomRecordsWithUnendorsed copies the map of custom records and adds an // CustomRecordsWithUnaccountable copies the map of custom records and adds an
// endorsed signal (replacing in the case of conflict) for assertion in tests. // accountable signal (replacing in the case of conflict) for assertion in
func CustomRecordsWithUnendorsed( // tests.
func CustomRecordsWithUnaccountable(
originalRecords lnwire.CustomRecords) map[uint64][]byte { originalRecords lnwire.CustomRecords) map[uint64][]byte {
if !ExperimentalEndorsementActive() {
// Return nil if there are no records, to match wire encoding.
if len(originalRecords) == 0 {
return nil
}
return originalRecords.Copy()
}
return originalRecords.MergedCopy(map[uint64][]byte{ return originalRecords.MergedCopy(map[uint64][]byte{
uint64(lnwire.ExperimentalEndorsementType): { uint64(lnwire.ExperimentalAccountableType): {
lnwire.ExperimentalUnendorsed, lnwire.ExperimentalUnaccountable,
}}, }},
) )
} }
// ExperimentalEndorsementActive returns true if the experimental endorsement
// window is still open.
func ExperimentalEndorsementActive() bool {
return time.Now().Before(lnd.EndorsementExperimentEnd)
}
// LnrpcOutpointToStr returns a string representation of an lnrpc.OutPoint. // LnrpcOutpointToStr returns a string representation of an lnrpc.OutPoint.
func LnrpcOutpointToStr(outpoint *lnrpc.OutPoint) string { func LnrpcOutpointToStr(outpoint *lnrpc.OutPoint) string {
return fmt.Sprintf("%s:%d", outpoint.TxidStr, outpoint.OutputIndex) return fmt.Sprintf("%s:%d", outpoint.TxidStr, outpoint.OutputIndex)
+10 -8
View File
@@ -289,13 +289,15 @@ const (
// being finalized. // being finalized.
SimpleTaprootChannelsOptionalStaging = 181 SimpleTaprootChannelsOptionalStaging = 181
// ExperimentalEndorsementRequired is a required feature bit that // ExperimentalAccountabilityRequired is a required feature bit that
// indicates that the node will relay experimental endorsement signals. // indicates that the node will relay experimental accountability
ExperimentalEndorsementRequired FeatureBit = 260 // signals.
ExperimentalAccountabilityRequired FeatureBit = 260
// ExperimentalEndorsementOptional is an optional feature bit that // ExperimentalAccountabilityOptional is an optional feature bit that
// indicates that the node will relay experimental endorsement signals. // indicates that the node will relay experimental accountability
ExperimentalEndorsementOptional FeatureBit = 261 // signals.
ExperimentalAccountabilityOptional FeatureBit = 261
// Bolt11BlindedPathsRequired is a required feature bit that indicates // Bolt11BlindedPathsRequired is a required feature bit that indicates
// that the node is able to understand the blinded path tagged field in // that the node is able to understand the blinded path tagged field in
@@ -385,8 +387,8 @@ var Features = map[FeatureBit]string{
SimpleTaprootChannelsOptionalStaging: "simple-taproot-chans-x", SimpleTaprootChannelsOptionalStaging: "simple-taproot-chans-x",
SimpleTaprootOverlayChansOptional: "taproot-overlay-chans", SimpleTaprootOverlayChansOptional: "taproot-overlay-chans",
SimpleTaprootOverlayChansRequired: "taproot-overlay-chans", SimpleTaprootOverlayChansRequired: "taproot-overlay-chans",
ExperimentalEndorsementRequired: "endorsement-x", ExperimentalAccountabilityRequired: "accountable-x",
ExperimentalEndorsementOptional: "endorsement-x", ExperimentalAccountabilityOptional: "accountable-x",
Bolt11BlindedPathsOptional: "bolt-11-blinded-paths", Bolt11BlindedPathsOptional: "bolt-11-blinded-paths",
Bolt11BlindedPathsRequired: "bolt-11-blinded-paths", Bolt11BlindedPathsRequired: "bolt-11-blinded-paths",
RbfCoopCloseOptional: "rbf-coop-close", RbfCoopCloseOptional: "rbf-coop-close",
+13 -12
View File
@@ -16,20 +16,21 @@ const (
// entire packet. // entire packet.
OnionPacketSize = 1366 OnionPacketSize = 1366
// ExperimentalEndorsementType is the TLV type used for a custom // ExperimentalAccountableType is the TLV type used for a custom
// record that sets an experimental endorsement value. // record that sets an experimental accountable value.
ExperimentalEndorsementType tlv.Type = 106823 ExperimentalAccountableType tlv.Type = 106823
// ExperimentalUnendorsed is the value that the experimental endorsement // ExperimentalUnaccountable is the value that the experimental
// field contains when a htlc is not endorsed. // accountable field contains when a htlc is not accountable.
ExperimentalUnendorsed = 0 ExperimentalUnaccountable = 0
// ExperimentalEndorsed is the value that the experimental endorsement // ExperimentalAccountable is the value that the experimental
// field contains when a htlc is endorsed. We're using a single byte // accountable field contains when a htlc is accountable. We're using a
// to represent our endorsement value, but limit the value to using // single byte to represent our accountable value, but limit the value
// the first three bits (max value = 00000111). Interpreted as a uint8 // to using the first three bits (max value = 00000111). Interpreted as
// (an alias for byte in go), we can just define this constant as 7. // a uint8 (an alias for byte in go), we can just define this constant
ExperimentalEndorsed = 7 // as 7.
ExperimentalAccountable = 7
) )
type ( type (
+22 -22
View File
@@ -468,9 +468,9 @@ type Config struct {
// onion messages to subscribers. // onion messages to subscribers.
OnionMessageServer *subscribe.Server OnionMessageServer *subscribe.Server
// ShouldFwdExpEndorsement is a closure that indicates whether // ShouldFwdExpAccountability is a closure that indicates whether
// experimental endorsement signals should be set. // experimental accountability signals should be set.
ShouldFwdExpEndorsement func() bool ShouldFwdExpAccountability func() bool
// NoDisconnectOnPongFailure indicates whether the peer should *not* be // NoDisconnectOnPongFailure indicates whether the peer should *not* be
// disconnected if a pong is not received in time or is mismatched. // disconnected if a pong is not received in time or is mismatched.
@@ -1460,25 +1460,25 @@ func (p *Brontide) addLink(chanPoint *wire.OutPoint,
PendingCommitTicker: ticker.New( PendingCommitTicker: ticker.New(
p.cfg.PendingCommitInterval, p.cfg.PendingCommitInterval,
), ),
BatchSize: p.cfg.ChannelCommitBatchSize, BatchSize: p.cfg.ChannelCommitBatchSize,
UnsafeReplay: p.cfg.UnsafeReplay, UnsafeReplay: p.cfg.UnsafeReplay,
MinUpdateTimeout: htlcswitch.DefaultMinLinkFeeUpdateTimeout, MinUpdateTimeout: htlcswitch.DefaultMinLinkFeeUpdateTimeout,
MaxUpdateTimeout: htlcswitch.DefaultMaxLinkFeeUpdateTimeout, MaxUpdateTimeout: htlcswitch.DefaultMaxLinkFeeUpdateTimeout,
OutgoingCltvRejectDelta: p.cfg.OutgoingCltvRejectDelta, OutgoingCltvRejectDelta: p.cfg.OutgoingCltvRejectDelta,
TowerClient: p.cfg.TowerClient, TowerClient: p.cfg.TowerClient,
MaxOutgoingCltvExpiry: p.cfg.MaxOutgoingCltvExpiry, MaxOutgoingCltvExpiry: p.cfg.MaxOutgoingCltvExpiry,
MaxFeeAllocation: p.cfg.MaxChannelFeeAllocation, MaxFeeAllocation: p.cfg.MaxChannelFeeAllocation,
MaxAnchorsCommitFeeRate: p.cfg.MaxAnchorsCommitFeeRate, MaxAnchorsCommitFeeRate: p.cfg.MaxAnchorsCommitFeeRate,
NotifyActiveLink: p.cfg.ChannelNotifier.NotifyActiveLinkEvent, NotifyActiveLink: p.cfg.ChannelNotifier.NotifyActiveLinkEvent,
NotifyActiveChannel: p.cfg.ChannelNotifier.NotifyActiveChannelEvent, NotifyActiveChannel: p.cfg.ChannelNotifier.NotifyActiveChannelEvent,
NotifyInactiveChannel: p.cfg.ChannelNotifier.NotifyInactiveChannelEvent, NotifyInactiveChannel: p.cfg.ChannelNotifier.NotifyInactiveChannelEvent,
NotifyInactiveLinkEvent: p.cfg.ChannelNotifier.NotifyInactiveLinkEvent, NotifyInactiveLinkEvent: p.cfg.ChannelNotifier.NotifyInactiveLinkEvent,
HtlcNotifier: p.cfg.HtlcNotifier, HtlcNotifier: p.cfg.HtlcNotifier,
GetAliases: p.cfg.GetAliases, GetAliases: p.cfg.GetAliases,
PreviouslySentShutdown: shutdownMsg, PreviouslySentShutdown: shutdownMsg,
DisallowRouteBlinding: p.cfg.DisallowRouteBlinding, DisallowRouteBlinding: p.cfg.DisallowRouteBlinding,
MaxFeeExposure: p.cfg.MaxFeeExposure, MaxFeeExposure: p.cfg.MaxFeeExposure,
ShouldFwdExpEndorsement: p.cfg.ShouldFwdExpEndorsement, ShouldFwdExpAccountability: p.cfg.ShouldFwdExpAccountability,
DisallowQuiescence: p.cfg.DisallowQuiescence || DisallowQuiescence: p.cfg.DisallowQuiescence ||
!p.remoteFeatures.HasFeature(lnwire.QuiescenceOptional), !p.remoteFeatures.HasFeature(lnwire.QuiescenceOptional),
AuxTrafficShaper: p.cfg.AuxTrafficShaper, AuxTrafficShaper: p.cfg.AuxTrafficShaper,
+1 -1
View File
@@ -526,7 +526,7 @@ type Route struct {
// FirstHopWireCustomRecords is a set of custom records that should be // FirstHopWireCustomRecords is a set of custom records that should be
// included in the wire message sent to the first hop. This is for // included in the wire message sent to the first hop. This is for
// example used in custom channels. Besides custom channels we use it // example used in custom channels. Besides custom channels we use it
// also for the endorsement bit. This data will be sent to the first // also for the accountable bit. This data will be sent to the first
// hop in the UpdateAddHTLC message. // hop in the UpdateAddHTLC message.
// //
// NOTE: Since these records already represent TLV records, and we // NOTE: Since these records already represent TLV records, and we
+2 -10
View File
@@ -695,8 +695,6 @@ func newRPCServer(cfg *Config, interceptorChain *rpcperms.InterceptorChain,
// addDeps populates all dependencies needed by the RPC server, and any // addDeps populates all dependencies needed by the RPC server, and any
// of the sub-servers that it maintains. When this is done, the RPC server can // of the sub-servers that it maintains. When this is done, the RPC server can
// be started, and start accepting RPC calls. // be started, and start accepting RPC calls.
//
//nolint:funlen
func (r *rpcServer) addDeps(ctx context.Context, s *server, func (r *rpcServer) addDeps(ctx context.Context, s *server,
macService *macaroons.Service, macService *macaroons.Service,
subServerCgs *subRPCServerConfigs, atpl *autopilot.Manager, subServerCgs *subRPCServerConfigs, atpl *autopilot.Manager,
@@ -781,14 +779,8 @@ func (r *rpcServer) addDeps(ctx context.Context, s *server,
return nil return nil
}, },
ShouldSetExpEndorsement: func() bool { ShouldSetExpAccountability: func() bool {
if s.cfg.ProtocolOptions.NoExperimentalEndorsement() { return !s.cfg.ProtocolOptions.NoExpAccountability()
return false
}
return clock.NewDefaultClock().Now().Before(
EndorsementExperimentEnd,
)
}, },
} }
+2 -2
View File
@@ -1440,8 +1440,8 @@
; Set to disable blinded route forwarding. ; Set to disable blinded route forwarding.
; protocol.no-route-blinding=false ; protocol.no-route-blinding=false
; Set to disable experimental endorsement signaling. ; Set to disable experimental accountability signaling.
; protocol.no-experimental-endorsement=false ; protocol.no-experimental-accountability=false
; Set to enable support for RBF based coop close. ; Set to enable support for RBF based coop close.
; protocol.rbf-coop-close=false ; protocol.rbf-coop-close=false
+18 -30
View File
@@ -139,12 +139,6 @@ var (
// TODO(roasbeef): add command line param to modify. // TODO(roasbeef): add command line param to modify.
MaxFundingAmount = funding.MaxBtcFundingAmount MaxFundingAmount = funding.MaxBtcFundingAmount
// EndorsementExperimentEnd is the time after which nodes should stop
// propagating experimental endorsement signals.
//
// Per blip04: January 1, 2026 12:00:00 AM UTC in unix seconds.
EndorsementExperimentEnd = time.Unix(1767225600, 0)
// ErrGossiperBan is one of the errors that can be returned when we // ErrGossiperBan is one of the errors that can be returned when we
// attempt to finalize a connection to a remote peer. // attempt to finalize a connection to a remote peer.
ErrGossiperBan = errors.New("gossiper has banned remote's key") ErrGossiperBan = errors.New("gossiper has banned remote's key")
@@ -641,22 +635,22 @@ func newServer(ctx context.Context, cfg *Config, listenAddrs []net.Addr,
//nolint:ll //nolint:ll
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.NoAnchorCommitments(), NoAnchors: cfg.ProtocolOptions.NoAnchorCommitments(),
NoWumbo: !cfg.ProtocolOptions.Wumbo(), NoWumbo: !cfg.ProtocolOptions.Wumbo(),
NoScriptEnforcementLease: cfg.ProtocolOptions.NoScriptEnforcementLease(), NoScriptEnforcementLease: cfg.ProtocolOptions.NoScriptEnforcementLease(),
NoKeysend: !cfg.AcceptKeySend, NoKeysend: !cfg.AcceptKeySend,
NoOptionScidAlias: !cfg.ProtocolOptions.ScidAlias(), NoOptionScidAlias: !cfg.ProtocolOptions.ScidAlias(),
NoZeroConf: !cfg.ProtocolOptions.ZeroConf(), NoZeroConf: !cfg.ProtocolOptions.ZeroConf(),
NoAnySegwit: cfg.ProtocolOptions.NoAnySegwit(), NoAnySegwit: cfg.ProtocolOptions.NoAnySegwit(),
CustomFeatures: cfg.ProtocolOptions.CustomFeatures(), CustomFeatures: cfg.ProtocolOptions.CustomFeatures(),
NoTaprootChans: !cfg.ProtocolOptions.TaprootChans, NoTaprootChans: !cfg.ProtocolOptions.TaprootChans,
NoTaprootOverlay: !cfg.ProtocolOptions.TaprootOverlayChans, NoTaprootOverlay: !cfg.ProtocolOptions.TaprootOverlayChans,
NoRouteBlinding: cfg.ProtocolOptions.NoRouteBlinding(), NoRouteBlinding: cfg.ProtocolOptions.NoRouteBlinding(),
NoExperimentalEndorsement: cfg.ProtocolOptions.NoExperimentalEndorsement(), NoExperimentalAccountability: cfg.ProtocolOptions.NoExpAccountability(),
NoQuiescence: cfg.ProtocolOptions.NoQuiescence(), NoQuiescence: cfg.ProtocolOptions.NoQuiescence(),
NoRbfCoopClose: !cfg.ProtocolOptions.RbfCoopClose, NoRbfCoopClose: !cfg.ProtocolOptions.RbfCoopClose,
}) })
if err != nil { if err != nil {
return nil, err return nil, err
@@ -4443,14 +4437,8 @@ func (s *server) peerConnected(conn net.Conn, connReq *connmgr.ConnReq,
AuxResolver: s.implCfg.AuxContractResolver, AuxResolver: s.implCfg.AuxContractResolver,
AuxTrafficShaper: s.implCfg.TrafficShaper, AuxTrafficShaper: s.implCfg.TrafficShaper,
AuxChannelNegotiator: s.implCfg.AuxChannelNegotiator, AuxChannelNegotiator: s.implCfg.AuxChannelNegotiator,
ShouldFwdExpEndorsement: func() bool { ShouldFwdExpAccountability: func() bool {
if s.cfg.ProtocolOptions.NoExperimentalEndorsement() { return !s.cfg.ProtocolOptions.NoExpAccountability()
return false
}
return clock.NewDefaultClock().Now().Before(
EndorsementExperimentEnd,
)
}, },
NoDisconnectOnPongFailure: s.cfg.NoDisconnectOnPongFailure, NoDisconnectOnPongFailure: s.cfg.NoDisconnectOnPongFailure,
} }