lnwallet: add noop updateType to paymendDescriptor
What changed, and why it matters
This commit adds a new internal bookkeeping label called NoOpAdd for a special kind of Lightning payment. The label marks HTLCs whose funds can return to the sender when settled, instead of always going to the receiver. The change only defines the label and makes existing log/commitment logic treat it like a normal Add. There is no actual implementation of the new behavior here, and the commit message says the feature must be explicitly enabled by external software. On its own, this patch does not appear to introduce a vulnerability, but it is a partial change that future code will build on.
Treat this as a feature foundation commit, not a security fix or vulnerability. Review the follow-up commits that implement NoOpAdd settlement logic, reserve checks, and external signaling to ensure funds cannot be incorrectly returned to senders or used to bypass channel reserve requirements. No immediate action is required for this commit alone.
Security signals we found
New HTLC update type with non-standard balance semantics (potential return-to-sender on settle)
Settlement behavior depends on channel reserve status, which is a safety-critical invariant
Feature is gated by external software signal per commit message, but no gating code is visible in this diff
Partial implementation: only enum and switch-case plumbing; actual logic is in future commits
Evidence from the diff
The patch introduces a new updateType constant NoOpAdd in lnwallet/payment_descriptor.go and updates the String() method and two switch statements (toLogUpdate and setCommitHeight) to handle it alongside the existing Add type. The comment explains that NoOpAdd differs from Add because, on settlement, the balance may revert to the sender depending on whether the receiver is above the channel reserve. The commit message states this HTLC type is only set if explicitly signalled by external software. No logic for the new settlement rule, reserve check, or external signaling is present in this commit.
Changed components
lnwallet/payment_descriptor.goupdateType enum and String() methodpaymentDescriptor.toLogUpdate()paymentDescriptor.setCommitHeight()Inspect captured patch +11 / −2
diff --git a/lnwallet/payment_descriptor.go b/lnwallet/payment_descriptor.go
index 49b79a1..3f4b9dd 100644
--- a/lnwallet/payment_descriptor.go
+++ b/lnwallet/payment_descriptor.go
@@ -42,6 +42,13 @@ const (
// FeeUpdate is an update type sent by the channel initiator that
// updates the fee rate used when signing the commitment transaction.
FeeUpdate
+
+ // NoOpAdd is an update type that adds a new HTLC entry into the log.
+ // This differs from the normal Add type, in that when settled the
+ // balance may go back to the sender, rather than be credited for the
+ // receiver. The criteria about whether the balance will go back to the
+ // sender is whether the receiver is sitting above the channel reserve.
+ NoOpAdd
)
// String returns a human readable string that uniquely identifies the target
@@ -58,6 +65,8 @@ func (u updateType) String() string {
return "Settle"
case FeeUpdate:
return "FeeUpdate"
+ case NoOpAdd:
+ return "NoOpAdd"
default:
return "<unknown type>"
}
@@ -238,7 +247,7 @@ type paymentDescriptor struct {
func (pd *paymentDescriptor) toLogUpdate() channeldb.LogUpdate {
var msg lnwire.Message
switch pd.EntryType {
- case Add:
+ case Add, NoOpAdd:
msg = &lnwire.UpdateAddHTLC{
ChanID: pd.ChanID,
ID: pd.HtlcIndex,
@@ -290,7 +299,7 @@ func (pd *paymentDescriptor) setCommitHeight(
whoseCommitChain lntypes.ChannelParty, nextHeight uint64) {
switch pd.EntryType {
- case Add:
+ case Add, NoOpAdd:
pd.addCommitHeights.SetForParty(
whoseCommitChain, nextHeight,
)
Why this scored 16/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.