routing: only pack amount and cltv if populated

With the addition of blinded routes, we now need to account for the
possibility that intermediate nodes payloads will not have an amount
and expiry set because that information is provided by the recipient
encrypted data blob. This commit updates our payload packing to only
optionally include those fields.
This commit is contained in:
Carla Kirk-Cohen
2022-12-20 14:02:42 -05:00
committed by Olaoluwa Osuntokun
parent fee0e05708
commit 940b491051
2 changed files with 40 additions and 11 deletions

View File

@@ -188,12 +188,21 @@ func (h *Hop) PackHopPayload(w io.Writer, nextChanID uint64) error {
// required routing fields, as well as these optional values.
var records []tlv.Record
// Every hop must have an amount to forward and CLTV expiry.
// Hops that are not part of a blinded path will have an amount and
// a CLTV expiry field. Zero values indicate that the hop is inside of
// a blinded route, so the TLV should not be included.
amt := uint64(h.AmtToForward)
records = append(records,
record.NewAmtToFwdRecord(&amt),
record.NewLockTimeRecord(&h.OutgoingTimeLock),
)
if amt != 0 {
records = append(
records, record.NewAmtToFwdRecord(&amt),
)
}
if h.OutgoingTimeLock != 0 {
records = append(
records, record.NewLockTimeRecord(&h.OutgoingTimeLock),
)
}
// BOLT 04 says the next_hop_id should be omitted for the final hop,
// but present for all others.
@@ -286,13 +295,18 @@ func (h *Hop) PayloadSize(nextChanID uint64) uint64 {
}
// Add amount size.
addRecord(record.AmtOnionType, tlv.SizeTUint64(uint64(h.AmtToForward)))
if h.AmtToForward != 0 {
addRecord(record.AmtOnionType, tlv.SizeTUint64(
uint64(h.AmtToForward),
))
}
// Add lock time size.
addRecord(
record.LockTimeOnionType,
tlv.SizeTUint64(uint64(h.OutgoingTimeLock)),
)
if h.OutgoingTimeLock != 0 {
addRecord(
record.LockTimeOnionType,
tlv.SizeTUint64(uint64(h.OutgoingTimeLock)),
)
}
// Add next hop if present.
if nextChanID != 0 {

View File

@@ -8,6 +8,7 @@ import (
"github.com/btcsuite/btcd/btcec/v2"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/record"
"github.com/stretchr/testify/require"
)
var (
@@ -159,6 +160,20 @@ func TestAMPHop(t *testing.T) {
}
}
// TestNoForwardingParams tests packing of a hop payload without an amount or
// expiry height.
func TestNoForwardingParams(t *testing.T) {
t.Parallel()
hop := Hop{
EncryptedData: []byte{1, 2, 3},
}
var b bytes.Buffer
err := hop.PackHopPayload(&b, 2)
require.NoError(t, err)
}
// TestPayloadSize tests the payload size calculation that is provided by Hop
// structs.
func TestPayloadSize(t *testing.T) {