github.com/decred/dcrlnd@v0.7.6/lntest/itest/lnd_multi-hop-payments_test.go (about)

     1  package itest
     2  
     3  import (
     4  	"context"
     5  	"time"
     6  
     7  	"github.com/decred/dcrd/dcrutil/v4"
     8  	"github.com/decred/dcrd/wire"
     9  	"github.com/decred/dcrlnd/chainreg"
    10  	"github.com/decred/dcrlnd/lnrpc"
    11  	"github.com/decred/dcrlnd/lnrpc/routerrpc"
    12  	"github.com/decred/dcrlnd/lntest"
    13  )
    14  
    15  func testMultiHopPayments(net *lntest.NetworkHarness, t *harnessTest) {
    16  
    17  	ctxb := context.Background()
    18  
    19  	const chanAmt = dcrutil.Amount(100000)
    20  	var networkChans []*lnrpc.ChannelPoint
    21  
    22  	// Open a channel with 100k atoms between Alice and Bob with Alice
    23  	// being the sole funder of the channel.
    24  	chanPointAlice := openChannelAndAssert(
    25  		t, net, net.Alice, net.Bob,
    26  		lntest.OpenChannelParams{
    27  			Amt: chanAmt,
    28  		},
    29  	)
    30  	networkChans = append(networkChans, chanPointAlice)
    31  
    32  	aliceChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointAlice)
    33  	if err != nil {
    34  		t.Fatalf("unable to get txid: %v", err)
    35  	}
    36  	aliceFundPoint := wire.OutPoint{
    37  		Hash:  *aliceChanTXID,
    38  		Index: chanPointAlice.OutputIndex,
    39  	}
    40  
    41  	// As preliminary setup, we'll create two new nodes: Carol and Dave,
    42  	// such that we now have a 4 node, 3 channel topology. Dave will make a
    43  	// channel with Alice, and Carol with Dave. After this setup, the
    44  	// network topology should now look like:
    45  	//     Carol -> Dave -> Alice -> Bob
    46  	//
    47  	// First, we'll create Dave and establish a channel to Alice. Dave will
    48  	// be running an older node that requires the legacy onion payload.
    49  	daveArgs := []string{"--protocol.legacy.onion"}
    50  	dave := net.NewNode(t.t, "Dave", daveArgs)
    51  	defer shutdownAndAssert(net, t, dave)
    52  
    53  	net.ConnectNodes(t.t, dave, net.Alice)
    54  	net.SendCoins(t.t, dcrutil.AtomsPerCoin, dave)
    55  
    56  	chanPointDave := openChannelAndAssert(
    57  		t, net, dave, net.Alice,
    58  		lntest.OpenChannelParams{
    59  			Amt: chanAmt,
    60  		},
    61  	)
    62  	networkChans = append(networkChans, chanPointDave)
    63  	daveChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointDave)
    64  	if err != nil {
    65  		t.Fatalf("unable to get txid: %v", err)
    66  	}
    67  	daveFundPoint := wire.OutPoint{
    68  		Hash:  *daveChanTXID,
    69  		Index: chanPointDave.OutputIndex,
    70  	}
    71  
    72  	// Next, we'll create Carol and establish a channel to from her to
    73  	// Dave.
    74  	carol := net.NewNode(t.t, "Carol", nil)
    75  	defer shutdownAndAssert(net, t, carol)
    76  
    77  	net.ConnectNodes(t.t, carol, dave)
    78  	net.SendCoins(t.t, dcrutil.AtomsPerCoin, carol)
    79  
    80  	chanPointCarol := openChannelAndAssert(
    81  		t, net, carol, dave,
    82  		lntest.OpenChannelParams{
    83  			Amt: chanAmt,
    84  		},
    85  	)
    86  	networkChans = append(networkChans, chanPointCarol)
    87  
    88  	carolChanTXID, err := lnrpc.GetChanPointFundingTxid(chanPointCarol)
    89  	if err != nil {
    90  		t.Fatalf("unable to get txid: %v", err)
    91  	}
    92  	carolFundPoint := wire.OutPoint{
    93  		Hash:  *carolChanTXID,
    94  		Index: chanPointCarol.OutputIndex,
    95  	}
    96  
    97  	// Wait for all nodes to have seen all channels.
    98  	nodes := []*lntest.HarnessNode{net.Alice, net.Bob, carol, dave}
    99  	nodeNames := []string{"Alice", "Bob", "Carol", "Dave"}
   100  	for _, chanPoint := range networkChans {
   101  		for i, node := range nodes {
   102  			txid, err := lnrpc.GetChanPointFundingTxid(chanPoint)
   103  			if err != nil {
   104  				t.Fatalf("unable to get txid: %v", err)
   105  			}
   106  			point := wire.OutPoint{
   107  				Hash:  *txid,
   108  				Index: chanPoint.OutputIndex,
   109  			}
   110  
   111  			err = node.WaitForNetworkChannelOpen(chanPoint)
   112  			if err != nil {
   113  				t.Fatalf("%s(%d): timeout waiting for "+
   114  					"channel(%s) open: %v", nodeNames[i],
   115  					node.NodeID, point, err)
   116  			}
   117  		}
   118  	}
   119  
   120  	// Create 5 invoices for Bob, which expect a payment from Carol for 1k
   121  	// atoms with a different preimage each time.
   122  	const numPayments = 5
   123  	const paymentAmt = 1000
   124  	payReqs, _, _, err := createPayReqs(
   125  		net.Bob, paymentAmt, numPayments,
   126  	)
   127  	if err != nil {
   128  		t.Fatalf("unable to create pay reqs: %v", err)
   129  	}
   130  
   131  	// We'll wait for all parties to recognize the new channels within the
   132  	// network.
   133  	err = dave.WaitForNetworkChannelOpen(chanPointDave)
   134  	if err != nil {
   135  		t.Fatalf("dave didn't advertise his channel: %v", err)
   136  	}
   137  	err = carol.WaitForNetworkChannelOpen(chanPointCarol)
   138  	if err != nil {
   139  		t.Fatalf("carol didn't advertise her channel in time: %v",
   140  			err)
   141  	}
   142  
   143  	time.Sleep(time.Millisecond * 50)
   144  
   145  	// Set the fee policies of the Alice -> Bob and the Dave -> Alice
   146  	// channel edges to relatively large non default values. This makes it
   147  	// possible to pick up more subtle fee calculation errors.
   148  	maxHtlc := calculateMaxHtlc(chanAmt)
   149  	const aliceBaseFeeAtoms = 1
   150  	const aliceFeeRatePPM = 100000
   151  	updateChannelPolicy(
   152  		t, net.Alice, chanPointAlice, aliceBaseFeeAtoms*1000,
   153  		aliceFeeRatePPM, chainreg.DefaultDecredTimeLockDelta, maxHtlc,
   154  		carol,
   155  	)
   156  
   157  	const daveBaseFeeAtoms = 5
   158  	const daveFeeRatePPM = 150000
   159  	updateChannelPolicy(
   160  		t, dave, chanPointDave, daveBaseFeeAtoms*1000, daveFeeRatePPM,
   161  		chainreg.DefaultDecredTimeLockDelta, maxHtlc, carol,
   162  	)
   163  
   164  	// Before we start sending payments, subscribe to htlc events for each
   165  	// node.
   166  	ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout)
   167  	defer cancel()
   168  
   169  	aliceEvents, err := net.Alice.RouterClient.SubscribeHtlcEvents(
   170  		ctxt, &routerrpc.SubscribeHtlcEventsRequest{},
   171  	)
   172  	if err != nil {
   173  		t.Fatalf("could not subscribe events: %v", err)
   174  	}
   175  
   176  	bobEvents, err := net.Bob.RouterClient.SubscribeHtlcEvents(
   177  		ctxt, &routerrpc.SubscribeHtlcEventsRequest{},
   178  	)
   179  	if err != nil {
   180  		t.Fatalf("could not subscribe events: %v", err)
   181  	}
   182  
   183  	carolEvents, err := carol.RouterClient.SubscribeHtlcEvents(
   184  		ctxt, &routerrpc.SubscribeHtlcEventsRequest{},
   185  	)
   186  	if err != nil {
   187  		t.Fatalf("could not subscribe events: %v", err)
   188  	}
   189  
   190  	daveEvents, err := dave.RouterClient.SubscribeHtlcEvents(
   191  		ctxt, &routerrpc.SubscribeHtlcEventsRequest{},
   192  	)
   193  	if err != nil {
   194  		t.Fatalf("could not subscribe events: %v", err)
   195  	}
   196  
   197  	// Using Carol as the source, pay to the 5 invoices from Bob created
   198  	// above.
   199  	err = completePaymentRequests(carol, carol.RouterClient, payReqs, true)
   200  	if err != nil {
   201  		t.Fatalf("unable to send payments: %v", err)
   202  	}
   203  
   204  	// At this point all the channels within our proto network should be
   205  	// shifted by 5k atoms in the direction of Bob, the sink within the
   206  	// payment flow generated above. The order of asserts corresponds to
   207  	// increasing of time is needed to embed the HTLC in commitment
   208  	// transaction, in channel Carol->David->Alice->Bob, order is Bob,
   209  	// Alice, David, Carol.
   210  
   211  	// The final node bob expects to get paid five times 1000 atoms.
   212  	expectedAmountPaidAtoB := int64(numPayments * paymentAmt)
   213  
   214  	assertAmountPaid(t, "Alice(local) => Bob(remote)", net.Bob,
   215  		aliceFundPoint, int64(0), expectedAmountPaidAtoB)
   216  	assertAmountPaid(t, "Alice(local) => Bob(remote)", net.Alice,
   217  		aliceFundPoint, expectedAmountPaidAtoB, int64(0))
   218  
   219  	// To forward a payment of 1000 atoms, Alice is charging a fee of 1
   220  	// atom + 10% = 101 atoms.
   221  	const aliceFeePerPayment = aliceBaseFeeAtoms +
   222  		(paymentAmt * aliceFeeRatePPM / 1_000_000)
   223  	const expectedFeeAlice = numPayments * aliceFeePerPayment
   224  
   225  	// Dave needs to pay what Alice pays plus Alice's fee.
   226  	expectedAmountPaidDtoA := expectedAmountPaidAtoB + expectedFeeAlice
   227  
   228  	assertAmountPaid(t, "Dave(local) => Alice(remote)", net.Alice,
   229  		daveFundPoint, int64(0), expectedAmountPaidDtoA)
   230  	assertAmountPaid(t, "Dave(local) => Alice(remote)", dave,
   231  		daveFundPoint, expectedAmountPaidDtoA, int64(0))
   232  
   233  	// To forward a payment of 1101 atom, Dave is charging a fee of 5 atoms
   234  	// + 15% = 170.15 atoms. This is rounded down in rpcserver to 170.
   235  	const davePaymentAmt = paymentAmt + aliceFeePerPayment
   236  	const daveFeePerPayment = daveBaseFeeAtoms +
   237  		(davePaymentAmt * daveFeeRatePPM / 1_000_000)
   238  	const expectedFeeDave = numPayments * daveFeePerPayment
   239  
   240  	// Carol needs to pay what Dave pays plus Dave's fee.
   241  	expectedAmountPaidCtoD := expectedAmountPaidDtoA + expectedFeeDave
   242  
   243  	assertAmountPaid(t, "Carol(local) => Dave(remote)", dave,
   244  		carolFundPoint, int64(0), expectedAmountPaidCtoD)
   245  	assertAmountPaid(t, "Carol(local) => Dave(remote)", carol,
   246  		carolFundPoint, expectedAmountPaidCtoD, int64(0))
   247  
   248  	// Now that we know all the balances have been settled out properly,
   249  	// we'll ensure that our internal record keeping for completed circuits
   250  	// was properly updated.
   251  
   252  	// First, check that the FeeReport response shows the proper fees
   253  	// accrued over each time range. Dave should've earned 170 atoms for
   254  	// each of the forwarded payments.
   255  	ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
   256  	feeReport, err := dave.FeeReport(ctxt, &lnrpc.FeeReportRequest{})
   257  	if err != nil {
   258  		t.Fatalf("unable to query for fee report: %v", err)
   259  	}
   260  
   261  	if feeReport.DayFeeSum != uint64(expectedFeeDave) {
   262  		t.Fatalf("fee mismatch: expected %v, got %v", expectedFeeDave,
   263  			feeReport.DayFeeSum)
   264  	}
   265  	if feeReport.WeekFeeSum != uint64(expectedFeeDave) {
   266  		t.Fatalf("fee mismatch: expected %v, got %v", expectedFeeDave,
   267  			feeReport.WeekFeeSum)
   268  	}
   269  	if feeReport.MonthFeeSum != uint64(expectedFeeDave) {
   270  		t.Fatalf("fee mismatch: expected %v, got %v", expectedFeeDave,
   271  			feeReport.MonthFeeSum)
   272  	}
   273  
   274  	// Next, ensure that if we issue the vanilla query for the forwarding
   275  	// history, it returns 5 values, and each entry is formatted properly.
   276  	ctxt, _ = context.WithTimeout(ctxb, defaultTimeout)
   277  	fwdingHistory, err := dave.ForwardingHistory(
   278  		ctxt, &lnrpc.ForwardingHistoryRequest{},
   279  	)
   280  	if err != nil {
   281  		t.Fatalf("unable to query for fee report: %v", err)
   282  	}
   283  	if len(fwdingHistory.ForwardingEvents) != numPayments {
   284  		t.Fatalf("wrong number of forwarding event: expected %v, "+
   285  			"got %v", numPayments,
   286  			len(fwdingHistory.ForwardingEvents))
   287  	}
   288  	expectedForwardingFee := uint64(expectedFeeDave / numPayments)
   289  	for _, event := range fwdingHistory.ForwardingEvents {
   290  		// Each event should show a fee of 170 atoms.
   291  		if event.Fee != expectedForwardingFee {
   292  			t.Fatalf("fee mismatch:  expected %v, got %v",
   293  				expectedForwardingFee, event.Fee)
   294  		}
   295  	}
   296  
   297  	// We expect Carol to have successful forwards and settles for
   298  	// her sends.
   299  	assertHtlcEvents(
   300  		t, numPayments, 0, numPayments, routerrpc.HtlcEvent_SEND,
   301  		carolEvents,
   302  	)
   303  
   304  	// Dave and Alice should both have forwards and settles for
   305  	// their role as forwarding nodes.
   306  	assertHtlcEvents(
   307  		t, numPayments, 0, numPayments, routerrpc.HtlcEvent_FORWARD,
   308  		daveEvents,
   309  	)
   310  	assertHtlcEvents(
   311  		t, numPayments, 0, numPayments, routerrpc.HtlcEvent_FORWARD,
   312  		aliceEvents,
   313  	)
   314  
   315  	// Bob should only have settle events for his receives.
   316  	assertHtlcEvents(
   317  		t, 0, 0, numPayments, routerrpc.HtlcEvent_RECEIVE, bobEvents,
   318  	)
   319  
   320  	closeChannelAndAssert(t, net, net.Alice, chanPointAlice, false)
   321  	closeChannelAndAssert(t, net, dave, chanPointDave, false)
   322  	closeChannelAndAssert(t, net, carol, chanPointCarol, false)
   323  }
   324  
   325  // assertHtlcEvents consumes events from a client and ensures that they are of
   326  // the expected type and contain the expected number of forwards, forward
   327  // failures and settles.
   328  func assertHtlcEvents(t *harnessTest, fwdCount, fwdFailCount, settleCount int,
   329  	userType routerrpc.HtlcEvent_EventType,
   330  	client routerrpc.Router_SubscribeHtlcEventsClient) {
   331  
   332  	var forwards, forwardFails, settles int
   333  
   334  	numEvents := fwdCount + fwdFailCount + settleCount
   335  	for i := 0; i < numEvents; i++ {
   336  		event := assertEventAndType(t, userType, client)
   337  
   338  		switch event.Event.(type) {
   339  		case *routerrpc.HtlcEvent_ForwardEvent:
   340  			forwards++
   341  
   342  		case *routerrpc.HtlcEvent_ForwardFailEvent:
   343  			forwardFails++
   344  
   345  		case *routerrpc.HtlcEvent_SettleEvent:
   346  			settles++
   347  
   348  		default:
   349  			t.Fatalf("unexpected event: %T", event.Event)
   350  		}
   351  	}
   352  
   353  	if forwards != fwdCount {
   354  		t.Fatalf("expected: %v forwards, got: %v", fwdCount, forwards)
   355  	}
   356  
   357  	if forwardFails != fwdFailCount {
   358  		t.Fatalf("expected: %v forward fails, got: %v", fwdFailCount,
   359  			forwardFails)
   360  	}
   361  
   362  	if settles != settleCount {
   363  		t.Fatalf("expected: %v settles, got: %v", settleCount, settles)
   364  	}
   365  }
   366  
   367  // assertEventAndType reads an event from the stream provided and ensures that
   368  // it is associated with the correct user related type - a user initiated send,
   369  // a receive to our node or a forward through our node. Note that this event
   370  // type is different from the htlc event type (forward, link failure etc).
   371  func assertEventAndType(t *harnessTest, eventType routerrpc.HtlcEvent_EventType,
   372  	client routerrpc.Router_SubscribeHtlcEventsClient) *routerrpc.HtlcEvent {
   373  	event, err := client.Recv()
   374  	if err != nil {
   375  		t.Fatalf("could not get event")
   376  	}
   377  
   378  	if event.EventType != eventType {
   379  		t.Fatalf("expected: %v, got: %v", eventType,
   380  			event.EventType)
   381  	}
   382  
   383  	return event
   384  }
   385  
   386  // updateChannelPolicy updates the channel policy of node to the
   387  // given fees and timelock delta. This function blocks until
   388  // listenerNode has received the policy update.
   389  func updateChannelPolicy(t *harnessTest, node *lntest.HarnessNode,
   390  	chanPoint *lnrpc.ChannelPoint, baseFee int64, feeRate int64,
   391  	timeLockDelta uint32, maxHtlc uint64, listenerNode *lntest.HarnessNode) {
   392  
   393  	ctxb := context.Background()
   394  
   395  	expectedPolicy := &lnrpc.RoutingPolicy{
   396  		FeeBaseMAtoms:      baseFee,
   397  		FeeRateMilliMAtoms: feeRate,
   398  		TimeLockDelta:      timeLockDelta,
   399  		MinHtlc:            1000, // default value
   400  		MaxHtlcMAtoms:      maxHtlc,
   401  	}
   402  
   403  	updateFeeReq := &lnrpc.PolicyUpdateRequest{
   404  		BaseFeeMAtoms: baseFee,
   405  		FeeRate:       float64(feeRate) / testFeeBase,
   406  		TimeLockDelta: timeLockDelta,
   407  		Scope: &lnrpc.PolicyUpdateRequest_ChanPoint{
   408  			ChanPoint: chanPoint,
   409  		},
   410  		MaxHtlcMAtoms: maxHtlc,
   411  	}
   412  
   413  	ctxt, _ := context.WithTimeout(ctxb, defaultTimeout)
   414  	if _, err := node.UpdateChannelPolicy(ctxt, updateFeeReq); err != nil {
   415  		t.Fatalf("unable to update chan policy: %v", err)
   416  	}
   417  
   418  	// Wait for listener node to receive the channel update from node.
   419  	assertChannelPolicyUpdate(
   420  		t.t, listenerNode, node.PubKeyStr,
   421  		expectedPolicy, chanPoint, false,
   422  	)
   423  }