Skip to content

Conversation

@elnosh
Copy link
Contributor

@elnosh elnosh commented Nov 13, 2025

This PR renames bLIP4's experimental endorsement signal to accountable to match the latest proposal in lightning/blips#67

@gemini-code-assist
Copy link

Summary of Changes

Hello @elnosh, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request implements a comprehensive renaming of the experimental endorsement signal to accountable. This change is crucial for aligning the codebase with the latest BLIP-0004 proposal, ensuring that the terminology used for this experimental feature is consistent and up-to-date across all relevant components, including feature management, HTLC forwarding logic, configuration, and testing infrastructure.

Highlights

  • Terminology Update: The experimental endorsement signal has been renamed to accountable across the entire codebase to align with the latest BLIP-0004 proposal.
  • Configuration Alignment: Configuration options, feature bits, and command-line flags related to this experimental signal have been updated to reflect the new accountable terminology.
  • Codebase Consistency: All relevant function names, variable names, constants, and test cases have been refactored to use the accountable term, ensuring consistency throughout the project.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request correctly renames the experimental endorsement feature to accountable to align with the latest bLIP-4 proposal. The changes are applied consistently across the entire codebase, including configuration options, feature flags, internal logic, and tests. I've also noted the removal of the time-based experiment logic for this feature, which is a correct interpretation of the updated proposal. The code quality is high, and I have no further comments. The changes look good to merge.

@carlaKC carlaKC self-requested a review November 13, 2025 16:36
Copy link
Collaborator

@carlaKC carlaKC left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for bringing this up to date!

Linter is unhappy in a few places because renames push over the 80 char limit, and needs an entry in release notes, otherwise LGTM!

