github.com/decred/dcrlnd@v0.7.6/routing/payment_lifecycle_test.go (about)

     1  package routing
     2  
     3  import (
     4  	"crypto/rand"
     5  	"fmt"
     6  	"sync/atomic"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/decred/dcrd/dcrutil/v4"
    11  	"github.com/decred/dcrlnd/channeldb"
    12  	"github.com/decred/dcrlnd/clock"
    13  	"github.com/decred/dcrlnd/htlcswitch"
    14  	"github.com/decred/dcrlnd/lntypes"
    15  	"github.com/decred/dcrlnd/lnwire"
    16  	"github.com/decred/dcrlnd/routing/route"
    17  	"github.com/go-errors/errors"
    18  	"github.com/stretchr/testify/require"
    19  )
    20  
    21  const stepTimeout = 5 * time.Second
    22  
    23  // createTestRoute builds a route a->b->c paying the given amt to c.
    24  func createTestRoute(amt lnwire.MilliAtom,
    25  	aliasMap map[string]route.Vertex) (*route.Route, error) {
    26  
    27  	hopFee := lnwire.NewMAtomsFromAtoms(3)
    28  	hop1 := aliasMap["b"]
    29  	hop2 := aliasMap["c"]
    30  	hops := []*route.Hop{
    31  		{
    32  			ChannelID:     1,
    33  			PubKeyBytes:   hop1,
    34  			LegacyPayload: true,
    35  			AmtToForward:  amt + hopFee,
    36  		},
    37  		{
    38  			ChannelID:     2,
    39  			PubKeyBytes:   hop2,
    40  			LegacyPayload: true,
    41  			AmtToForward:  amt,
    42  		},
    43  	}
    44  
    45  	// We create a simple route that we will supply every time the router
    46  	// requests one.
    47  	return route.NewRouteFromHops(
    48  		amt+2*hopFee, 100, aliasMap["a"], hops,
    49  	)
    50  }
    51  
    52  // paymentLifecycleTestCase contains the steps that we expect for a payment
    53  // lifecycle test, and the routes that pathfinding should deliver.
    54  type paymentLifecycleTestCase struct {
    55  	name string
    56  
    57  	// steps is a list of steps to perform during the testcase.
    58  	steps []string
    59  
    60  	// routes is the sequence of routes we will provide to the
    61  	// router when it requests a new route.
    62  	routes []*route.Route
    63  
    64  	// paymentErr is the error we expect our payment to fail with. This
    65  	// should be nil for tests with paymentSuccess steps and non-nil for
    66  	// payments with paymentError steps.
    67  	paymentErr error
    68  }
    69  
    70  const (
    71  	// routerInitPayment is a test step where we expect the router
    72  	// to call the InitPayment method on the control tower.
    73  	routerInitPayment = "Router:init-payment"
    74  
    75  	// routerRegisterAttempt is a test step where we expect the
    76  	// router to call the RegisterAttempt method on the control
    77  	// tower.
    78  	routerRegisterAttempt = "Router:register-attempt"
    79  
    80  	// routerSettleAttempt is a test step where we expect the
    81  	// router to call the SettleAttempt method on the control
    82  	// tower.
    83  	routerSettleAttempt = "Router:settle-attempt"
    84  
    85  	// routerFailAttempt is a test step where we expect the router
    86  	// to call the FailAttempt method on the control tower.
    87  	routerFailAttempt = "Router:fail-attempt"
    88  
    89  	// routerFailPayment is a test step where we expect the router
    90  	// to call the Fail method on the control tower.
    91  	routerFailPayment = "Router:fail-payment"
    92  
    93  	// routeRelease is a test step where we unblock pathfinding and
    94  	// allow it to respond to our test with a route.
    95  	routeRelease = "PaymentSession:release"
    96  
    97  	// sendToSwitchSuccess is a step where we expect the router to
    98  	// call send the payment attempt to the switch, and we will
    99  	// respond with a non-error, indicating that the payment
   100  	// attempt was successfully forwarded.
   101  	sendToSwitchSuccess = "SendToSwitch:success"
   102  
   103  	// sendToSwitchResultFailure is a step where we expect the
   104  	// router to send the payment attempt to the switch, and we
   105  	// will respond with a forwarding error. This can happen when
   106  	// forwarding fail on our local links.
   107  	sendToSwitchResultFailure = "SendToSwitch:failure"
   108  
   109  	// getPaymentResultSuccess is a test step where we expect the
   110  	// router to call the GetPaymentResult method, and we will
   111  	// respond with a successful payment result.
   112  	getPaymentResultSuccess = "GetPaymentResult:success"
   113  
   114  	// getPaymentResultTempFailure is a test step where we expect the
   115  	// router to call the GetPaymentResult method, and we will
   116  	// respond with a forwarding error, expecting the router to retry.
   117  	getPaymentResultTempFailure = "GetPaymentResult:temp-failure"
   118  
   119  	// getPaymentResultTerminalFailure is a test step where we
   120  	// expect the router to call the GetPaymentResult method, and
   121  	// we will respond with a terminal error, expecting the router
   122  	// to stop making payment attempts.
   123  	getPaymentResultTerminalFailure = "GetPaymentResult:terminal-failure"
   124  
   125  	// resendPayment is a test step where we manually try to resend
   126  	// the same payment, making sure the router responds with an
   127  	// error indicating that it is already in flight.
   128  	resendPayment = "ResendPayment"
   129  
   130  	// startRouter is a step where we manually start the router,
   131  	// used to test that it automatically will resume payments at
   132  	// startup.
   133  	startRouter = "StartRouter"
   134  
   135  	// stopRouter is a test step where we manually make the router
   136  	// shut down.
   137  	stopRouter = "StopRouter"
   138  
   139  	// paymentSuccess is a step where assert that we receive a
   140  	// successful result for the original payment made.
   141  	paymentSuccess = "PaymentSuccess"
   142  
   143  	// paymentError is a step where assert that we receive an error
   144  	// for the original payment made.
   145  	paymentError = "PaymentError"
   146  
   147  	// resentPaymentSuccess is a step where assert that we receive
   148  	// a successful result for a payment that was resent.
   149  	resentPaymentSuccess = "ResentPaymentSuccess"
   150  
   151  	// resentPaymentError is a step where assert that we receive an
   152  	// error for a payment that was resent.
   153  	resentPaymentError = "ResentPaymentError"
   154  )
   155  
   156  // TestRouterPaymentStateMachine tests that the router interacts as expected
   157  // with the ControlTower during a payment lifecycle, such that it payment
   158  // attempts are not sent twice to the switch, and results are handled after a
   159  // restart.
   160  func TestRouterPaymentStateMachine(t *testing.T) {
   161  	t.Parallel()
   162  
   163  	const startingBlockHeight = 101
   164  
   165  	// Setup two simple channels such that we can mock sending along this
   166  	// route.
   167  	chanCapSat := dcrutil.Amount(100000)
   168  	testChannels := []*testChannel{
   169  		symmetricTestChannel("a", "b", chanCapSat, &testChannelPolicy{
   170  			Expiry:  144,
   171  			FeeRate: 400,
   172  			MinHTLC: 1,
   173  			MaxHTLC: lnwire.NewMAtomsFromAtoms(chanCapSat),
   174  		}, 1),
   175  		symmetricTestChannel("b", "c", chanCapSat, &testChannelPolicy{
   176  			Expiry:  144,
   177  			FeeRate: 400,
   178  			MinHTLC: 1,
   179  			MaxHTLC: lnwire.NewMAtomsFromAtoms(chanCapSat),
   180  		}, 2),
   181  	}
   182  
   183  	testGraph, err := createTestGraphFromChannels(true, testChannels, "a")
   184  	if err != nil {
   185  		t.Fatalf("unable to create graph: %v", err)
   186  	}
   187  	defer testGraph.cleanUp()
   188  
   189  	paymentAmt := lnwire.NewMAtomsFromAtoms(1000)
   190  
   191  	// We create a simple route that we will supply every time the router
   192  	// requests one.
   193  	rt, err := createTestRoute(paymentAmt, testGraph.aliasMap)
   194  	if err != nil {
   195  		t.Fatalf("unable to create route: %v", err)
   196  	}
   197  
   198  	tests := []paymentLifecycleTestCase{
   199  		{
   200  			// Tests a normal payment flow that succeeds.
   201  			name: "single shot success",
   202  
   203  			steps: []string{
   204  				routerInitPayment,
   205  				routeRelease,
   206  				routerRegisterAttempt,
   207  				sendToSwitchSuccess,
   208  				getPaymentResultSuccess,
   209  				routerSettleAttempt,
   210  				paymentSuccess,
   211  			},
   212  			routes: []*route.Route{rt},
   213  		},
   214  		{
   215  			// A payment flow with a failure on the first attempt,
   216  			// but that succeeds on the second attempt.
   217  			name: "single shot retry",
   218  
   219  			steps: []string{
   220  				routerInitPayment,
   221  				routeRelease,
   222  				routerRegisterAttempt,
   223  				sendToSwitchSuccess,
   224  
   225  				// Make the first sent attempt fail.
   226  				getPaymentResultTempFailure,
   227  				routerFailAttempt,
   228  
   229  				// The router should retry.
   230  				routeRelease,
   231  				routerRegisterAttempt,
   232  				sendToSwitchSuccess,
   233  
   234  				// Make the second sent attempt succeed.
   235  				getPaymentResultSuccess,
   236  				routerSettleAttempt,
   237  				paymentSuccess,
   238  			},
   239  			routes: []*route.Route{rt, rt},
   240  		},
   241  		{
   242  			// A payment flow with a forwarding failure first time
   243  			// sending to the switch, but that succeeds on the
   244  			// second attempt.
   245  			name: "single shot switch failure",
   246  
   247  			steps: []string{
   248  				routerInitPayment,
   249  				routeRelease,
   250  				routerRegisterAttempt,
   251  
   252  				// Make the first sent attempt fail.
   253  				sendToSwitchResultFailure,
   254  				routerFailAttempt,
   255  
   256  				// The router should retry.
   257  				routeRelease,
   258  				routerRegisterAttempt,
   259  				sendToSwitchSuccess,
   260  
   261  				// Make the second sent attempt succeed.
   262  				getPaymentResultSuccess,
   263  				routerSettleAttempt,
   264  				paymentSuccess,
   265  			},
   266  			routes: []*route.Route{rt, rt},
   267  		},
   268  		{
   269  			// A payment that fails on the first attempt, and has
   270  			// only one route available to try. It will therefore
   271  			// fail permanently.
   272  			name: "single shot route fails",
   273  
   274  			steps: []string{
   275  				routerInitPayment,
   276  				routeRelease,
   277  				routerRegisterAttempt,
   278  				sendToSwitchSuccess,
   279  
   280  				// Make the first sent attempt fail.
   281  				getPaymentResultTempFailure,
   282  				routerFailAttempt,
   283  
   284  				routeRelease,
   285  
   286  				// Since there are no more routes to try, the
   287  				// payment should fail.
   288  				routerFailPayment,
   289  				paymentError,
   290  			},
   291  			routes:     []*route.Route{rt},
   292  			paymentErr: channeldb.FailureReasonNoRoute,
   293  		},
   294  		{
   295  			// We expect the payment to fail immediately if we have
   296  			// no routes to try.
   297  			name: "single shot no route",
   298  
   299  			steps: []string{
   300  				routerInitPayment,
   301  				routeRelease,
   302  				routerFailPayment,
   303  				paymentError,
   304  			},
   305  			routes:     []*route.Route{},
   306  			paymentErr: channeldb.FailureReasonNoRoute,
   307  		},
   308  		{
   309  			// A normal payment flow, where we attempt to resend
   310  			// the same payment after each step. This ensures that
   311  			// the router don't attempt to resend a payment already
   312  			// in flight.
   313  			name: "single shot resend",
   314  
   315  			steps: []string{
   316  				routerInitPayment,
   317  				routeRelease,
   318  				routerRegisterAttempt,
   319  
   320  				// Manually resend the payment, the router
   321  				// should attempt to init with the control
   322  				// tower, but fail since it is already in
   323  				// flight.
   324  				resendPayment,
   325  				routerInitPayment,
   326  				resentPaymentError,
   327  
   328  				// The original payment should proceed as
   329  				// normal.
   330  				sendToSwitchSuccess,
   331  
   332  				// Again resend the payment and assert it's not
   333  				// allowed.
   334  				resendPayment,
   335  				routerInitPayment,
   336  				resentPaymentError,
   337  
   338  				// Notify about a success for the original
   339  				// payment.
   340  				getPaymentResultSuccess,
   341  				routerSettleAttempt,
   342  
   343  				// Now that the original payment finished,
   344  				// resend it again to ensure this is not
   345  				// allowed.
   346  				resendPayment,
   347  				routerInitPayment,
   348  				resentPaymentError,
   349  				paymentSuccess,
   350  			},
   351  			routes: []*route.Route{rt},
   352  		},
   353  		{
   354  			// Tests that the router is able to handle the
   355  			// receieved payment result after a restart.
   356  			name: "single shot restart",
   357  
   358  			steps: []string{
   359  				routerInitPayment,
   360  				routeRelease,
   361  				routerRegisterAttempt,
   362  				sendToSwitchSuccess,
   363  
   364  				// Shut down the router. The original caller
   365  				// should get notified about this.
   366  				stopRouter,
   367  				paymentError,
   368  
   369  				// Start the router again, and ensure the
   370  				// router registers the success with the
   371  				// control tower.
   372  				startRouter,
   373  				getPaymentResultSuccess,
   374  				routerSettleAttempt,
   375  			},
   376  			routes:     []*route.Route{rt},
   377  			paymentErr: ErrRouterShuttingDown,
   378  		},
   379  		{
   380  			// Tests that we are allowed to resend a payment after
   381  			// it has permanently failed.
   382  			name: "single shot resend fail",
   383  
   384  			steps: []string{
   385  				routerInitPayment,
   386  				routeRelease,
   387  				routerRegisterAttempt,
   388  				sendToSwitchSuccess,
   389  
   390  				// Resending the payment at this stage should
   391  				// not be allowed.
   392  				resendPayment,
   393  				routerInitPayment,
   394  				resentPaymentError,
   395  
   396  				// Make the first attempt fail.
   397  				getPaymentResultTempFailure,
   398  				routerFailAttempt,
   399  
   400  				// Since we have no more routes to try, the
   401  				// original payment should fail.
   402  				routeRelease,
   403  				routerFailPayment,
   404  				paymentError,
   405  
   406  				// Now resend the payment again. This should be
   407  				// allowed, since the payment has failed.
   408  				resendPayment,
   409  				routerInitPayment,
   410  				routeRelease,
   411  				routerRegisterAttempt,
   412  				sendToSwitchSuccess,
   413  				getPaymentResultSuccess,
   414  				routerSettleAttempt,
   415  				resentPaymentSuccess,
   416  			},
   417  			routes:     []*route.Route{rt},
   418  			paymentErr: channeldb.FailureReasonNoRoute,
   419  		},
   420  	}
   421  
   422  	for _, test := range tests {
   423  		test := test
   424  		t.Run(test.name, func(t *testing.T) {
   425  			testPaymentLifecycle(
   426  				t, test, paymentAmt, startingBlockHeight,
   427  				testGraph,
   428  			)
   429  		})
   430  	}
   431  }
   432  
   433  func testPaymentLifecycle(t *testing.T, test paymentLifecycleTestCase,
   434  	paymentAmt lnwire.MilliAtom, startingBlockHeight uint32,
   435  	testGraph *testGraphInstance) {
   436  
   437  	// Create a mock control tower with channels set up, that we use to
   438  	// synchronize and listen for events.
   439  	control := makeMockControlTower()
   440  	control.init = make(chan initArgs)
   441  	control.registerAttempt = make(chan registerAttemptArgs)
   442  	control.settleAttempt = make(chan settleAttemptArgs)
   443  	control.failAttempt = make(chan failAttemptArgs)
   444  	control.failPayment = make(chan failPaymentArgs)
   445  	control.fetchInFlight = make(chan struct{})
   446  
   447  	// setupRouter is a helper method that creates and starts the router in
   448  	// the desired configuration for this test.
   449  	setupRouter := func() (*ChannelRouter, chan error,
   450  		chan *htlcswitch.PaymentResult) {
   451  
   452  		chain := newMockChain(startingBlockHeight)
   453  		chainView := newMockChainView(chain)
   454  
   455  		// We set uo the use the following channels and a mock Payer to
   456  		// synchonize with the interaction to the Switch.
   457  		sendResult := make(chan error)
   458  		paymentResult := make(chan *htlcswitch.PaymentResult)
   459  
   460  		payer := &mockPayerOld{
   461  			sendResult:    sendResult,
   462  			paymentResult: paymentResult,
   463  		}
   464  
   465  		router, err := New(Config{
   466  			Graph:              testGraph.graph,
   467  			Chain:              chain,
   468  			ChainView:          chainView,
   469  			Control:            control,
   470  			SessionSource:      &mockPaymentSessionSourceOld{},
   471  			MissionControl:     &mockMissionControlOld{},
   472  			Payer:              payer,
   473  			ChannelPruneExpiry: time.Hour * 24,
   474  			GraphPruneInterval: time.Hour * 2,
   475  			NextPaymentID: func() (uint64, error) {
   476  				next := atomic.AddUint64(&uniquePaymentID, 1)
   477  				return next, nil
   478  			},
   479  			Clock: clock.NewTestClock(time.Unix(1, 0)),
   480  		})
   481  		if err != nil {
   482  			t.Fatalf("unable to create router %v", err)
   483  		}
   484  
   485  		// On startup, the router should fetch all pending payments
   486  		// from the ControlTower, so assert that here.
   487  		errCh := make(chan error)
   488  		go func() {
   489  			close(errCh)
   490  			select {
   491  			case <-control.fetchInFlight:
   492  				return
   493  			case <-time.After(1 * time.Second):
   494  				errCh <- errors.New("router did not fetch in flight " +
   495  					"payments")
   496  			}
   497  		}()
   498  
   499  		if err := router.Start(); err != nil {
   500  			t.Fatalf("unable to start router: %v", err)
   501  		}
   502  
   503  		select {
   504  		case err := <-errCh:
   505  			if err != nil {
   506  				t.Fatalf("error in anonymous goroutine: %s", err)
   507  			}
   508  		case <-time.After(1 * time.Second):
   509  			t.Fatalf("did not fetch in flight payments at startup")
   510  		}
   511  
   512  		return router, sendResult, paymentResult
   513  	}
   514  
   515  	router, sendResult, getPaymentResult := setupRouter()
   516  	defer func() {
   517  		if err := router.Stop(); err != nil {
   518  			t.Fatal(err)
   519  		}
   520  	}()
   521  
   522  	// Craft a LightningPayment struct.
   523  	var preImage lntypes.Preimage
   524  	if _, err := rand.Read(preImage[:]); err != nil {
   525  		t.Fatalf("unable to generate preimage")
   526  	}
   527  
   528  	payHash := preImage.Hash()
   529  
   530  	payment := LightningPayment{
   531  		Target:      testGraph.aliasMap["c"],
   532  		Amount:      paymentAmt,
   533  		FeeLimit:    noFeeLimit,
   534  		paymentHash: &payHash,
   535  	}
   536  
   537  	// Setup our payment session source to block on release of
   538  	// routes.
   539  	routeChan := make(chan struct{})
   540  	router.cfg.SessionSource = &mockPaymentSessionSourceOld{
   541  		routes:       test.routes,
   542  		routeRelease: routeChan,
   543  	}
   544  
   545  	router.cfg.MissionControl = &mockMissionControlOld{}
   546  
   547  	// Send the payment. Since this is new payment hash, the
   548  	// information should be registered with the ControlTower.
   549  	paymentResult := make(chan error)
   550  	done := make(chan struct{})
   551  	go func() {
   552  		_, _, err := router.SendPayment(&payment)
   553  		paymentResult <- err
   554  		close(done)
   555  	}()
   556  
   557  	var resendResult chan error
   558  	for i, step := range test.steps {
   559  		i, step := i, step
   560  
   561  		// fatal is a helper closure that wraps the step info.
   562  		fatal := func(err string, args ...interface{}) {
   563  			if args != nil {
   564  				err = fmt.Sprintf(err, args)
   565  			}
   566  			t.Fatalf(
   567  				"test case: %s failed on step [%v:%s], err: %s",
   568  				test.name, i, step, err,
   569  			)
   570  		}
   571  
   572  		switch step {
   573  
   574  		case routerInitPayment:
   575  			var args initArgs
   576  			select {
   577  			case args = <-control.init:
   578  			case <-time.After(stepTimeout):
   579  				fatal("no init payment with control")
   580  			}
   581  
   582  			if args.c == nil {
   583  				fatal("expected non-nil CreationInfo")
   584  			}
   585  
   586  		case routeRelease:
   587  			select {
   588  			case <-routeChan:
   589  			case <-time.After(stepTimeout):
   590  				fatal("no route requested")
   591  			}
   592  
   593  		// In this step we expect the router to make a call to
   594  		// register a new attempt with the ControlTower.
   595  		case routerRegisterAttempt:
   596  			var args registerAttemptArgs
   597  			select {
   598  			case args = <-control.registerAttempt:
   599  			case <-time.After(stepTimeout):
   600  				fatal("attempt not registered with control")
   601  			}
   602  
   603  			if args.a == nil {
   604  				fatal("expected non-nil AttemptInfo")
   605  			}
   606  
   607  		// In this step we expect the router to call the
   608  		// ControlTower's SettleAttempt method with the preimage.
   609  		case routerSettleAttempt:
   610  			select {
   611  			case <-control.settleAttempt:
   612  			case <-time.After(stepTimeout):
   613  				fatal("attempt settle not " +
   614  					"registered with control")
   615  			}
   616  
   617  		// In this step we expect the router to call the
   618  		// ControlTower's FailAttempt method with a HTLC fail
   619  		// info.
   620  		case routerFailAttempt:
   621  			select {
   622  			case <-control.failAttempt:
   623  			case <-time.After(stepTimeout):
   624  				fatal("attempt fail not " +
   625  					"registered with control")
   626  			}
   627  
   628  		// In this step we expect the router to call the
   629  		// ControlTower's Fail method, to indicate that the
   630  		// payment failed.
   631  		case routerFailPayment:
   632  			select {
   633  			case <-control.failPayment:
   634  			case <-time.After(stepTimeout):
   635  				fatal("payment fail not " +
   636  					"registered with control")
   637  			}
   638  
   639  		// In this step we expect the SendToSwitch method to be
   640  		// called, and we respond with a nil-error.
   641  		case sendToSwitchSuccess:
   642  			select {
   643  			case sendResult <- nil:
   644  			case <-time.After(stepTimeout):
   645  				fatal("unable to send result")
   646  			}
   647  
   648  		// In this step we expect the SendToSwitch method to be
   649  		// called, and we respond with a forwarding error
   650  		case sendToSwitchResultFailure:
   651  			select {
   652  			case sendResult <- htlcswitch.NewForwardingError(
   653  				&lnwire.FailTemporaryChannelFailure{},
   654  				1,
   655  			):
   656  			case <-time.After(stepTimeout):
   657  				fatal("unable to send result")
   658  			}
   659  
   660  		// In this step we expect the GetPaymentResult method
   661  		// to be called, and we respond with the preimage to
   662  		// complete the payment.
   663  		case getPaymentResultSuccess:
   664  			select {
   665  			case getPaymentResult <- &htlcswitch.PaymentResult{
   666  				Preimage: preImage,
   667  			}:
   668  			case <-time.After(stepTimeout):
   669  				fatal("unable to send result")
   670  			}
   671  
   672  		// In this state we expect the GetPaymentResult method
   673  		// to be called, and we respond with a forwarding
   674  		// error, indicating that the router should retry.
   675  		case getPaymentResultTempFailure:
   676  			failure := htlcswitch.NewForwardingError(
   677  				&lnwire.FailTemporaryChannelFailure{},
   678  				1,
   679  			)
   680  
   681  			select {
   682  			case getPaymentResult <- &htlcswitch.PaymentResult{
   683  				Error: failure,
   684  			}:
   685  			case <-time.After(stepTimeout):
   686  				fatal("unable to get result")
   687  			}
   688  
   689  		// In this state we expect the router to call the
   690  		// GetPaymentResult method, and we will respond with a
   691  		// terminal error, indiating the router should stop
   692  		// making payment attempts.
   693  		case getPaymentResultTerminalFailure:
   694  			failure := htlcswitch.NewForwardingError(
   695  				&lnwire.FailIncorrectDetails{},
   696  				1,
   697  			)
   698  
   699  			select {
   700  			case getPaymentResult <- &htlcswitch.PaymentResult{
   701  				Error: failure,
   702  			}:
   703  			case <-time.After(stepTimeout):
   704  				fatal("unable to get result")
   705  			}
   706  
   707  		// In this step we manually try to resend the same
   708  		// payment, making sure the router responds with an
   709  		// error indicating that it is already in flight.
   710  		case resendPayment:
   711  			resendResult = make(chan error)
   712  			go func() {
   713  				_, _, err := router.SendPayment(&payment)
   714  				resendResult <- err
   715  			}()
   716  
   717  		// In this step we manually stop the router.
   718  		case stopRouter:
   719  			// On shutdown, the switch closes our result channel.
   720  			// Mimic this behavior in our mock.
   721  			close(getPaymentResult)
   722  
   723  			if err := router.Stop(); err != nil {
   724  				fatal("unable to restart: %v", err)
   725  			}
   726  
   727  		// In this step we manually start the router.
   728  		case startRouter:
   729  			router, sendResult, getPaymentResult = setupRouter()
   730  
   731  		// In this state we expect to receive an error for the
   732  		// original payment made.
   733  		case paymentError:
   734  			require.Error(t, test.paymentErr,
   735  				"paymentError not set")
   736  
   737  			select {
   738  			case err := <-paymentResult:
   739  				require.Equal(t, test.paymentErr, err)
   740  
   741  			case <-time.After(stepTimeout):
   742  				fatal("got no payment result")
   743  			}
   744  
   745  		// In this state we expect the original payment to
   746  		// succeed.
   747  		case paymentSuccess:
   748  			require.Nil(t, test.paymentErr)
   749  
   750  			select {
   751  			case err := <-paymentResult:
   752  				if err != nil {
   753  					t.Fatalf("did not expect "+
   754  						"error %v", err)
   755  				}
   756  
   757  			case <-time.After(stepTimeout):
   758  				fatal("got no payment result")
   759  			}
   760  
   761  		// In this state we expect to receive an error for the
   762  		// resent payment made.
   763  		case resentPaymentError:
   764  			select {
   765  			case err := <-resendResult:
   766  				if err == nil {
   767  					t.Fatalf("expected error")
   768  				}
   769  
   770  			case <-time.After(stepTimeout):
   771  				fatal("got no payment result")
   772  			}
   773  
   774  		// In this state we expect the resent payment to
   775  		// succeed.
   776  		case resentPaymentSuccess:
   777  			select {
   778  			case err := <-resendResult:
   779  				if err != nil {
   780  					t.Fatalf("did not expect error %v", err)
   781  				}
   782  
   783  			case <-time.After(stepTimeout):
   784  				fatal("got no payment result")
   785  			}
   786  
   787  		default:
   788  			fatal("unknown step %v", step)
   789  		}
   790  	}
   791  
   792  	select {
   793  	case <-done:
   794  	case <-time.After(testTimeout):
   795  		t.Fatalf("SendPayment didn't exit")
   796  	}
   797  }
   798  
   799  // TestPaymentState tests that the logics implemented on paymentState struct
   800  // are as expected. In particular, that the method terminated and
   801  // needWaitForShards return the right values.
   802  func TestPaymentState(t *testing.T) {
   803  	t.Parallel()
   804  
   805  	testCases := []struct {
   806  		name string
   807  
   808  		// Use the following three params, each is equivalent to a bool
   809  		// statement, to construct 8 test cases so that we can
   810  		// exhaustively catch all possible states.
   811  		numShardsInFlight int
   812  		remainingAmt      lnwire.MilliAtom
   813  		terminate         bool
   814  
   815  		expectedTerminated        bool
   816  		expectedNeedWaitForShards bool
   817  	}{
   818  		{
   819  			// If we have active shards and terminate is marked
   820  			// false, the state is not terminated. Since the
   821  			// remaining amount is zero, we need to wait for shards
   822  			// to be finished and launch no more shards.
   823  			name:                      "state 100",
   824  			numShardsInFlight:         1,
   825  			remainingAmt:              lnwire.MilliAtom(0),
   826  			terminate:                 false,
   827  			expectedTerminated:        false,
   828  			expectedNeedWaitForShards: true,
   829  		},
   830  		{
   831  			// If we have active shards while terminate is marked
   832  			// true, the state is not terminated, and we need to
   833  			// wait for shards to be finished and launch no more
   834  			// shards.
   835  			name:                      "state 101",
   836  			numShardsInFlight:         1,
   837  			remainingAmt:              lnwire.MilliAtom(0),
   838  			terminate:                 true,
   839  			expectedTerminated:        false,
   840  			expectedNeedWaitForShards: true,
   841  		},
   842  
   843  		{
   844  			// If we have active shards and terminate is marked
   845  			// false, the state is not terminated. Since the
   846  			// remaining amount is not zero, we don't need to wait
   847  			// for shards outcomes and should launch more shards.
   848  			name:                      "state 110",
   849  			numShardsInFlight:         1,
   850  			remainingAmt:              lnwire.MilliAtom(1),
   851  			terminate:                 false,
   852  			expectedTerminated:        false,
   853  			expectedNeedWaitForShards: false,
   854  		},
   855  		{
   856  			// If we have active shards and terminate is marked
   857  			// true, the state is not terminated. Even the
   858  			// remaining amount is not zero, we need to wait for
   859  			// shards outcomes because state is terminated.
   860  			name:                      "state 111",
   861  			numShardsInFlight:         1,
   862  			remainingAmt:              lnwire.MilliAtom(1),
   863  			terminate:                 true,
   864  			expectedTerminated:        false,
   865  			expectedNeedWaitForShards: true,
   866  		},
   867  		{
   868  			// If we have no active shards while terminate is marked
   869  			// false, the state is not terminated, and we don't
   870  			// need to wait for more shard outcomes because there
   871  			// are no active shards.
   872  			name:                      "state 000",
   873  			numShardsInFlight:         0,
   874  			remainingAmt:              lnwire.MilliAtom(0),
   875  			terminate:                 false,
   876  			expectedTerminated:        false,
   877  			expectedNeedWaitForShards: false,
   878  		},
   879  		{
   880  			// If we have no active shards while terminate is marked
   881  			// true, the state is terminated, and we don't need to
   882  			// wait for shards to be finished.
   883  			name:                      "state 001",
   884  			numShardsInFlight:         0,
   885  			remainingAmt:              lnwire.MilliAtom(0),
   886  			terminate:                 true,
   887  			expectedTerminated:        true,
   888  			expectedNeedWaitForShards: false,
   889  		},
   890  		{
   891  			// If we have no active shards while terminate is marked
   892  			// false, the state is not terminated. Since the
   893  			// remaining amount is not zero, we don't need to wait
   894  			// for shards outcomes and should launch more shards.
   895  			name:                      "state 010",
   896  			numShardsInFlight:         0,
   897  			remainingAmt:              lnwire.MilliAtom(1),
   898  			terminate:                 false,
   899  			expectedTerminated:        false,
   900  			expectedNeedWaitForShards: false,
   901  		},
   902  		{
   903  			// If we have no active shards while terminate is marked
   904  			// true, the state is terminated, and we don't need to
   905  			// wait for shards outcomes.
   906  			name:                      "state 011",
   907  			numShardsInFlight:         0,
   908  			remainingAmt:              lnwire.MilliAtom(1),
   909  			terminate:                 true,
   910  			expectedTerminated:        true,
   911  			expectedNeedWaitForShards: false,
   912  		},
   913  	}
   914  
   915  	for _, tc := range testCases {
   916  		tc := tc
   917  		t.Run(tc.name, func(t *testing.T) {
   918  			t.Parallel()
   919  
   920  			ps := &paymentState{
   921  				numShardsInFlight: tc.numShardsInFlight,
   922  				remainingAmt:      tc.remainingAmt,
   923  				terminate:         tc.terminate,
   924  			}
   925  
   926  			require.Equal(
   927  				t, tc.expectedTerminated, ps.terminated(),
   928  				"terminated returned wrong value",
   929  			)
   930  			require.Equal(
   931  				t, tc.expectedNeedWaitForShards,
   932  				ps.needWaitForShards(),
   933  				"needWaitForShards returned wrong value",
   934  			)
   935  		})
   936  	}
   937  
   938  }
   939  
   940  // TestUpdatePaymentState checks that the method updatePaymentState updates the
   941  // paymentState as expected.
   942  func TestUpdatePaymentState(t *testing.T) {
   943  	t.Parallel()
   944  
   945  	// paymentHash is the identifier on paymentLifecycle.
   946  	paymentHash := lntypes.Hash{}
   947  
   948  	// TODO(yy): make MPPayment into an interface so we can mock it. The
   949  	// current design implicitly tests the methods SendAmt, TerminalInfo,
   950  	// and InFlightHTLCs on channeldb.MPPayment, which is not good. Once
   951  	// MPPayment becomes an interface, we can then mock these methods here.
   952  
   953  	// SentAmt returns 90, 10
   954  	// TerminalInfo returns non-nil, nil
   955  	// InFlightHTLCs returns 0
   956  	var preimage lntypes.Preimage
   957  	paymentSettled := &channeldb.MPPayment{
   958  		HTLCs: []channeldb.HTLCAttempt{
   959  			makeSettledAttempt(100, 10, preimage),
   960  		},
   961  	}
   962  
   963  	// SentAmt returns 0, 0
   964  	// TerminalInfo returns nil, non-nil
   965  	// InFlightHTLCs returns 0
   966  	reason := channeldb.FailureReasonError
   967  	paymentFailed := &channeldb.MPPayment{
   968  		FailureReason: &reason,
   969  	}
   970  
   971  	// SentAmt returns 90, 10
   972  	// TerminalInfo returns nil, nil
   973  	// InFlightHTLCs returns 1
   974  	paymentActive := &channeldb.MPPayment{
   975  		HTLCs: []channeldb.HTLCAttempt{
   976  			makeActiveAttempt(100, 10),
   977  			makeFailedAttempt(100, 10),
   978  		},
   979  	}
   980  
   981  	testCases := []struct {
   982  		name     string
   983  		payment  *channeldb.MPPayment
   984  		totalAmt int
   985  		feeLimit int
   986  
   987  		expectedState     *paymentState
   988  		shouldReturnError bool
   989  	}{
   990  		{
   991  			// Test that the error returned from FetchPayment is
   992  			// handled properly. We use a nil payment to indicate
   993  			// we want to return an error.
   994  			name:              "fetch payment error",
   995  			payment:           nil,
   996  			shouldReturnError: true,
   997  		},
   998  		{
   999  			// Test that when the sentAmt exceeds totalAmount, the
  1000  			// error is returned.
  1001  			name:              "amount exceeded error",
  1002  			payment:           paymentSettled,
  1003  			totalAmt:          1,
  1004  			shouldReturnError: true,
  1005  		},
  1006  		{
  1007  			// Test that when the fee budget is reached, the
  1008  			// remaining fee should be zero.
  1009  			name:     "fee budget reached",
  1010  			payment:  paymentActive,
  1011  			totalAmt: 1000,
  1012  			feeLimit: 1,
  1013  			expectedState: &paymentState{
  1014  				numShardsInFlight: 1,
  1015  				remainingAmt:      1000 - 90,
  1016  				remainingFees:     0,
  1017  				terminate:         false,
  1018  			},
  1019  		},
  1020  		{
  1021  			// Test when the payment is settled, the state should
  1022  			// be marked as terminated.
  1023  			name:     "payment settled",
  1024  			payment:  paymentSettled,
  1025  			totalAmt: 1000,
  1026  			feeLimit: 100,
  1027  			expectedState: &paymentState{
  1028  				numShardsInFlight: 0,
  1029  				remainingAmt:      1000 - 90,
  1030  				remainingFees:     100 - 10,
  1031  				terminate:         true,
  1032  			},
  1033  		},
  1034  		{
  1035  			// Test when the payment is failed, the state should be
  1036  			// marked as terminated.
  1037  			name:     "payment failed",
  1038  			payment:  paymentFailed,
  1039  			totalAmt: 1000,
  1040  			feeLimit: 100,
  1041  			expectedState: &paymentState{
  1042  				numShardsInFlight: 0,
  1043  				remainingAmt:      1000,
  1044  				remainingFees:     100,
  1045  				terminate:         true,
  1046  			},
  1047  		},
  1048  	}
  1049  
  1050  	for _, tc := range testCases {
  1051  		tc := tc
  1052  		t.Run(tc.name, func(t *testing.T) {
  1053  			t.Parallel()
  1054  
  1055  			// Create mock control tower and assign it to router.
  1056  			// We will then use the router and the paymentHash
  1057  			// above to create our paymentLifecycle for this test.
  1058  			ct := &mockControlTower{}
  1059  			rt := &ChannelRouter{cfg: &Config{Control: ct}}
  1060  			pl := &paymentLifecycle{
  1061  				router:      rt,
  1062  				identifier:  paymentHash,
  1063  				totalAmount: lnwire.MilliAtom(tc.totalAmt),
  1064  				feeLimit:    lnwire.MilliAtom(tc.feeLimit),
  1065  			}
  1066  
  1067  			if tc.payment == nil {
  1068  				// A nil payment indicates we want to test an
  1069  				// error returned from FetchPayment.
  1070  				dummyErr := errors.New("dummy")
  1071  				ct.On("FetchPayment", paymentHash).Return(
  1072  					nil, dummyErr,
  1073  				)
  1074  
  1075  			} else {
  1076  				// Otherwise we will return the payment.
  1077  				ct.On("FetchPayment", paymentHash).Return(
  1078  					tc.payment, nil,
  1079  				)
  1080  			}
  1081  
  1082  			// Call the method that updates the payment state.
  1083  			_, state, err := pl.fetchPaymentState()
  1084  
  1085  			// Assert that the mock method is called as
  1086  			// intended.
  1087  			ct.AssertExpectations(t)
  1088  
  1089  			if tc.shouldReturnError {
  1090  				require.Error(t, err, "expect an error")
  1091  				return
  1092  			}
  1093  
  1094  			require.NoError(t, err, "unexpected error")
  1095  			require.Equal(
  1096  				t, tc.expectedState, state,
  1097  				"state not updated as expected",
  1098  			)
  1099  
  1100  		})
  1101  	}
  1102  
  1103  }
  1104  
  1105  func makeActiveAttempt(total, fee int) channeldb.HTLCAttempt {
  1106  	return channeldb.HTLCAttempt{
  1107  		HTLCAttemptInfo: makeAttemptInfo(total, total-fee),
  1108  	}
  1109  }
  1110  
  1111  func makeSettledAttempt(total, fee int,
  1112  	preimage lntypes.Preimage) channeldb.HTLCAttempt {
  1113  
  1114  	return channeldb.HTLCAttempt{
  1115  		HTLCAttemptInfo: makeAttemptInfo(total, total-fee),
  1116  		Settle:          &channeldb.HTLCSettleInfo{Preimage: preimage},
  1117  	}
  1118  }
  1119  
  1120  func makeFailedAttempt(total, fee int) channeldb.HTLCAttempt {
  1121  	return channeldb.HTLCAttempt{
  1122  		HTLCAttemptInfo: makeAttemptInfo(total, total-fee),
  1123  		Failure: &channeldb.HTLCFailInfo{
  1124  			Reason: channeldb.HTLCFailInternal,
  1125  		},
  1126  	}
  1127  }
  1128  
  1129  func makeAttemptInfo(total, amtForwarded int) channeldb.HTLCAttemptInfo {
  1130  	hop := &route.Hop{AmtToForward: lnwire.MilliAtom(amtForwarded)}
  1131  	return channeldb.HTLCAttemptInfo{
  1132  		Route: route.Route{
  1133  			TotalAmount: lnwire.MilliAtom(total),
  1134  			Hops:        []*route.Hop{hop},
  1135  		},
  1136  	}
  1137  }