lnwire: add blinding point to update_add_htlc TLVs

Add blinding points to update_add_htlc. This TLV will be set for
nodes that are relaying payments in blinded routes that are _not_
the introduction node.
This commit is contained in:
Carla Kirk-Cohen committed 2024-03-27 09:38:50 -04:00
1 parent d8979d3086
commit e4f90ec593
5 files changed
+111 -17

No files matched your search

+7 -11
View File
@@ -651,8 +651,7 @@ func TestChannelStateTransition(t *testing.T) {
{ {
LogIndex: 2, LogIndex: 2,
UpdateMsg: &lnwire.UpdateAddHTLC{ UpdateMsg: &lnwire.UpdateAddHTLC{
ChanID: lnwire.ChannelID{1, 2, 3}, ChanID: lnwire.ChannelID{1, 2, 3},
ExtraData: make([]byte, 0),
}, },
}, },
} }
@@ -710,25 +709,22 @@ func TestChannelStateTransition(t *testing.T) {
wireSig, wireSig,
wireSig, wireSig,
}, },
ExtraData: make([]byte, 0),
}, },
LogUpdates: []LogUpdate{ LogUpdates: []LogUpdate{
{ {
LogIndex: 1, LogIndex: 1,
UpdateMsg: &lnwire.UpdateAddHTLC{ UpdateMsg: &lnwire.UpdateAddHTLC{
ID: 1, ID: 1,
Amount: lnwire.NewMSatFromSatoshis(100), Amount: lnwire.NewMSatFromSatoshis(100),
Expiry: 25, Expiry: 25,
ExtraData: make([]byte, 0),
}, },
}, },
{ {
LogIndex: 2, LogIndex: 2,
UpdateMsg: &lnwire.UpdateAddHTLC{ UpdateMsg: &lnwire.UpdateAddHTLC{
ID: 2, ID: 2,
Amount: lnwire.NewMSatFromSatoshis(200), Amount: lnwire.NewMSatFromSatoshis(200),
Expiry: 50, Expiry: 50,
ExtraData: make([]byte, 0),
}, },
}, },
}, },
-2
View File
@@ -3037,7 +3037,6 @@ func TestChanSyncOweCommitment(t *testing.T) {
Amount: htlcAmt, Amount: htlcAmt,
Expiry: uint32(10), Expiry: uint32(10),
OnionBlob: fakeOnionBlob, OnionBlob: fakeOnionBlob,
ExtraData: make([]byte, 0),
} }
htlcIndex, err := bobChannel.AddHTLC(h, nil) htlcIndex, err := bobChannel.AddHTLC(h, nil)
@@ -3082,7 +3081,6 @@ func TestChanSyncOweCommitment(t *testing.T) {
Amount: htlcAmt, Amount: htlcAmt,
Expiry: uint32(10), Expiry: uint32(10),
OnionBlob: fakeOnionBlob, OnionBlob: fakeOnionBlob,
ExtraData: make([]byte, 0),
} }
aliceHtlcIndex, err := aliceChannel.AddHTLC(aliceHtlc, nil) aliceHtlcIndex, err := aliceChannel.AddHTLC(aliceHtlc, nil)
require.NoError(t, err, "unable to add alice's htlc") require.NoError(t, err, "unable to add alice's htlc")
+36
View File
@@ -1337,6 +1337,42 @@ func TestLightningWireProtocol(t *testing.T) {
v[0] = reflect.ValueOf(req) v[0] = reflect.ValueOf(req)
}, },
MsgUpdateAddHTLC: func(v []reflect.Value, r *rand.Rand) {
req := &UpdateAddHTLC{
ID: r.Uint64(),
Amount: MilliSatoshi(r.Uint64()),
Expiry: r.Uint32(),
}
_, err := r.Read(req.ChanID[:])
require.NoError(t, err)
_, err = r.Read(req.PaymentHash[:])
require.NoError(t, err)
_, err = r.Read(req.OnionBlob[:])
require.NoError(t, err)
// Generate a blinding point 50% of the time, since not
// all update adds will use route blinding.
if r.Int31()%2 == 0 {
pubkey, err := randPubKey()
if err != nil {
t.Fatalf("unable to generate key: %v",
err)
return
}
req.BlindingPoint = tlv.SomeRecordT(
tlv.NewPrimitiveRecord[tlv.TlvType0](
pubkey,
),
)
}
v[0] = reflect.ValueOf(*req)
},
} }
// With the above types defined, we'll now generate a slice of // With the above types defined, we'll now generate a slice of
+54 -2
View File
@@ -3,6 +3,9 @@ package lnwire
import ( import (
"bytes" "bytes"
"io" "io"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/lightningnetwork/lnd/tlv"
) )
// OnionPacketSize is the size of the serialized Sphinx onion packet included // OnionPacketSize is the size of the serialized Sphinx onion packet included
@@ -11,6 +14,17 @@ import (
// of per-hop data, and a 32-byte HMAC over the entire packet. // of per-hop data, and a 32-byte HMAC over the entire packet.
const OnionPacketSize = 1366 const OnionPacketSize = 1366
type (
// BlindingPointTlvType is the type for ephemeral pubkeys used in
// route blinding.
BlindingPointTlvType = tlv.TlvType0
// BlindingPointRecord holds an optional blinding point on update add
// htlc.
//nolint:lll
BlindingPointRecord = tlv.OptionalRecordT[BlindingPointTlvType, *btcec.PublicKey]
)
// UpdateAddHTLC is the message sent by Alice to Bob when she wishes to add an // UpdateAddHTLC is the message sent by Alice to Bob when she wishes to add an
// HTLC to his remote commitment transaction. In addition to information // HTLC to his remote commitment transaction. In addition to information
// detailing the value, the ID, expiry, and the onion blob is also included // detailing the value, the ID, expiry, and the onion blob is also included
@@ -54,6 +68,10 @@ type UpdateAddHTLC struct {
// used in the subsequent UpdateAddHTLC message. // used in the subsequent UpdateAddHTLC message.
OnionBlob [OnionPacketSize]byte OnionBlob [OnionPacketSize]byte
// BlindingPoint is the ephemeral pubkey used to optionally blind the
// next hop for this htlc.
BlindingPoint BlindingPointRecord
// ExtraData is the set of data that was appended to this message to // ExtraData is the set of data that was appended to this message to
// fill out the full maximum transport message size. These fields can // fill out the full maximum transport message size. These fields can
// be used to specify optional data such as custom TLV fields. // be used to specify optional data such as custom TLV fields.
@@ -74,7 +92,7 @@ var _ Message = (*UpdateAddHTLC)(nil)
// //
// This is part of the lnwire.Message interface. // This is part of the lnwire.Message interface.
func (c *UpdateAddHTLC) Decode(r io.Reader, pver uint32) error { func (c *UpdateAddHTLC) Decode(r io.Reader, pver uint32) error {
return ReadElements(r, if err := ReadElements(r,
&c.ChanID, &c.ChanID,
&c.ID, &c.ID,
&c.Amount, &c.Amount,
@@ -82,7 +100,27 @@ func (c *UpdateAddHTLC) Decode(r io.Reader, pver uint32) error {
&c.Expiry, &c.Expiry,
c.OnionBlob[:], c.OnionBlob[:],
&c.ExtraData, &c.ExtraData,
) ); err != nil {
return err
}
blindingRecord := c.BlindingPoint.Zero()
tlvMap, err := c.ExtraData.ExtractRecords(&blindingRecord)
if err != nil {
return err
}
if val, ok := tlvMap[c.BlindingPoint.TlvType()]; ok && val == nil {
c.BlindingPoint = tlv.SomeRecordT(blindingRecord)
}
// Set extra data to nil if we didn't parse anything out of it so that
// we can use assert.Equal in tests.
if len(tlvMap) == 0 {
c.ExtraData = nil
}
return nil
} }
// Encode serializes the target UpdateAddHTLC into the passed io.Writer // Encode serializes the target UpdateAddHTLC into the passed io.Writer
@@ -114,6 +152,20 @@ func (c *UpdateAddHTLC) Encode(w *bytes.Buffer, pver uint32) error {
return err return err
} }
// Only include blinding point in extra data if present.
var records []tlv.RecordProducer
c.BlindingPoint.WhenSome(func(b tlv.RecordT[BlindingPointTlvType,
*btcec.PublicKey]) {
records = append(records, &b)
})
err := EncodeMessageExtraData(&c.ExtraData, records...)
if err != nil {
return err
}
return WriteBytes(w, c.ExtraData) return WriteBytes(w, c.ExtraData)
} }
+14 -2
View File
@@ -45,6 +45,7 @@ import (
"github.com/lightningnetwork/lnd/queue" "github.com/lightningnetwork/lnd/queue"
"github.com/lightningnetwork/lnd/subscribe" "github.com/lightningnetwork/lnd/subscribe"
"github.com/lightningnetwork/lnd/ticker" "github.com/lightningnetwork/lnd/ticker"
"github.com/lightningnetwork/lnd/tlv"
"github.com/lightningnetwork/lnd/watchtower/wtclient" "github.com/lightningnetwork/lnd/watchtower/wtclient"
) )
@@ -1985,8 +1986,19 @@ func messageSummary(msg lnwire.Message) string {
msg.FeeSatoshis) msg.FeeSatoshis)
case *lnwire.UpdateAddHTLC: case *lnwire.UpdateAddHTLC:
return fmt.Sprintf("chan_id=%v, id=%v, amt=%v, expiry=%v, hash=%x", var blindingPoint []byte
msg.ChanID, msg.ID, msg.Amount, msg.Expiry, msg.PaymentHash[:]) msg.BlindingPoint.WhenSome(
func(b tlv.RecordT[lnwire.BlindingPointTlvType,
*btcec.PublicKey]) {
blindingPoint = b.Val.SerializeCompressed()
},
)
return fmt.Sprintf("chan_id=%v, id=%v, amt=%v, expiry=%v, "+
"hash=%x, blinding_point=%x", msg.ChanID, msg.ID,
msg.Amount, msg.Expiry, msg.PaymentHash[:],
blindingPoint)
case *lnwire.UpdateFailHTLC: case *lnwire.UpdateFailHTLC:
return fmt.Sprintf("chan_id=%v, id=%v, reason=%x", msg.ChanID, return fmt.Sprintf("chan_id=%v, id=%v, reason=%x", msg.ChanID,