diff --git a/docs/release-notes/release-notes-0.21.0.md b/docs/release-notes/release-notes-0.21.0.md index 04b4290e26..eae9b238c7 100644 --- a/docs/release-notes/release-notes-0.21.0.md +++ b/docs/release-notes/release-notes-0.21.0.md @@ -48,6 +48,10 @@ This applies to both funders and fundees, with the ability to override the 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 ## lncli Updates diff --git a/feature/default_sets.go b/feature/default_sets.go index fcb53b6664..5be5706f68 100644 --- a/feature/default_sets.go +++ b/feature/default_sets.go @@ -100,7 +100,7 @@ var defaultSetDesc = setDesc{ SetInit: {}, // I SetNodeAnn: {}, // N }, - lnwire.ExperimentalEndorsementOptional: { + lnwire.ExperimentalAccountabilityOptional: { SetNodeAnn: {}, // N }, lnwire.RbfCoopCloseOptionalStaging: { diff --git a/feature/manager.go b/feature/manager.go index 862880f3b2..baef44019d 100644 --- a/feature/manager.go +++ b/feature/manager.go @@ -69,9 +69,9 @@ type Config struct { // NoTaprootOverlay unsets the taproot overlay channel feature bits. NoTaprootOverlay bool - // NoExperimentalEndorsement unsets any bits that signal support for - // forwarding experimental endorsement. - NoExperimentalEndorsement bool + // NoExperimentalAccountability unsets any bits that signal support for + // forwarding experimental accountability. + NoExperimentalAccountability bool // NoRbfCoopClose unsets any bits that signal support for using RBF for // coop close. @@ -213,9 +213,9 @@ func newManager(cfg Config, desc setDesc) (*Manager, error) { raw.Unset(lnwire.SimpleTaprootOverlayChansOptional) raw.Unset(lnwire.SimpleTaprootOverlayChansRequired) } - if cfg.NoExperimentalEndorsement { - raw.Unset(lnwire.ExperimentalEndorsementOptional) - raw.Unset(lnwire.ExperimentalEndorsementRequired) + if cfg.NoExperimentalAccountability { + raw.Unset(lnwire.ExperimentalAccountabilityOptional) + raw.Unset(lnwire.ExperimentalAccountabilityRequired) } if cfg.NoRbfCoopClose { raw.Unset(lnwire.RbfCoopCloseOptionalStaging) diff --git a/htlcswitch/link.go b/htlcswitch/link.go index 4c81964cc2..0fc1e5cd14 100644 --- a/htlcswitch/link.go +++ b/htlcswitch/link.go @@ -290,9 +290,9 @@ type ChannelLinkConfig struct { // restrict the flow of HTLCs and fee updates. MaxFeeExposure lnwire.MilliSatoshi - // ShouldFwdExpEndorsement is a closure that indicates whether the link - // should forward experimental endorsement signals. - ShouldFwdExpEndorsement func() bool + // ShouldFwdExpAccountability is a closure that indicates whether the + // link should forward experimental accountability signals. + ShouldFwdExpAccountability func() bool // AuxTrafficShaper is an optional auxiliary traffic shaper that can be // used to manage the bandwidth of the link. @@ -3163,11 +3163,11 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg) { continue } - endorseValue := l.experimentalEndorsement( + accountableValue := l.experimentalAccountability( record.CustomSet(add.CustomRecords), ) - endorseType := uint64( - lnwire.ExperimentalEndorsementType, + accountableType := uint64( + lnwire.ExperimentalAccountableType, ) switch fwdPkg.State { @@ -3191,9 +3191,9 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg) { BlindingPoint: fwdInfo.NextBlinding, } - endorseValue.WhenSome(func(e byte) { + accountableValue.WhenSome(func(e byte) { custRecords := map[uint64][]byte{ - endorseType: {e}, + accountableType: {e}, } outgoingAdd.CustomRecords = custRecords @@ -3249,9 +3249,9 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg) { BlindingPoint: fwdInfo.NextBlinding, } - endorseValue.WhenSome(func(e byte) { + accountableValue.WhenSome(func(e 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...) } -// experimentalEndorsement returns the value to set for our outgoing -// experimental endorsement field, and a boolean indicating whether it should +// experimentalAccountability returns the value to set for our outgoing +// experimental accountable field, and a boolean indicating whether it should // be populated on the outgoing htlc. -func (l *channelLink) experimentalEndorsement( +func (l *channelLink) experimentalAccountability( customUpdateAdd record.CustomSet) fn.Option[byte] { - // Only relay experimental signal if we are within the experiment - // period. - if !l.cfg.ShouldFwdExpEndorsement() { + if !l.cfg.ShouldFwdExpAccountability() { return fn.None[byte]() } // If we don't have any custom records or the experimental field is // not set, just forward a zero value. 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] 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 // it has no data and just forward a zero value. 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. - if value[0] == lnwire.ExperimentalEndorsed { - return fn.Some[byte](lnwire.ExperimentalEndorsed) + // Only forward accountable if the incoming link is accountable. + if value[0] == lnwire.ExperimentalAccountable { + 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. - 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 diff --git a/htlcswitch/link_test.go b/htlcswitch/link_test.go index 101a47b98a..e4e63d9820 100644 --- a/htlcswitch/link_test.go +++ b/htlcswitch/link_test.go @@ -2234,18 +2234,18 @@ func newSingleLinkTestHarness(t *testing.T, chanAmt, PendingCommitTicker: ticker.New(time.Minute), // Make the BatchSize and Min/MaxUpdateTimeout large enough // to not trigger commit updates automatically during tests. - BatchSize: 10000, - MinUpdateTimeout: 30 * time.Minute, - MaxUpdateTimeout: 40 * time.Minute, - MaxOutgoingCltvExpiry: DefaultMaxOutgoingCltvExpiry, - MaxFeeAllocation: DefaultMaxLinkFeeAllocation, - NotifyActiveLink: func(wire.OutPoint) {}, - NotifyActiveChannel: func(wire.OutPoint) {}, - NotifyInactiveChannel: func(wire.OutPoint) {}, - NotifyInactiveLinkEvent: func(wire.OutPoint) {}, - HtlcNotifier: aliceSwitch.cfg.HtlcNotifier, - GetAliases: getAliases, - ShouldFwdExpEndorsement: func() bool { return true }, + BatchSize: 10000, + MinUpdateTimeout: 30 * time.Minute, + MaxUpdateTimeout: 40 * time.Minute, + MaxOutgoingCltvExpiry: DefaultMaxOutgoingCltvExpiry, + MaxFeeAllocation: DefaultMaxLinkFeeAllocation, + NotifyActiveLink: func(wire.OutPoint) {}, + NotifyActiveChannel: func(wire.OutPoint) {}, + NotifyInactiveChannel: func(wire.OutPoint) {}, + NotifyInactiveLinkEvent: func(wire.OutPoint) {}, + HtlcNotifier: aliceSwitch.cfg.HtlcNotifier, + GetAliases: getAliases, + ShouldFwdExpAccountability: func() bool { return true }, } aliceLink := NewChannelLink(aliceCfg, aliceLc.channel) @@ -4924,17 +4924,17 @@ func (h *persistentLinkHarness) restartLink( MinUpdateTimeout: 30 * time.Minute, MaxUpdateTimeout: 40 * time.Minute, // Set any hodl flags requested for the new link. - HodlMask: hodl.MaskFromFlags(hodlFlags...), - MaxOutgoingCltvExpiry: DefaultMaxOutgoingCltvExpiry, - MaxFeeAllocation: DefaultMaxLinkFeeAllocation, - NotifyActiveLink: func(wire.OutPoint) {}, - NotifyActiveChannel: func(wire.OutPoint) {}, - NotifyInactiveChannel: func(wire.OutPoint) {}, - NotifyInactiveLinkEvent: func(wire.OutPoint) {}, - HtlcNotifier: h.hSwitch.cfg.HtlcNotifier, - SyncStates: syncStates, - GetAliases: getAliases, - ShouldFwdExpEndorsement: func() bool { return true }, + HodlMask: hodl.MaskFromFlags(hodlFlags...), + MaxOutgoingCltvExpiry: DefaultMaxOutgoingCltvExpiry, + MaxFeeAllocation: DefaultMaxLinkFeeAllocation, + NotifyActiveLink: func(wire.OutPoint) {}, + NotifyActiveChannel: func(wire.OutPoint) {}, + NotifyInactiveChannel: func(wire.OutPoint) {}, + NotifyInactiveLinkEvent: func(wire.OutPoint) {}, + HtlcNotifier: h.hSwitch.cfg.HtlcNotifier, + SyncStates: syncStates, + GetAliases: getAliases, + ShouldFwdExpAccountability: func() bool { return true }, } aliceLink := NewChannelLink(aliceCfg, aliceChannel) diff --git a/htlcswitch/test_utils.go b/htlcswitch/test_utils.go index bdb365d3c9..b74dbd0bbf 100644 --- a/htlcswitch/test_utils.go +++ b/htlcswitch/test_utils.go @@ -1157,27 +1157,27 @@ func (h *hopNetwork) createChannelLink(server, peer *mockServer, UpdateContractSignals: func(*contractcourt.ContractSignals) error { return nil }, - NotifyContractUpdate: notifyContractUpdate, - ChainEvents: &contractcourt.ChainEventSubscription{}, - SyncStates: true, - BatchSize: 10, - BatchTicker: ticker.NewForce(testBatchTimeout), - FwdPkgGCTicker: ticker.NewForce(fwdPkgTimeout), - PendingCommitTicker: ticker.New(2 * time.Minute), - MinUpdateTimeout: minFeeUpdateTimeout, - MaxUpdateTimeout: maxFeeUpdateTimeout, - OnChannelFailure: func(lnwire.ChannelID, lnwire.ShortChannelID, LinkFailureError) {}, - OutgoingCltvRejectDelta: 3, - MaxOutgoingCltvExpiry: DefaultMaxOutgoingCltvExpiry, - MaxFeeAllocation: DefaultMaxLinkFeeAllocation, - MaxAnchorsCommitFeeRate: chainfee.SatPerKVByte(10 * 1000).FeePerKWeight(), - NotifyActiveLink: func(wire.OutPoint) {}, - NotifyActiveChannel: func(wire.OutPoint) {}, - NotifyInactiveChannel: func(wire.OutPoint) {}, - NotifyInactiveLinkEvent: func(wire.OutPoint) {}, - HtlcNotifier: server.htlcSwitch.cfg.HtlcNotifier, - GetAliases: getAliases, - ShouldFwdExpEndorsement: func() bool { return true }, + NotifyContractUpdate: notifyContractUpdate, + ChainEvents: &contractcourt.ChainEventSubscription{}, + SyncStates: true, + BatchSize: 10, + BatchTicker: ticker.NewForce(testBatchTimeout), + FwdPkgGCTicker: ticker.NewForce(fwdPkgTimeout), + PendingCommitTicker: ticker.New(2 * time.Minute), + MinUpdateTimeout: minFeeUpdateTimeout, + MaxUpdateTimeout: maxFeeUpdateTimeout, + OnChannelFailure: func(lnwire.ChannelID, lnwire.ShortChannelID, LinkFailureError) {}, + OutgoingCltvRejectDelta: 3, + MaxOutgoingCltvExpiry: DefaultMaxOutgoingCltvExpiry, + MaxFeeAllocation: DefaultMaxLinkFeeAllocation, + MaxAnchorsCommitFeeRate: chainfee.SatPerKVByte(10 * 1000).FeePerKWeight(), + NotifyActiveLink: func(wire.OutPoint) {}, + NotifyActiveChannel: func(wire.OutPoint) {}, + NotifyInactiveChannel: func(wire.OutPoint) {}, + NotifyInactiveLinkEvent: func(wire.OutPoint) {}, + HtlcNotifier: server.htlcSwitch.cfg.HtlcNotifier, + GetAliases: getAliases, + ShouldFwdExpAccountability: func() bool { return true }, }, channel, ) diff --git a/itest/list_on_test.go b/itest/list_on_test.go index f5961147d3..02457d7d13 100644 --- a/itest/list_on_test.go +++ b/itest/list_on_test.go @@ -700,8 +700,8 @@ var allTestCases = []*lntest.TestCase{ TestFunc: testDebuglevelShow, }, { - Name: "experimental endorsement", - TestFunc: testExperimentalEndorsement, + Name: "experimental accountability", + TestFunc: testExperimentalAccountability, }, { Name: "quiescence", diff --git a/itest/lnd_experimental_endorsement.go b/itest/lnd_experimental_accountability.go similarity index 67% rename from itest/lnd_experimental_endorsement.go rename to itest/lnd_experimental_accountability.go index 7b0fc21a09..3d2227620c 100644 --- a/itest/lnd_experimental_endorsement.go +++ b/itest/lnd_experimental_accountability.go @@ -15,19 +15,19 @@ import ( "github.com/stretchr/testify/require" ) -// testExperimentalEndorsement tests setting of positive and negative -// experimental endorsement signals. -func testExperimentalEndorsement(ht *lntest.HarnessTest) { - testEndorsement(ht, true) - testEndorsement(ht, false) +// testExperimentalAccountability tests setting of positive and negative +// experimental accountable signals. +func testExperimentalAccountability(ht *lntest.HarnessTest) { + testAccountability(ht, true) + testAccountability(ht, false) } -// testEndorsement sets up a 5 hop network and tests propagation of -// experimental endorsement signals. -func testEndorsement(ht *lntest.HarnessTest, aliceEndorse bool) { +// testAccountability sets up a 5 hop network and tests propagation of +// experimental accountable signals. +func testAccountability(ht *lntest.HarnessTest, aliceAccountable bool) { cfg := node.CfgAnchor carolCfg := append( - []string{"--protocol.no-experimental-endorsement"}, cfg..., + []string{"--protocol.no-experimental-accountability"}, cfg..., ) cfgs := [][]string{cfg, cfg, carolCfg, cfg, cfg} @@ -57,10 +57,10 @@ func testEndorsement(ht *lntest.HarnessTest, aliceEndorse bool) { FeeLimitMsat: math.MaxInt64, } - expectedValue := []byte{lnwire.ExperimentalUnendorsed} - if aliceEndorse { - expectedValue = []byte{lnwire.ExperimentalEndorsed} - t := uint64(lnwire.ExperimentalEndorsementType) + expectedValue := []byte{lnwire.ExperimentalUnaccountable} + if aliceAccountable { + expectedValue = []byte{lnwire.ExperimentalAccountable} + t := uint64(lnwire.ExperimentalAccountableType) sendReq.FirstHopCustomRecords = map[uint64][]byte{ t: expectedValue, } @@ -70,24 +70,24 @@ func testEndorsement(ht *lntest.HarnessTest, aliceEndorse bool) { // Validate that our signal (positive or zero) propagates until carol // and then is dropped because she has disabled the feature. - validateEndorsedAndResume(ht, bobIntercept, true, expectedValue) - validateEndorsedAndResume(ht, carolIntercept, true, expectedValue) - validateEndorsedAndResume(ht, daveIntercept, false, nil) + validateAccountableAndResume(ht, bobIntercept, true, expectedValue) + validateAccountableAndResume(ht, carolIntercept, true, expectedValue) + validateAccountableAndResume(ht, daveIntercept, false, nil) var preimage lntypes.Preimage copy(preimage[:], invoice.RPreimage) ht.AssertPaymentStatus(alice, preimage.Hash(), lnrpc.Payment_SUCCEEDED) } -func validateEndorsedAndResume(ht *lntest.HarnessTest, - interceptor rpc.InterceptorClient, hasEndorsement bool, +func validateAccountableAndResume(ht *lntest.HarnessTest, + interceptor rpc.InterceptorClient, hasAccountable bool, expectedValue []byte) { packet := ht.ReceiveHtlcInterceptor(interceptor) var expectedRecords map[uint64][]byte - if hasEndorsement { - u64Type := uint64(lnwire.ExperimentalEndorsementType) + if hasAccountable { + u64Type := uint64(lnwire.ExperimentalAccountableType) expectedRecords = map[uint64][]byte{ u64Type: expectedValue, } diff --git a/itest/lnd_forward_interceptor_test.go b/itest/lnd_forward_interceptor_test.go index 8eec171741..de8cc054a6 100644 --- a/itest/lnd_forward_interceptor_test.go +++ b/itest/lnd_forward_interceptor_test.go @@ -387,7 +387,7 @@ func testForwardInterceptorRestart(ht *lntest.HarnessTest) { // all intercepted packets. These packets are held to simulate a // pending payment. packet := ht.ReceiveHtlcInterceptor(bobInterceptor) - require.Equal(ht, lntest.CustomRecordsWithUnendorsed( + require.Equal(ht, lntest.CustomRecordsWithUnaccountable( customRecords, ), packet.InWireCustomRecords) @@ -433,11 +433,11 @@ func testForwardInterceptorRestart(ht *lntest.HarnessTest) { packet = ht.ReceiveHtlcInterceptor(bobInterceptor) require.Len(ht, packet.InWireCustomRecords, 2) - require.Equal(ht, lntest.CustomRecordsWithUnendorsed(customRecords), + require.Equal(ht, lntest.CustomRecordsWithUnaccountable(customRecords), packet.InWireCustomRecords) // And now we forward the payment at Carol, expecting only an - // endorsement signal in our incoming custom records. + // accountable signal in our incoming custom records. packet = ht.ReceiveHtlcInterceptor(carolInterceptor) require.Len(ht, packet.InWireCustomRecords, 1) err = carolInterceptor.Send(&routerrpc.ForwardHtlcInterceptResponse{ @@ -451,7 +451,7 @@ func testForwardInterceptorRestart(ht *lntest.HarnessTest) { alice, preimage.Hash(), lnrpc.Payment_SUCCEEDED, func(p *lnrpc.Payment) error { recordsEqual := reflect.DeepEqual( - lntest.CustomRecordsWithUnendorsed( + lntest.CustomRecordsWithUnaccountable( sendReq.FirstHopCustomRecords, ), p.FirstHopCustomRecords, ) diff --git a/itest/lnd_invoice_acceptor_test.go b/itest/lnd_invoice_acceptor_test.go index f7c617b250..4d5e30cc1b 100644 --- a/itest/lnd_invoice_acceptor_test.go +++ b/itest/lnd_invoice_acceptor_test.go @@ -102,9 +102,9 @@ func testInvoiceHtlcModifierBasic(ht *lntest.HarnessTest) { ht, tc.sendAmountMsat, modifierRequest.ExitHtlcAmt, ) - // Expect custom records plus endorsement signal. + // Expect custom records plus accountable signal. require.Equal( - ht, lntest.CustomRecordsWithUnendorsed( + ht, lntest.CustomRecordsWithUnaccountable( tc.lastHopCustomRecords, ), modifierRequest.ExitHtlcWireCustomRecords, ) @@ -152,7 +152,7 @@ func testInvoiceHtlcModifierBasic(ht *lntest.HarnessTest) { require.Len(ht, updatedInvoice.Htlcs, 1) require.Equal( - ht, lntest.CustomRecordsWithUnendorsed( + ht, lntest.CustomRecordsWithUnaccountable( tc.lastHopCustomRecords, ), updatedInvoice.Htlcs[0].CustomRecords, ) diff --git a/lncfg/protocol.go b/lncfg/protocol.go index 4d348b2154..fbfe26411b 100644 --- a/lncfg/protocol.go +++ b/lncfg/protocol.go @@ -71,8 +71,8 @@ type ProtocolOptions struct { // 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"` - // NoExperimentalEndorsementOption disables experimental endorsement. - NoExperimentalEndorsementOption bool `long:"no-experimental-endorsement" description:"do not forward experimental endorsement signals"` + // NoExperimentalAccountabilityOption disables experimental accountability. + NoExperimentalAccountabilityOption bool `long:"no-experimental-accountability" description:"do not forward experimental accountability signals"` // CustomMessage allows the custom message APIs to handle messages with // the provided protocol numbers, which fall outside the custom message @@ -139,10 +139,10 @@ func (l *ProtocolOptions) NoRouteBlinding() bool { return l.NoRouteBlindingOption } -// NoExperimentalEndorsement returns true if experimental endorsement should -// be disabled. -func (l *ProtocolOptions) NoExperimentalEndorsement() bool { - return l.NoExperimentalEndorsementOption +// NoExpAccountability returns true if experimental accountability should be +// disabled. +func (l *ProtocolOptions) NoExpAccountability() bool { + return l.NoExperimentalAccountabilityOption } // NoQuiescence returns true if quiescence is disabled. diff --git a/lncfg/protocol_integration.go b/lncfg/protocol_integration.go index c68d6ffe63..72a26ae8b0 100644 --- a/lncfg/protocol_integration.go +++ b/lncfg/protocol_integration.go @@ -74,8 +74,8 @@ type ProtocolOptions struct { // 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"` - // NoExperimentalEndorsementOption disables experimental endorsement. - NoExperimentalEndorsementOption bool `long:"no-experimental-endorsement" description:"do not forward experimental endorsement signals"` + // NoExperimentalAccountabilityOption disables experimental accountability. + NoExperimentalAccountabilityOption bool `long:"no-experimental-accountability" description:"do not forward experimental accountability signals"` // NoQuiescenceOption disables quiescence for all channels. 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 } -// NoExperimentalEndorsement returns true if experimental endorsement should -// be disabled. -func (l *ProtocolOptions) NoExperimentalEndorsement() bool { - return l.NoExperimentalEndorsementOption +// NoExpAccountability returns true if experimental accountability should be +// disabled. +func (l *ProtocolOptions) NoExpAccountability() bool { + return l.NoExperimentalAccountabilityOption } // NoQuiescence returns true if quiescence is disabled. diff --git a/lnrpc/routerrpc/router_backend.go b/lnrpc/routerrpc/router_backend.go index d19127f32b..bb63da0c34 100644 --- a/lnrpc/routerrpc/router_backend.go +++ b/lnrpc/routerrpc/router_backend.go @@ -117,9 +117,9 @@ type RouterBackend struct { // channel data from the first hop of a route. ParseCustomChannelData func(message proto.Message) error - // ShouldSetExpEndorsement returns a boolean indicating whether the - // experimental endorsement bit should be set. - ShouldSetExpEndorsement func() bool + // ShouldSetExpAccountability returns a boolean indicating whether the + // experimental accountability bit should be set. + ShouldSetExpAccountability func() bool // Clock is the clock used to validate payment requests expiry. // It is useful for testing. @@ -942,19 +942,19 @@ func (r *RouterBackend) extractIntentFromSendRequest( } 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. - if r.ShouldSetExpEndorsement() { + if r.ShouldSetExpAccountability() { if payIntent.FirstHopCustomRecords == nil { payIntent.FirstHopCustomRecords = make( map[uint64][]byte, ) } - t := uint64(lnwire.ExperimentalEndorsementType) + t := uint64(lnwire.ExperimentalAccountableType) if _, set := payIntent.FirstHopCustomRecords[t]; !set { payIntent.FirstHopCustomRecords[t] = []byte{ - lnwire.ExperimentalUnendorsed, + lnwire.ExperimentalUnaccountable, } } } diff --git a/lnrpc/routerrpc/router_backend_test.go b/lnrpc/routerrpc/router_backend_test.go index a1095a36c8..373b929839 100644 --- a/lnrpc/routerrpc/router_backend_test.go +++ b/lnrpc/routerrpc/router_backend_test.go @@ -677,7 +677,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) { { name: "Amount conflict, both sat and msat specified", backend: &RouterBackend{ - ShouldSetExpEndorsement: func() bool { + ShouldSetExpAccountability: func() bool { return true }, }, @@ -692,7 +692,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) { { name: "Both dest and payment_request provided", backend: &RouterBackend{ - ShouldSetExpEndorsement: func() bool { + ShouldSetExpAccountability: func() bool { return false }, }, @@ -708,7 +708,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) { { name: "Both payment_hash and payment_request provided", backend: &RouterBackend{ - ShouldSetExpEndorsement: func() bool { + ShouldSetExpAccountability: func() bool { return false }, }, @@ -725,7 +725,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) { name: "Both final_cltv_delta and payment_request " + "provided", backend: &RouterBackend{ - ShouldSetExpEndorsement: func() bool { + ShouldSetExpAccountability: func() bool { return false }, }, @@ -741,7 +741,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) { { name: "Invalid payment request length", backend: &RouterBackend{ - ShouldSetExpEndorsement: func() bool { + ShouldSetExpAccountability: func() bool { return false }, ActiveNetParams: &chaincfg.RegressionNetParams, @@ -756,7 +756,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) { { name: "Expired invoice payment request", backend: &RouterBackend{ - ShouldSetExpEndorsement: func() bool { + ShouldSetExpAccountability: func() bool { return false }, ActiveNetParams: &chaincfg.RegressionNetParams, @@ -772,7 +772,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) { { name: "Invoice missing payment address", backend: &RouterBackend{ - ShouldSetExpEndorsement: func() bool { + ShouldSetExpAccountability: func() bool { return false }, ActiveNetParams: &chaincfg.RegressionNetParams, @@ -789,7 +789,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) { { name: "Invalid dest vertex length", backend: &RouterBackend{ - ShouldSetExpEndorsement: func() bool { + ShouldSetExpAccountability: func() bool { return false }, }, @@ -803,7 +803,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) { { name: "Payment request with missing amount", backend: &RouterBackend{ - ShouldSetExpEndorsement: func() bool { + ShouldSetExpAccountability: func() bool { return false }, }, @@ -817,7 +817,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) { { name: "Destination lacks AMP support", backend: &RouterBackend{ - ShouldSetExpEndorsement: func() bool { + ShouldSetExpAccountability: func() bool { return false }, }, @@ -834,7 +834,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) { { name: "Invalid payment hash length", backend: &RouterBackend{ - ShouldSetExpEndorsement: func() bool { + ShouldSetExpAccountability: func() bool { return false }, }, @@ -849,7 +849,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) { { name: "Payment amount exceeds maximum possible amount", backend: &RouterBackend{ - ShouldSetExpEndorsement: func() bool { + ShouldSetExpAccountability: func() bool { return false }, }, @@ -868,7 +868,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) { name: "Reject self-payments if not permitted", backend: &RouterBackend{ MaxTotalTimelock: 1000, - ShouldSetExpEndorsement: func() bool { + ShouldSetExpAccountability: func() bool { return false }, SelfNode: target, @@ -885,7 +885,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) { name: "Required and optional feature bits set", backend: &RouterBackend{ MaxTotalTimelock: 1000, - ShouldSetExpEndorsement: func() bool { + ShouldSetExpAccountability: func() bool { return false }, }, @@ -906,7 +906,7 @@ func TestExtractIntentFromSendRequest(t *testing.T) { name: "Valid send req parameters, payment settled", backend: &RouterBackend{ MaxTotalTimelock: 1000, - ShouldSetExpEndorsement: func() bool { + ShouldSetExpAccountability: func() bool { return false }, }, diff --git a/lntest/utils.go b/lntest/utils.go index a07b064369..406e37a4ef 100644 --- a/lntest/utils.go +++ b/lntest/utils.go @@ -283,14 +283,15 @@ func CalcStaticFeeBuffer(c lnrpc.CommitmentType, numHTLCs int) btcutil.Amount { return feeBuffer.ToSatoshis() } -// CustomRecordsWithUnendorsed copies the map of custom records and adds an -// endorsed signal (replacing in the case of conflict) for assertion in tests. -func CustomRecordsWithUnendorsed( +// CustomRecordsWithUnaccountable copies the map of custom records and adds an +// accountable signal (replacing in the case of conflict) for assertion in +// tests. +func CustomRecordsWithUnaccountable( originalRecords lnwire.CustomRecords) map[uint64][]byte { return originalRecords.MergedCopy(map[uint64][]byte{ - uint64(lnwire.ExperimentalEndorsementType): { - lnwire.ExperimentalUnendorsed, + uint64(lnwire.ExperimentalAccountableType): { + lnwire.ExperimentalUnaccountable, }}, ) } diff --git a/lnwire/features.go b/lnwire/features.go index 107828ee20..4e927e170b 100644 --- a/lnwire/features.go +++ b/lnwire/features.go @@ -289,13 +289,15 @@ const ( // being finalized. SimpleTaprootChannelsOptionalStaging = 181 - // ExperimentalEndorsementRequired is a required feature bit that - // indicates that the node will relay experimental endorsement signals. - ExperimentalEndorsementRequired FeatureBit = 260 + // ExperimentalAccountabilityRequired is a required feature bit that + // indicates that the node will relay experimental accountability + // signals. + ExperimentalAccountabilityRequired FeatureBit = 260 - // ExperimentalEndorsementOptional is an optional feature bit that - // indicates that the node will relay experimental endorsement signals. - ExperimentalEndorsementOptional FeatureBit = 261 + // ExperimentalAccountabilityOptional is an optional feature bit that + // indicates that the node will relay experimental accountability + // signals. + ExperimentalAccountabilityOptional FeatureBit = 261 // Bolt11BlindedPathsRequired is a required feature bit that indicates // 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", SimpleTaprootOverlayChansOptional: "taproot-overlay-chans", SimpleTaprootOverlayChansRequired: "taproot-overlay-chans", - ExperimentalEndorsementRequired: "endorsement-x", - ExperimentalEndorsementOptional: "endorsement-x", + ExperimentalAccountabilityRequired: "accountable-x", + ExperimentalAccountabilityOptional: "accountable-x", Bolt11BlindedPathsOptional: "bolt-11-blinded-paths", Bolt11BlindedPathsRequired: "bolt-11-blinded-paths", RbfCoopCloseOptional: "rbf-coop-close", diff --git a/lnwire/update_add_htlc.go b/lnwire/update_add_htlc.go index e627dbf4e6..38ceeec214 100644 --- a/lnwire/update_add_htlc.go +++ b/lnwire/update_add_htlc.go @@ -16,20 +16,21 @@ const ( // entire packet. OnionPacketSize = 1366 - // ExperimentalEndorsementType is the TLV type used for a custom - // record that sets an experimental endorsement value. - ExperimentalEndorsementType tlv.Type = 106823 - - // ExperimentalUnendorsed is the value that the experimental endorsement - // field contains when a htlc is not endorsed. - ExperimentalUnendorsed = 0 - - // ExperimentalEndorsed is the value that the experimental endorsement - // field contains when a htlc is endorsed. We're using a single byte - // to represent our endorsement value, but limit the value to using - // the first three bits (max value = 00000111). Interpreted as a uint8 - // (an alias for byte in go), we can just define this constant as 7. - ExperimentalEndorsed = 7 + // ExperimentalAccountableType is the TLV type used for a custom + // record that sets an experimental accountable value. + ExperimentalAccountableType tlv.Type = 106823 + + // ExperimentalUnaccountable is the value that the experimental + // accountable field contains when a htlc is not accountable. + ExperimentalUnaccountable = 0 + + // ExperimentalAccountable is the value that the experimental + // accountable field contains when a htlc is accountable. We're using a + // single byte to represent our accountable value, but limit the value + // to using the first three bits (max value = 00000111). Interpreted as + // a uint8 (an alias for byte in go), we can just define this constant + // as 7. + ExperimentalAccountable = 7 ) type ( diff --git a/peer/brontide.go b/peer/brontide.go index 8d02ca6e53..73c5acda48 100644 --- a/peer/brontide.go +++ b/peer/brontide.go @@ -468,9 +468,9 @@ type Config struct { // onion messages to subscribers. OnionMessageServer *subscribe.Server - // ShouldFwdExpEndorsement is a closure that indicates whether - // experimental endorsement signals should be set. - ShouldFwdExpEndorsement func() bool + // ShouldFwdExpAccountability is a closure that indicates whether + // experimental accountability signals should be set. + ShouldFwdExpAccountability func() bool // NoDisconnectOnPongFailure indicates whether the peer should *not* be // 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( p.cfg.PendingCommitInterval, ), - BatchSize: p.cfg.ChannelCommitBatchSize, - UnsafeReplay: p.cfg.UnsafeReplay, - MinUpdateTimeout: htlcswitch.DefaultMinLinkFeeUpdateTimeout, - MaxUpdateTimeout: htlcswitch.DefaultMaxLinkFeeUpdateTimeout, - OutgoingCltvRejectDelta: p.cfg.OutgoingCltvRejectDelta, - TowerClient: p.cfg.TowerClient, - MaxOutgoingCltvExpiry: p.cfg.MaxOutgoingCltvExpiry, - MaxFeeAllocation: p.cfg.MaxChannelFeeAllocation, - MaxAnchorsCommitFeeRate: p.cfg.MaxAnchorsCommitFeeRate, - NotifyActiveLink: p.cfg.ChannelNotifier.NotifyActiveLinkEvent, - NotifyActiveChannel: p.cfg.ChannelNotifier.NotifyActiveChannelEvent, - NotifyInactiveChannel: p.cfg.ChannelNotifier.NotifyInactiveChannelEvent, - NotifyInactiveLinkEvent: p.cfg.ChannelNotifier.NotifyInactiveLinkEvent, - HtlcNotifier: p.cfg.HtlcNotifier, - GetAliases: p.cfg.GetAliases, - PreviouslySentShutdown: shutdownMsg, - DisallowRouteBlinding: p.cfg.DisallowRouteBlinding, - MaxFeeExposure: p.cfg.MaxFeeExposure, - ShouldFwdExpEndorsement: p.cfg.ShouldFwdExpEndorsement, + BatchSize: p.cfg.ChannelCommitBatchSize, + UnsafeReplay: p.cfg.UnsafeReplay, + MinUpdateTimeout: htlcswitch.DefaultMinLinkFeeUpdateTimeout, + MaxUpdateTimeout: htlcswitch.DefaultMaxLinkFeeUpdateTimeout, + OutgoingCltvRejectDelta: p.cfg.OutgoingCltvRejectDelta, + TowerClient: p.cfg.TowerClient, + MaxOutgoingCltvExpiry: p.cfg.MaxOutgoingCltvExpiry, + MaxFeeAllocation: p.cfg.MaxChannelFeeAllocation, + MaxAnchorsCommitFeeRate: p.cfg.MaxAnchorsCommitFeeRate, + NotifyActiveLink: p.cfg.ChannelNotifier.NotifyActiveLinkEvent, + NotifyActiveChannel: p.cfg.ChannelNotifier.NotifyActiveChannelEvent, + NotifyInactiveChannel: p.cfg.ChannelNotifier.NotifyInactiveChannelEvent, + NotifyInactiveLinkEvent: p.cfg.ChannelNotifier.NotifyInactiveLinkEvent, + HtlcNotifier: p.cfg.HtlcNotifier, + GetAliases: p.cfg.GetAliases, + PreviouslySentShutdown: shutdownMsg, + DisallowRouteBlinding: p.cfg.DisallowRouteBlinding, + MaxFeeExposure: p.cfg.MaxFeeExposure, + ShouldFwdExpAccountability: p.cfg.ShouldFwdExpAccountability, DisallowQuiescence: p.cfg.DisallowQuiescence || !p.remoteFeatures.HasFeature(lnwire.QuiescenceOptional), AuxTrafficShaper: p.cfg.AuxTrafficShaper, diff --git a/routing/route/route.go b/routing/route/route.go index 349a2bc9bd..7d7e2a2a3c 100644 --- a/routing/route/route.go +++ b/routing/route/route.go @@ -526,7 +526,7 @@ type Route struct { // FirstHopWireCustomRecords is a set of custom records that should be // included in the wire message sent to the first hop. This is for // 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. // // NOTE: Since these records already represent TLV records, and we diff --git a/rpcserver.go b/rpcserver.go index ee810d1e1e..89940c219b 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -774,14 +774,8 @@ func (r *rpcServer) addDeps(ctx context.Context, s *server, return nil }, - ShouldSetExpEndorsement: func() bool { - if s.cfg.ProtocolOptions.NoExperimentalEndorsement() { - return false - } - - return clock.NewDefaultClock().Now().Before( - EndorsementExperimentEnd, - ) + ShouldSetExpAccountability: func() bool { + return !s.cfg.ProtocolOptions.NoExpAccountability() }, } diff --git a/sample-lnd.conf b/sample-lnd.conf index ed5dabd43c..c0a5cd7ff0 100644 --- a/sample-lnd.conf +++ b/sample-lnd.conf @@ -1440,8 +1440,8 @@ ; Set to disable blinded route forwarding. ; protocol.no-route-blinding=false -; Set to disable experimental endorsement signaling. -; protocol.no-experimental-endorsement=false +; Set to disable experimental accountability signaling. +; protocol.no-experimental-accountability=false ; Set to enable support for RBF based coop close. ; protocol.rbf-coop-close=false diff --git a/server.go b/server.go index 3c011f8b0b..5656087cf9 100644 --- a/server.go +++ b/server.go @@ -139,12 +139,6 @@ var ( // TODO(roasbeef): add command line param to modify. 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 // attempt to finalize a connection to a remote peer. 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 featureMgr, err := feature.NewManager(feature.Config{ - NoTLVOnion: cfg.ProtocolOptions.LegacyOnion(), - NoStaticRemoteKey: cfg.ProtocolOptions.NoStaticRemoteKey(), - NoAnchors: cfg.ProtocolOptions.NoAnchorCommitments(), - NoWumbo: !cfg.ProtocolOptions.Wumbo(), - NoScriptEnforcementLease: cfg.ProtocolOptions.NoScriptEnforcementLease(), - NoKeysend: !cfg.AcceptKeySend, - NoOptionScidAlias: !cfg.ProtocolOptions.ScidAlias(), - NoZeroConf: !cfg.ProtocolOptions.ZeroConf(), - NoAnySegwit: cfg.ProtocolOptions.NoAnySegwit(), - CustomFeatures: cfg.ProtocolOptions.CustomFeatures(), - NoTaprootChans: !cfg.ProtocolOptions.TaprootChans, - NoTaprootOverlay: !cfg.ProtocolOptions.TaprootOverlayChans, - NoRouteBlinding: cfg.ProtocolOptions.NoRouteBlinding(), - NoExperimentalEndorsement: cfg.ProtocolOptions.NoExperimentalEndorsement(), - NoQuiescence: cfg.ProtocolOptions.NoQuiescence(), - NoRbfCoopClose: !cfg.ProtocolOptions.RbfCoopClose, + NoTLVOnion: cfg.ProtocolOptions.LegacyOnion(), + NoStaticRemoteKey: cfg.ProtocolOptions.NoStaticRemoteKey(), + NoAnchors: cfg.ProtocolOptions.NoAnchorCommitments(), + NoWumbo: !cfg.ProtocolOptions.Wumbo(), + NoScriptEnforcementLease: cfg.ProtocolOptions.NoScriptEnforcementLease(), + NoKeysend: !cfg.AcceptKeySend, + NoOptionScidAlias: !cfg.ProtocolOptions.ScidAlias(), + NoZeroConf: !cfg.ProtocolOptions.ZeroConf(), + NoAnySegwit: cfg.ProtocolOptions.NoAnySegwit(), + CustomFeatures: cfg.ProtocolOptions.CustomFeatures(), + NoTaprootChans: !cfg.ProtocolOptions.TaprootChans, + NoTaprootOverlay: !cfg.ProtocolOptions.TaprootOverlayChans, + NoRouteBlinding: cfg.ProtocolOptions.NoRouteBlinding(), + NoExperimentalAccountability: cfg.ProtocolOptions.NoExpAccountability(), + NoQuiescence: cfg.ProtocolOptions.NoQuiescence(), + NoRbfCoopClose: !cfg.ProtocolOptions.RbfCoopClose, }) if err != nil { return nil, err @@ -4431,14 +4425,8 @@ func (s *server) peerConnected(conn net.Conn, connReq *connmgr.ConnReq, AuxResolver: s.implCfg.AuxContractResolver, AuxTrafficShaper: s.implCfg.TrafficShaper, AuxChannelNegotiator: s.implCfg.AuxChannelNegotiator, - ShouldFwdExpEndorsement: func() bool { - if s.cfg.ProtocolOptions.NoExperimentalEndorsement() { - return false - } - - return clock.NewDefaultClock().Now().Before( - EndorsementExperimentEnd, - ) + ShouldFwdExpAccountability: func() bool { + return !s.cfg.ProtocolOptions.NoExpAccountability() }, NoDisconnectOnPongFailure: s.cfg.NoDisconnectOnPongFailure, }