lnd/htlcswitch/hop/iterator_test.go
Carla Kirk-Cohen fa78d21975
htlcswitch/test: add sphinx action to decoding test
Update test to include the sphinx action to more closely represent
reality. This will be required when we add more validation to the
presence of a nextChanID field. A MoreHops action is chose because
we're testing the case with a payload that contains forwarding info.
2023-12-18 11:27:48 -05:00

102 lines
3.1 KiB
Go

package hop
import (
"bytes"
"encoding/binary"
"testing"
"github.com/davecgh/go-spew/spew"
sphinx "github.com/lightningnetwork/lightning-onion"
"github.com/lightningnetwork/lnd/lnwire"
"github.com/lightningnetwork/lnd/record"
"github.com/lightningnetwork/lnd/tlv"
"github.com/stretchr/testify/require"
)
// TestSphinxHopIteratorForwardingInstructions tests that we're able to
// properly decode an onion payload, no matter the payload type, into the
// original set of forwarding instructions.
func TestSphinxHopIteratorForwardingInstructions(t *testing.T) {
t.Parallel()
// First, we'll make the hop data that the sender would create to send
// an HTLC through our imaginary route.
hopData := sphinx.HopData{
ForwardAmount: 100000,
OutgoingCltv: 4343,
}
copy(hopData.NextAddress[:], bytes.Repeat([]byte("a"), 8))
// Next, we'll make the hop forwarding information that we should
// extract each type, no matter the payload type.
nextAddrInt := binary.BigEndian.Uint64(hopData.NextAddress[:])
expectedFwdInfo := ForwardingInfo{
NextHop: lnwire.NewShortChanIDFromInt(nextAddrInt),
AmountToForward: lnwire.MilliSatoshi(hopData.ForwardAmount),
OutgoingCTLV: hopData.OutgoingCltv,
}
// For our TLV payload, we'll serialize the hop into into a TLV stream
// as we would normally in the routing network.
var b bytes.Buffer
tlvRecords := []tlv.Record{
record.NewAmtToFwdRecord(&hopData.ForwardAmount),
record.NewLockTimeRecord(&hopData.OutgoingCltv),
record.NewNextHopIDRecord(&nextAddrInt),
}
tlvStream, err := tlv.NewStream(tlvRecords...)
require.NoError(t, err, "unable to create stream")
if err := tlvStream.Encode(&b); err != nil {
t.Fatalf("unable to encode stream: %v", err)
}
var testCases = []struct {
sphinxPacket *sphinx.ProcessedPacket
expectedFwdInfo ForwardingInfo
}{
// A regular legacy payload that signals more hops.
{
sphinxPacket: &sphinx.ProcessedPacket{
Payload: sphinx.HopPayload{
Type: sphinx.PayloadLegacy,
},
Action: sphinx.MoreHops,
ForwardingInstructions: &hopData,
},
expectedFwdInfo: expectedFwdInfo,
},
// A TLV payload, which includes the sphinx action as
// cid may be zero for blinded routes (thus we require the
// action to signal whether we are at the final hop).
{
sphinxPacket: &sphinx.ProcessedPacket{
Payload: sphinx.HopPayload{
Type: sphinx.PayloadTLV,
Payload: b.Bytes(),
},
Action: sphinx.MoreHops,
},
expectedFwdInfo: expectedFwdInfo,
},
}
// Finally, we'll test that we get the same set of
// ForwardingInstructions for each payload type.
iterator := sphinxHopIterator{}
for i, testCase := range testCases {
iterator.processedPacket = testCase.sphinxPacket
pld, err := iterator.HopPayload()
if err != nil {
t.Fatalf("#%v: unable to extract forwarding "+
"instructions: %v", i, err)
}
fwdInfo := pld.ForwardingInfo()
if fwdInfo != testCase.expectedFwdInfo {
t.Fatalf("#%v: wrong fwding info: expected %v, got %v",
i, spew.Sdump(testCase.expectedFwdInfo),
spew.Sdump(fwdInfo))
}
}
}