SetNodeAnn: {}, // N
},
lnwire.ExperimentalEndorsementOptional: {
lnwire.ExperimentalAccountabilityOptional: {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: one mention of endorsement left in comment.

rpcserver.go Outdated
return clock.NewDefaultClock().Now().Before(
AccountabilityExperimentEnd,
)
return !s.cfg.ProtocolOptions.NoExperimentalAccountability()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

linter unhappy: perhaps NoExpAccountability to shorten line

@elnosh elnosh force-pushed the rename-endorsement-accountable branch 3 times, most recently from 19f31ec to 73d1e41 Compare November 19, 2025 16:05
Copy link
Collaborator

@carlaKC carlaKC left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tACK, tested sending + relaying of zero value signal.

@Roasbeef
Copy link
Member

Approved the CI run.

@saubyk saubyk added this to the v0.21.0 milestone Dec 10, 2025
@saubyk saubyk added this to v0.21 Dec 10, 2025
@saubyk saubyk moved this to In progress in v0.21 Dec 10, 2025
@saubyk saubyk moved this from In progress to In review in v0.21 Dec 10, 2025
Copy link
Member

@Roasbeef Roasbeef left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 💎

// 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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this comment is outdated, it does not return a boolean ?

// experimental accountable field, and a boolean indicating whether it should
// be populated on the outgoing htlc.
func (l *channelLink) experimentalEndorsement(
func (l *channelLink) experimentalAccountability(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we ok that basically this check resets the whole CustomRecord froward TLV in case no Accuntability bit is set? Probably not a problem now since it is not used for anything but I think this should be more fine granular in the future ? This seems to remove the old customRecord data and replaces it with the single lnwire.ExperimentalUnaccountable value can you verifiy @gemini-code-assist

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You've accurately identified a potential issue, @ziggie1984. The current implementation of processRemoteAdds (in htlcswitch/link.go, specifically around lines 3194-3199 and 3252-3255) indeed overwrites the entire outgoingAdd.CustomRecords map with only the ExperimentalAccountableType TLV if experimentalAccountability returns a value (which it does if forwarding is enabled, even if the incoming HTLC didn't have the accountability bit set or had an invalid one).

This means any other custom records present in the incoming HTLC would be lost when forwarding. To prevent this, the outgoingAdd.CustomRecords should be initialized with a copy of the incoming add.CustomRecords before adding or updating the ExperimentalAccountableType.

You can use the record.CustomSet.Copy() method to create a mutable copy of the existing custom records. The corrected logic would look something like this:

For lines 3194-3199:

				accountableValue.WhenSome(func(e byte) {
					// Create a mutable copy of the incoming custom records.
					custRecords := add.CustomRecords.Copy()
					custRecords[accountableType] = []byte{e}
					outgoingAdd.CustomRecords = custRecords
				})

And similarly for lines 3252-3255:

			accountableValue.WhenSome(func(e byte) {
				// Create a mutable copy of the incoming custom records.
				custRecords := add.CustomRecords.Copy()
				custRecords[accountableType] = []byte{e}
				addMsg.CustomRecords = custRecords
			})

This ensures that only the ExperimentalAccountableType is modified or added, while preserving any other custom records.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you clarify? I'm not seeing the custom records passed to experimentalAccountability reset if the accountability bit is not set.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so currently I think we do not forward any customRecords so it is fine but look at the code, as soon as this option has a value:

endorseValue := l.experimentalEndorsement(

we would replace the complete custome records and in the above function we do not merge any custom records we just set the Endorse or Unendorse Bit:

outgoingAdd.CustomRecords = custRecords

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah I was referring to when it is set, we would overwrite all values which were there in the first place and set only the endorseBit/unendorse

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, ok. As you said, seems fine given that at that point the outgoingAdd.CustomRecords is nil since outgoingAdd was set just up above in

outgoingAdd := &lnwire.UpdateAddHTLC{
with the CustomRecords not set. But lmk if you'd want me to change it

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you maybe add in the experimentalEndorsement func comment that this only considers the endorsement bit, and any other custom records present will not be forwarded ?

Can you also rebase!

@lightninglabs-deploy
Copy link

@elnosh, remember to re-request review from reviewers when ready

@elnosh elnosh force-pushed the rename-endorsement-accountable branch 3 times, most recently from 4d43f53 to 28b234b Compare January 5, 2026 18:59
server.go Outdated
//
// Per blip04: January 1, 2026 12:00:00 AM UTC in unix seconds.
EndorsementExperimentEnd = time.Unix(1767225600, 0)
AccountabilityExperimentEnd = time.Unix(1767225600, 0)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there plans to remove the experiment from the code, we are now renaming things and the experiment is actually over so is it really worth it comes to my mind. What are the plans there ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah we can just remove this now.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are the plans there ?

The acinq node is collecting data including this signal, and LDK is going to start actively setting the signal so ideally we'd continue to relay these values so we can start fine-tuning parameters for the BOLT PR. Assuming that we're heading in a direction that this proposal is going to be adopted, I think it's reasonable to just deprecate the experimental signal when the BOLT PR is in?

@ziggie1984
Copy link
Collaborator

@elnosh the linter is still failing

Copy link
Collaborator

@ziggie1984 ziggie1984 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (pending linter fix)

elnosh added 2 commits January 6, 2026 09:12
Renames the endorsement signal to accountable to
match the latest proposal lightning/blips#67
In the previous iteration with endorsement
signaling, the recommendation was for the sender to
set it to 1 and that could have had privacy concerns
when first deploying given that the default was to
downgrade the signal to 0. In the latest proposal
the recommended default for both sending and
forwarding nodes is to set `accountable` to 0.
As a result, the dates have been removed given
that there are no privacy risks associated
with relaying the signal with zero values.
@elnosh elnosh force-pushed the rename-endorsement-accountable branch from 28b234b to 6f49bea Compare January 6, 2026 14:13
@ziggie1984 ziggie1984 added the backport-v0.20.x-branch This label is used to trigger the creation of a backport PR to the branch `v0.20.x-branch`. label Jan 6, 2026
@ziggie1984 ziggie1984 removed the backport-v0.20.x-branch This label is used to trigger the creation of a backport PR to the branch `v0.20.x-branch`. label Jan 6, 2026
@ziggie1984 ziggie1984 merged commit 99d07fd into lightningnetwork:master Jan 6, 2026
42 checks passed
@github-project-automation github-project-automation bot moved this from In review to Done in v0.21 Jan 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

6 participants