Merge pull request #3441 from cfromknecht/truncated-sid

htlcswitch+routing: omit next_hop_id in final hop payload
This commit is contained in:
Olaoluwa Osuntokun 2019-09-04 19:55:38 -07:00 committed by GitHub
commit 00682584aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 77 additions and 53 deletions

@ -9,6 +9,7 @@ import (
"github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/btcec"
"github.com/lightningnetwork/lightning-onion" "github.com/lightningnetwork/lightning-onion"
"github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/record"
"github.com/lightningnetwork/lnd/tlv" "github.com/lightningnetwork/lnd/tlv"
) )
@ -175,15 +176,9 @@ func (r *sphinxHopIterator) ForwardingInstructions() (ForwardingInfo, error) {
var cid uint64 var cid uint64
tlvStream, err := tlv.NewStream( tlvStream, err := tlv.NewStream(
tlv.MakeDynamicRecord( record.NewAmtToFwdRecord(&amt),
tlv.AmtOnionType, &amt, nil, record.NewLockTimeRecord(&cltv),
tlv.ETUint64, tlv.DTUint64, record.NewNextHopIDRecord(&cid),
),
tlv.MakeDynamicRecord(
tlv.LockTimeOnionType, &cltv, nil,
tlv.ETUint32, tlv.DTUint32,
),
tlv.MakePrimitiveRecord(tlv.NextHopOnionType, &cid),
) )
if err != nil { if err != nil {
return ForwardingInfo{}, err return ForwardingInfo{}, err

@ -8,6 +8,7 @@ import (
"github.com/davecgh/go-spew/spew" "github.com/davecgh/go-spew/spew"
sphinx "github.com/lightningnetwork/lightning-onion" sphinx "github.com/lightningnetwork/lightning-onion"
"github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/record"
"github.com/lightningnetwork/lnd/tlv" "github.com/lightningnetwork/lnd/tlv"
) )
@ -38,19 +39,9 @@ func TestSphinxHopIteratorForwardingInstructions(t *testing.T) {
// as we would normally in the routing network. // as we would normally in the routing network.
var b bytes.Buffer var b bytes.Buffer
tlvRecords := []tlv.Record{ tlvRecords := []tlv.Record{
tlv.MakeDynamicRecord( record.NewAmtToFwdRecord(&hopData.ForwardAmount),
tlv.AmtOnionType, &hopData.ForwardAmount, func() uint64 { record.NewLockTimeRecord(&hopData.OutgoingCltv),
return tlv.SizeTUint64(hopData.ForwardAmount) record.NewNextHopIDRecord(&nextAddrInt),
},
tlv.ETUint64, tlv.DTUint64,
),
tlv.MakeDynamicRecord(
tlv.LockTimeOnionType, &hopData.OutgoingCltv, func() uint64 {
return tlv.SizeTUint32(hopData.OutgoingCltv)
},
tlv.ETUint32, tlv.DTUint32,
),
tlv.MakePrimitiveRecord(tlv.NextHopOnionType, &nextAddrInt),
} }
tlvStream, err := tlv.NewStream(tlvRecords...) tlvStream, err := tlv.NewStream(tlvRecords...)
if err != nil { if err != nil {

47
record/hop.go Normal file

@ -0,0 +1,47 @@
package record
import (
"github.com/lightningnetwork/lnd/tlv"
)
const (
// AmtOnionType is the type used in the onion to refrence the amount to
// send to the next hop.
AmtOnionType tlv.Type = 2
// LockTimeTLV is the type used in the onion to refenernce the CLTV
// value that should be used for the next hop's HTLC.
LockTimeOnionType tlv.Type = 4
// NextHopOnionType is the type used in the onion to reference the ID
// of the next hop.
NextHopOnionType tlv.Type = 6
)
// NewAmtToFwdRecord creates a tlv.Record that encodes the amount_to_forward
// (type 2) for an onion payload.
func NewAmtToFwdRecord(amt *uint64) tlv.Record {
return tlv.MakeDynamicRecord(
AmtOnionType, amt, func() uint64 {
return tlv.SizeTUint64(*amt)
},
tlv.ETUint64, tlv.DTUint64,
)
}
// NewLockTimeRecord creates a tlv.Record that encodes the outgoing_cltv_value
// (type 4) for an onion payload.
func NewLockTimeRecord(lockTime *uint32) tlv.Record {
return tlv.MakeDynamicRecord(
LockTimeOnionType, lockTime, func() uint64 {
return tlv.SizeTUint32(*lockTime)
},
tlv.ETUint32, tlv.DTUint32,
)
}
// NewNextHopIDRecord creates a tlv.Record that encodes the short_channel_id
// (type 6) for an onion payload.
func NewNextHopIDRecord(cid *uint64) tlv.Record {
return tlv.MakePrimitiveRecord(NextHopOnionType, cid)
}

@ -11,6 +11,7 @@ import (
"github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/btcec"
sphinx "github.com/lightningnetwork/lightning-onion" sphinx "github.com/lightningnetwork/lightning-onion"
"github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/record"
"github.com/lightningnetwork/lnd/tlv" "github.com/lightningnetwork/lnd/tlv"
) )
@ -103,28 +104,33 @@ func (h *Hop) PackHopPayload(w io.Writer, nextChanID uint64) error {
// Otherwise, we'll need to make a new stream that includes our // Otherwise, we'll need to make a new stream that includes our
// required routing fields, as well as these optional values. // required routing fields, as well as these optional values.
var records []tlv.Record
// Every hop must have an amount to forward and CLTV expiry.
amt := uint64(h.AmtToForward) amt := uint64(h.AmtToForward)
combinedRecords := append(h.TLVRecords, records = append(records,
tlv.MakeDynamicRecord( record.NewAmtToFwdRecord(&amt),
tlv.AmtOnionType, &amt, func() uint64 { record.NewLockTimeRecord(&h.OutgoingTimeLock),
return tlv.SizeTUint64(amt)
},
tlv.ETUint64, tlv.DTUint64,
),
tlv.MakeDynamicRecord(
tlv.LockTimeOnionType, &h.OutgoingTimeLock, func() uint64 {
return tlv.SizeTUint32(h.OutgoingTimeLock)
},
tlv.ETUint32, tlv.DTUint32,
),
tlv.MakePrimitiveRecord(tlv.NextHopOnionType, &nextChanID),
) )
// BOLT 04 says the next_hop_id should be omitted for the final hop,
// but present for all others.
//
// TODO(conner): test using hop.Exit once available
if nextChanID != 0 {
records = append(records,
record.NewNextHopIDRecord(&nextChanID),
)
}
// Append any custom types destined for this hop.
records = append(records, h.TLVRecords...)
// To ensure we produce a canonical stream, we'll sort the records // To ensure we produce a canonical stream, we'll sort the records
// before encoding them as a stream in the hop payload. // before encoding them as a stream in the hop payload.
tlv.SortRecords(combinedRecords) tlv.SortRecords(records)
tlvStream, err := tlv.NewStream(combinedRecords...) tlvStream, err := tlv.NewStream(records...)
if err != nil { if err != nil {
return err return err
} }

@ -1,15 +0,0 @@
package tlv
const (
// AmtOnionType is the type used in the onion to refrence the amount to
// send to the next hop.
AmtOnionType Type = 2
// LockTimeTLV is the type used in the onion to refenernce the CLTV
// value that should be used for the next hop's HTLC.
LockTimeOnionType Type = 4
// NextHopOnionType is the type used in the onion to reference the ID
// of the next hop.
NextHopOnionType Type = 6
)