2019-09-05 14:35:39 +03:00
|
|
|
package hop
|
2019-07-31 07:52:17 +03:00
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"encoding/binary"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/davecgh/go-spew/spew"
|
|
|
|
sphinx "github.com/lightningnetwork/lightning-onion"
|
|
|
|
"github.com/lightningnetwork/lnd/lnwire"
|
2019-08-30 11:41:12 +03:00
|
|
|
"github.com/lightningnetwork/lnd/record"
|
2019-07-31 07:52:17 +03:00
|
|
|
"github.com/lightningnetwork/lnd/tlv"
|
|
|
|
)
|
|
|
|
|
|
|
|
// 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[:])
|
2019-09-05 14:35:39 +03:00
|
|
|
expectedFwdInfo := ForwardingInfo{
|
2019-07-31 07:52:17 +03:00
|
|
|
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{
|
2019-08-30 11:41:12 +03:00
|
|
|
record.NewAmtToFwdRecord(&hopData.ForwardAmount),
|
|
|
|
record.NewLockTimeRecord(&hopData.OutgoingCltv),
|
|
|
|
record.NewNextHopIDRecord(&nextAddrInt),
|
2019-07-31 07:52:17 +03:00
|
|
|
}
|
|
|
|
tlvStream, err := tlv.NewStream(tlvRecords...)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("unable to create stream: %v", err)
|
|
|
|
}
|
|
|
|
if err := tlvStream.Encode(&b); err != nil {
|
|
|
|
t.Fatalf("unable to encode stream: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
var testCases = []struct {
|
|
|
|
sphinxPacket *sphinx.ProcessedPacket
|
2019-09-05 14:35:39 +03:00
|
|
|
expectedFwdInfo ForwardingInfo
|
2019-07-31 07:52:17 +03:00
|
|
|
}{
|
|
|
|
// 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, we can leave off the action as we'll always
|
|
|
|
// read the cid encoded.
|
|
|
|
{
|
|
|
|
sphinxPacket: &sphinx.ProcessedPacket{
|
|
|
|
Payload: sphinx.HopPayload{
|
|
|
|
Type: sphinx.PayloadTLV,
|
|
|
|
Payload: b.Bytes(),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
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
|
|
|
|
|
2019-11-05 02:10:15 +03:00
|
|
|
pld, err := iterator.HopPayload()
|
2019-07-31 07:52:17 +03:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("#%v: unable to extract forwarding "+
|
|
|
|
"instructions: %v", i, err)
|
|
|
|
}
|
|
|
|
|
2019-11-05 02:10:15 +03:00
|
|
|
fwdInfo := pld.ForwardingInfo()
|
2019-07-31 07:52:17 +03:00
|
|
|
if fwdInfo != testCase.expectedFwdInfo {
|
|
|
|
t.Fatalf("#%v: wrong fwding info: expected %v, got %v",
|
|
|
|
i, spew.Sdump(testCase.expectedFwdInfo),
|
|
|
|
spew.Sdump(fwdInfo))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|