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 }