github.com/decred/dcrlnd@v0.7.6/htlcswitch/hop/iterator_test.go (about)

     1  package hop
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  	"testing"
     7  
     8  	"github.com/davecgh/go-spew/spew"
     9  	"github.com/decred/dcrlnd/lnwire"
    10  	"github.com/decred/dcrlnd/record"
    11  	"github.com/decred/dcrlnd/tlv"
    12  	sphinx "github.com/decred/lightning-onion/v4"
    13  )
    14  
    15  // TestSphinxHopIteratorForwardingInstructions tests that we're able to
    16  // properly decode an onion payload, no matter the payload type, into the
    17  // original set of forwarding instructions.
    18  func TestSphinxHopIteratorForwardingInstructions(t *testing.T) {
    19  	t.Parallel()
    20  
    21  	// First, we'll make the hop data that the sender would create to send
    22  	// an HTLC through our imaginary route.
    23  	hopData := sphinx.HopData{
    24  		ForwardAmount: 100000,
    25  		OutgoingCltv:  4343,
    26  	}
    27  	copy(hopData.NextAddress[:], bytes.Repeat([]byte("a"), 8))
    28  
    29  	// Next, we'll make the hop forwarding information that we should
    30  	// extract each type, no matter the payload type.
    31  	nextAddrInt := binary.BigEndian.Uint64(hopData.NextAddress[:])
    32  	expectedFwdInfo := ForwardingInfo{
    33  		Network:         DecredNetwork,
    34  		NextHop:         lnwire.NewShortChanIDFromInt(nextAddrInt),
    35  		AmountToForward: lnwire.MilliAtom(hopData.ForwardAmount),
    36  		OutgoingCTLV:    hopData.OutgoingCltv,
    37  	}
    38  
    39  	// For our TLV payload, we'll serialize the hop into into a TLV stream
    40  	// as we would normally in the routing network.
    41  	var b bytes.Buffer
    42  	tlvRecords := []tlv.Record{
    43  		record.NewAmtToFwdRecord(&hopData.ForwardAmount),
    44  		record.NewLockTimeRecord(&hopData.OutgoingCltv),
    45  		record.NewNextHopIDRecord(&nextAddrInt),
    46  	}
    47  	tlvStream, err := tlv.NewStream(tlvRecords...)
    48  	if err != nil {
    49  		t.Fatalf("unable to create stream: %v", err)
    50  	}
    51  	if err := tlvStream.Encode(&b); err != nil {
    52  		t.Fatalf("unable to encode stream: %v", err)
    53  	}
    54  
    55  	var testCases = []struct {
    56  		sphinxPacket    *sphinx.ProcessedPacket
    57  		expectedFwdInfo ForwardingInfo
    58  	}{
    59  		// A regular legacy payload that signals more hops.
    60  		{
    61  			sphinxPacket: &sphinx.ProcessedPacket{
    62  				Payload: sphinx.HopPayload{
    63  					Type: sphinx.PayloadLegacy,
    64  				},
    65  				Action:                 sphinx.MoreHops,
    66  				ForwardingInstructions: &hopData,
    67  			},
    68  			expectedFwdInfo: expectedFwdInfo,
    69  		},
    70  		// A TLV payload, we can leave off the action as we'll always
    71  		// read the cid encoded.
    72  		{
    73  			sphinxPacket: &sphinx.ProcessedPacket{
    74  				Payload: sphinx.HopPayload{
    75  					Type:    sphinx.PayloadTLV,
    76  					Payload: b.Bytes(),
    77  				},
    78  			},
    79  			expectedFwdInfo: expectedFwdInfo,
    80  		},
    81  	}
    82  
    83  	// Finally, we'll test that we get the same set of
    84  	// ForwardingInstructions for each payload type.
    85  	iterator := sphinxHopIterator{}
    86  	for i, testCase := range testCases {
    87  		iterator.processedPacket = testCase.sphinxPacket
    88  
    89  		pld, err := iterator.HopPayload()
    90  		if err != nil {
    91  			t.Fatalf("#%v: unable to extract forwarding "+
    92  				"instructions: %v", i, err)
    93  		}
    94  
    95  		fwdInfo := pld.ForwardingInfo()
    96  		if fwdInfo != testCase.expectedFwdInfo {
    97  			t.Fatalf("#%v: wrong fwding info: expected %v, got %v",
    98  				i, spew.Sdump(testCase.expectedFwdInfo),
    99  				spew.Sdump(fwdInfo))
   100  		}
   101  	}
   102  }