payments_test.go raw

   1  package transactions
   2  
   3  import (
   4  	"context"
   5  	"encoding/json"
   6  	"errors"
   7  	"fmt"
   8  	"strings"
   9  	"sync"
  10  	"testing"
  11  	"time"
  12  
  13  	"github.com/stretchr/testify/assert"
  14  	"github.com/stretchr/testify/require"
  15  
  16  	"github.com/getAlby/hub/constants"
  17  	"github.com/getAlby/hub/db"
  18  	"github.com/getAlby/hub/events"
  19  	"github.com/getAlby/hub/lnclient"
  20  	"github.com/getAlby/hub/tests"
  21  )
  22  
  23  func TestSendPaymentSync_NoApp(t *testing.T) {
  24  	svc, err := tests.CreateTestService(t)
  25  	require.NoError(t, err)
  26  	defer svc.Remove()
  27  
  28  	metadata := map[string]interface{}{
  29  		"a": 123,
  30  	}
  31  
  32  	transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher)
  33  	transaction, err := transactionsService.SendPaymentSync(tests.MockLNClientTransaction.Invoice, nil, metadata, svc.LNClient, nil, nil)
  34  
  35  	assert.NoError(t, err)
  36  	assert.Equal(t, uint64(123000), transaction.AmountMsat)
  37  	assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, transaction.State)
  38  	assert.Zero(t, transaction.FeeReserveMsat)
  39  	assert.Equal(t, "123preimage", *transaction.Preimage)
  40  
  41  	type dummyMetadata struct {
  42  		A int `json:"a"`
  43  	}
  44  	var decodedMetadata dummyMetadata
  45  	err = json.Unmarshal(transaction.Metadata, &decodedMetadata)
  46  	assert.NoError(t, err)
  47  	assert.Equal(t, 123, decodedMetadata.A)
  48  }
  49  
  50  func TestSendPaymentSync_ZeroAmount(t *testing.T) {
  51  	svc, err := tests.CreateTestService(t)
  52  	require.NoError(t, err)
  53  	defer svc.Remove()
  54  
  55  	metadata := map[string]interface{}{
  56  		"a": 123,
  57  	}
  58  
  59  	transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher)
  60  	amount := uint64(1234)
  61  	transaction, err := transactionsService.SendPaymentSync(tests.MockZeroAmountInvoice, &amount, metadata, svc.LNClient, nil, nil)
  62  
  63  	assert.NoError(t, err)
  64  	assert.Equal(t, amount, transaction.AmountMsat)
  65  	assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, transaction.State)
  66  	assert.Zero(t, transaction.FeeReserveMsat)
  67  	assert.Equal(t, "123preimage", *transaction.Preimage)
  68  }
  69  
  70  func TestSendPaymentSync_AmountOnNonZeroAmountInvoice(t *testing.T) {
  71  	svc, err := tests.CreateTestService(t)
  72  	require.NoError(t, err)
  73  	defer svc.Remove()
  74  
  75  	metadata := map[string]interface{}{
  76  		"a": 123,
  77  	}
  78  
  79  	transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher)
  80  	amount := uint64(1234)
  81  	transaction, err := transactionsService.SendPaymentSync(tests.MockInvoice, &amount, metadata, svc.LNClient, nil, nil)
  82  
  83  	assert.NoError(t, err)
  84  	// amount is from the invoice, not what was specified
  85  	assert.Equal(t, uint64(123_000), transaction.AmountMsat)
  86  	assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, transaction.State)
  87  	assert.Zero(t, transaction.FeeReserveMsat)
  88  	assert.Equal(t, "123preimage", *transaction.Preimage)
  89  }
  90  
  91  func TestSendPaymentSync_MetadataTooLarge(t *testing.T) {
  92  	svc, err := tests.CreateTestService(t)
  93  	require.NoError(t, err)
  94  	defer svc.Remove()
  95  
  96  	metadata := make(map[string]interface{})
  97  	metadata["randomkey"] = strings.Repeat("a", constants.INVOICE_METADATA_MAX_LENGTH-15) // json encoding adds 16 characters
  98  
  99  	transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher)
 100  	transaction, err := transactionsService.SendPaymentSync(tests.MockLNClientTransaction.Invoice, nil, metadata, svc.LNClient, nil, nil)
 101  
 102  	assert.Error(t, err)
 103  	assert.Equal(t, fmt.Sprintf("encoded payment metadata provided is too large. Limit: %d Received: %d", constants.INVOICE_METADATA_MAX_LENGTH, constants.INVOICE_METADATA_MAX_LENGTH+1), err.Error())
 104  	assert.Nil(t, transaction)
 105  }
 106  
 107  func TestSendPaymentSync_Duplicate_AlreadyPaid(t *testing.T) {
 108  	svc, err := tests.CreateTestService(t)
 109  	require.NoError(t, err)
 110  	defer svc.Remove()
 111  
 112  	svc.DB.Create(&db.Transaction{
 113  		State:          constants.TRANSACTION_STATE_SETTLED,
 114  		Type:           constants.TRANSACTION_TYPE_OUTGOING,
 115  		PaymentRequest: tests.MockLNClientTransaction.Invoice,
 116  		PaymentHash:    tests.MockLNClientTransaction.PaymentHash,
 117  		AmountMsat:     123000,
 118  	})
 119  
 120  	transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher)
 121  	transaction, err := transactionsService.SendPaymentSync(tests.MockLNClientTransaction.Invoice, nil, nil, svc.LNClient, nil, nil)
 122  
 123  	assert.Error(t, err)
 124  	assert.Equal(t, "this invoice has already been paid", err.Error())
 125  	assert.Nil(t, transaction)
 126  }
 127  
 128  func TestSendPaymentSync_Duplicate_Pending(t *testing.T) {
 129  	svc, err := tests.CreateTestService(t)
 130  	require.NoError(t, err)
 131  	defer svc.Remove()
 132  
 133  	svc.DB.Create(&db.Transaction{
 134  		State:          constants.TRANSACTION_STATE_PENDING,
 135  		Type:           constants.TRANSACTION_TYPE_OUTGOING,
 136  		PaymentHash:    tests.MockLNClientTransaction.PaymentHash,
 137  		PaymentRequest: tests.MockLNClientTransaction.Invoice,
 138  		AmountMsat:     123000,
 139  	})
 140  
 141  	transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher)
 142  	transaction, err := transactionsService.SendPaymentSync(tests.MockLNClientTransaction.Invoice, nil, nil, svc.LNClient, nil, nil)
 143  
 144  	assert.Error(t, err)
 145  	assert.Equal(t, "there is already a payment pending for this invoice", err.Error())
 146  	assert.Nil(t, transaction)
 147  }
 148  
 149  func TestSendPaymentSync_Duplicate_Failed(t *testing.T) {
 150  	svc, err := tests.CreateTestService(t)
 151  	require.NoError(t, err)
 152  	defer svc.Remove()
 153  
 154  	svc.DB.Create(&db.Transaction{
 155  		State:       constants.TRANSACTION_STATE_FAILED,
 156  		Type:        constants.TRANSACTION_TYPE_OUTGOING,
 157  		PaymentHash: tests.MockLNClientTransaction.PaymentHash,
 158  		AmountMsat:  123000,
 159  	})
 160  
 161  	transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher)
 162  	_, err = transactionsService.SendPaymentSync(tests.MockLNClientTransaction.Invoice, nil, nil, svc.LNClient, nil, nil)
 163  
 164  	assert.NoError(t, err)
 165  }
 166  
 167  func TestMarkSettled_Sent(t *testing.T) {
 168  	svc, err := tests.CreateTestService(t)
 169  	require.NoError(t, err)
 170  	defer svc.Remove()
 171  
 172  	dbTransaction := db.Transaction{
 173  		State:       constants.TRANSACTION_STATE_PENDING,
 174  		Type:        constants.TRANSACTION_TYPE_OUTGOING,
 175  		PaymentHash: tests.MockLNClientTransaction.PaymentHash,
 176  		AmountMsat:  123000,
 177  	}
 178  	svc.DB.Create(&dbTransaction)
 179  
 180  	mockEventConsumer := tests.NewMockEventConsumer()
 181  	svc.EventPublisher.RegisterSubscriber(mockEventConsumer)
 182  	transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher)
 183  	_, err = transactionsService.markTransactionSettled(&dbTransaction, "test", 0, false)
 184  
 185  	assert.NoError(t, err)
 186  	assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, dbTransaction.State)
 187  	consumedEvents := mockEventConsumer.WaitForConsumedEvents(1)
 188  	assert.Equal(t, 1, len(consumedEvents))
 189  	assert.Equal(t, "nwc_payment_sent", consumedEvents[0].Event)
 190  	settledTransaction := consumedEvents[0].Properties.(*db.Transaction)
 191  	assert.Equal(t, &dbTransaction, settledTransaction)
 192  }
 193  
 194  func TestMarkSettled_Twice(t *testing.T) {
 195  	svc, err := tests.CreateTestService(t)
 196  	require.NoError(t, err)
 197  	defer svc.Remove()
 198  
 199  	dbTransaction := db.Transaction{
 200  		State:       constants.TRANSACTION_STATE_PENDING,
 201  		Type:        constants.TRANSACTION_TYPE_OUTGOING,
 202  		PaymentHash: tests.MockLNClientTransaction.PaymentHash,
 203  		AmountMsat:  123000,
 204  	}
 205  	svc.DB.Create(&dbTransaction)
 206  
 207  	mockEventConsumer := tests.NewMockEventConsumer()
 208  	svc.EventPublisher.RegisterSubscriber(mockEventConsumer)
 209  	transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher)
 210  	var wg sync.WaitGroup
 211  	n := 10
 212  	markErrors := make([]error, n)
 213  	wg.Add(n)
 214  	for i := range n {
 215  		go func() {
 216  			defer wg.Done()
 217  			// load an independent copy so goroutines don't share the struct
 218  			var transactionCopy db.Transaction
 219  			if err := svc.DB.First(&transactionCopy, dbTransaction.ID).Error; err != nil {
 220  				markErrors[i] = err
 221  				return
 222  			}
 223  			_, markErrors[i] = transactionsService.markTransactionSettled(&transactionCopy, "test", 0, false)
 224  		}()
 225  	}
 226  	wg.Wait()
 227  
 228  	for _, markError := range markErrors {
 229  		assert.NoError(t, markError)
 230  	}
 231  
 232  	// ensure we only mark transaction settled once and only fire
 233  	// settled notifications once
 234  	var reloadedTransaction db.Transaction
 235  	require.NoError(t, svc.DB.First(&reloadedTransaction, dbTransaction.ID).Error)
 236  	assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, reloadedTransaction.State)
 237  	consumedEvents := mockEventConsumer.WaitForConsumedEvents(1)
 238  	assert.Equal(t, 1, len(consumedEvents))
 239  	assert.Equal(t, "nwc_payment_sent", consumedEvents[0].Event)
 240  	settledTransaction := consumedEvents[0].Properties.(*db.Transaction)
 241  	assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, settledTransaction.State)
 242  	assert.Equal(t, dbTransaction.PaymentHash, settledTransaction.PaymentHash)
 243  }
 244  
 245  func TestMarkSettled_Received(t *testing.T) {
 246  	svc, err := tests.CreateTestService(t)
 247  	require.NoError(t, err)
 248  	defer svc.Remove()
 249  
 250  	dbTransaction := db.Transaction{
 251  		State:       constants.TRANSACTION_STATE_PENDING,
 252  		Type:        constants.TRANSACTION_TYPE_INCOMING,
 253  		PaymentHash: tests.MockLNClientTransaction.PaymentHash,
 254  		AmountMsat:  123000,
 255  	}
 256  	svc.DB.Create(&dbTransaction)
 257  
 258  	mockEventConsumer := tests.NewMockEventConsumer()
 259  	svc.EventPublisher.RegisterSubscriber(mockEventConsumer)
 260  	transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher)
 261  	_, err = transactionsService.markTransactionSettled(&dbTransaction, "test", 0, false)
 262  
 263  	assert.NoError(t, err)
 264  	assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, dbTransaction.State)
 265  	consumedEvents := mockEventConsumer.WaitForConsumedEvents(1)
 266  	assert.Equal(t, 1, len(consumedEvents))
 267  	assert.Equal(t, "nwc_payment_received", consumedEvents[0].Event)
 268  	settledTransaction := consumedEvents[0].Properties.(*db.Transaction)
 269  	assert.Equal(t, &dbTransaction, settledTransaction)
 270  }
 271  
 272  func TestDoNotMarkSettledTwice(t *testing.T) {
 273  	svc, err := tests.CreateTestService(t)
 274  	require.NoError(t, err)
 275  	defer svc.Remove()
 276  
 277  	settledAt := time.Now().Add(time.Duration(-1) * time.Minute)
 278  	dbTransaction := db.Transaction{
 279  		State:       constants.TRANSACTION_STATE_SETTLED,
 280  		Type:        constants.TRANSACTION_TYPE_OUTGOING,
 281  		PaymentHash: tests.MockLNClientTransaction.PaymentHash,
 282  		AmountMsat:  123000,
 283  		SettledAt:   &settledAt,
 284  	}
 285  	svc.DB.Create(&dbTransaction)
 286  
 287  	mockEventConsumer := tests.NewMockEventConsumer()
 288  	svc.EventPublisher.RegisterSubscriber(mockEventConsumer)
 289  	transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher)
 290  	_, err = transactionsService.markTransactionSettled(&dbTransaction, "test", 0, false)
 291  
 292  	assert.NoError(t, err)
 293  	assert.Zero(t, len(mockEventConsumer.GetConsumedEvents()))
 294  }
 295  
 296  func TestMarkFailed(t *testing.T) {
 297  	svc, err := tests.CreateTestService(t)
 298  	require.NoError(t, err)
 299  	defer svc.Remove()
 300  
 301  	dbTransaction := db.Transaction{
 302  		State:       constants.TRANSACTION_STATE_PENDING,
 303  		Type:        constants.TRANSACTION_TYPE_OUTGOING,
 304  		PaymentHash: tests.MockLNClientTransaction.PaymentHash,
 305  		AmountMsat:  123000,
 306  	}
 307  	svc.DB.Create(&dbTransaction)
 308  
 309  	mockEventConsumer := tests.NewMockEventConsumer()
 310  	svc.EventPublisher.RegisterSubscriber(mockEventConsumer)
 311  	transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher)
 312  	markedFailed, err := transactionsService.markPaymentFailed(&dbTransaction, "some routing error")
 313  
 314  	assert.NoError(t, err)
 315  	assert.True(t, markedFailed)
 316  	assert.Equal(t, constants.TRANSACTION_STATE_FAILED, dbTransaction.State)
 317  	consumedEvents := mockEventConsumer.WaitForConsumedEvents(1)
 318  	assert.Equal(t, 1, len(consumedEvents))
 319  	assert.Equal(t, "nwc_payment_failed", consumedEvents[0].Event)
 320  	settledTransaction := consumedEvents[0].Properties.(*db.Transaction)
 321  	assert.Equal(t, &dbTransaction, settledTransaction)
 322  	assert.Equal(t, "some routing error", settledTransaction.FailureReason)
 323  }
 324  
 325  func TestDoNotMarkFailedTwice(t *testing.T) {
 326  	svc, err := tests.CreateTestService(t)
 327  	require.NoError(t, err)
 328  	defer svc.Remove()
 329  
 330  	updatedAt := time.Now().Add(time.Duration(-1) * time.Minute)
 331  	dbTransaction := db.Transaction{
 332  		State:       constants.TRANSACTION_STATE_FAILED,
 333  		Type:        constants.TRANSACTION_TYPE_OUTGOING,
 334  		PaymentHash: tests.MockLNClientTransaction.PaymentHash,
 335  		AmountMsat:  123000,
 336  		UpdatedAt:   updatedAt,
 337  	}
 338  	svc.DB.Create(&dbTransaction)
 339  
 340  	mockEventConsumer := tests.NewMockEventConsumer()
 341  	svc.EventPublisher.RegisterSubscriber(mockEventConsumer)
 342  	transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher)
 343  	markedFailed, err := transactionsService.markPaymentFailed(&dbTransaction, "some routing error")
 344  
 345  	assert.NoError(t, err)
 346  	assert.False(t, markedFailed)
 347  	assert.Equal(t, updatedAt, dbTransaction.UpdatedAt)
 348  	assert.Zero(t, len(mockEventConsumer.GetConsumedEvents()))
 349  }
 350  
 351  func TestDoNotMarkSettledPaymentFailed(t *testing.T) {
 352  	svc, err := tests.CreateTestService(t)
 353  	require.NoError(t, err)
 354  	defer svc.Remove()
 355  
 356  	settledAt := time.Now()
 357  	dbTransaction := db.Transaction{
 358  		State:       constants.TRANSACTION_STATE_SETTLED,
 359  		Type:        constants.TRANSACTION_TYPE_OUTGOING,
 360  		PaymentHash: tests.MockLNClientTransaction.PaymentHash,
 361  		AmountMsat:  123000,
 362  		SettledAt:   &settledAt,
 363  	}
 364  	svc.DB.Create(&dbTransaction)
 365  
 366  	mockEventConsumer := tests.NewMockEventConsumer()
 367  	svc.EventPublisher.RegisterSubscriber(mockEventConsumer)
 368  	transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher)
 369  	markedFailed, err := transactionsService.markPaymentFailed(&dbTransaction, "some routing error")
 370  
 371  	assert.Error(t, err)
 372  	assert.False(t, markedFailed)
 373  
 374  	var reloadedTransaction db.Transaction
 375  	require.NoError(t, svc.DB.First(&reloadedTransaction, dbTransaction.ID).Error)
 376  	assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, reloadedTransaction.State)
 377  	assert.Zero(t, len(mockEventConsumer.GetConsumedEvents()))
 378  }
 379  
 380  func TestSendPaymentSync_FailedRemovesFeeReserve(t *testing.T) {
 381  	svc, err := tests.CreateTestService(t)
 382  	require.NoError(t, err)
 383  	defer svc.Remove()
 384  
 385  	svc.LNClient.(*tests.MockLn).PayInvoiceErrors = append(svc.LNClient.(*tests.MockLn).PayInvoiceErrors, errors.New("Some error"))
 386  	svc.LNClient.(*tests.MockLn).PayInvoiceResponses = append(svc.LNClient.(*tests.MockLn).PayInvoiceResponses, nil)
 387  
 388  	mockEventConsumer := tests.NewMockEventConsumer()
 389  	svc.EventPublisher.RegisterSubscriber(mockEventConsumer)
 390  
 391  	transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher)
 392  	transaction, err := transactionsService.SendPaymentSync(tests.MockLNClientTransaction.Invoice, nil, nil, svc.LNClient, nil, nil)
 393  
 394  	assert.Error(t, err)
 395  	assert.Nil(t, transaction)
 396  
 397  	transactionType := constants.TRANSACTION_TYPE_OUTGOING
 398  	transaction, err = transactionsService.LookupTransaction(context.TODO(), tests.MockLNClientTransaction.PaymentHash, &transactionType, svc.LNClient, nil)
 399  	assert.NoError(t, err)
 400  
 401  	assert.Equal(t, uint64(123000), transaction.AmountMsat)
 402  	assert.Equal(t, constants.TRANSACTION_STATE_FAILED, transaction.State)
 403  	assert.Zero(t, transaction.FeeReserveMsat)
 404  	assert.Nil(t, transaction.Preimage)
 405  
 406  	consumedEvents := mockEventConsumer.WaitForConsumedEvents(1)
 407  	assert.Equal(t, 1, len(consumedEvents))
 408  	assert.Equal(t, "nwc_payment_failed", consumedEvents[0].Event)
 409  }
 410  
 411  func TestSendPaymentSync_PendingHasFeeReserve(t *testing.T) {
 412  	svc, err := tests.CreateTestService(t)
 413  	require.NoError(t, err)
 414  	defer svc.Remove()
 415  
 416  	// fake a delay to ensure the payment is still pending
 417  	delay := 10 * time.Second
 418  	svc.LNClient.(*tests.MockLn).PaymentDelay = &delay
 419  
 420  	transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher)
 421  	go func() {
 422  		transactionsService.SendPaymentSync(tests.MockLNClientTransaction.Invoice, nil, nil, svc.LNClient, nil, nil)
 423  	}()
 424  	// ensure the goroutine above runs first
 425  	time.Sleep(10 * time.Millisecond)
 426  
 427  	transactionType := constants.TRANSACTION_TYPE_OUTGOING
 428  	transaction, err := transactionsService.LookupTransaction(context.TODO(), tests.MockLNClientTransaction.PaymentHash, &transactionType, svc.LNClient, nil)
 429  	assert.NoError(t, err)
 430  
 431  	assert.Equal(t, uint64(123000), transaction.AmountMsat)
 432  	assert.Equal(t, constants.TRANSACTION_STATE_PENDING, transaction.State)
 433  	assert.Equal(t, uint64(10000), transaction.FeeReserveMsat)
 434  	assert.Nil(t, transaction.Preimage)
 435  }
 436  
 437  func TestConsumeEvent_FailedMarkedAsSuccessful(t *testing.T) {
 438  	svc, err := tests.CreateTestService(t)
 439  	require.NoError(t, err)
 440  	defer svc.Remove()
 441  
 442  	transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher)
 443  
 444  	svc.LNClient.(*tests.MockLn).PayInvoiceErrors = append(svc.LNClient.(*tests.MockLn).PayInvoiceErrors, errors.New("some error"))
 445  	svc.LNClient.(*tests.MockLn).PayInvoiceResponses = append(svc.LNClient.(*tests.MockLn).PayInvoiceResponses, nil)
 446  
 447  	transaction, err := transactionsService.SendPaymentSync(tests.MockLNClientTransaction.Invoice, nil, nil, svc.LNClient, nil, nil)
 448  
 449  	assert.Error(t, err)
 450  	assert.Nil(t, transaction)
 451  
 452  	var transactions []db.Transaction
 453  	result := svc.DB.Find(&transactions, &db.Transaction{
 454  		Type:        constants.TRANSACTION_TYPE_OUTGOING,
 455  		PaymentHash: tests.MockLNClientTransaction.PaymentHash,
 456  	})
 457  	assert.NoError(t, result.Error)
 458  	assert.Equal(t, 1, len(transactions))
 459  
 460  	transaction = &transactions[0]
 461  	assert.Equal(t, constants.TRANSACTION_STATE_FAILED, transaction.State)
 462  
 463  	// Now that we have a failed transaction, we submit a "nwc_lnclient_payment_sent" event.
 464  	// This should be marked as successful as long as there are no pending payments for the
 465  	// same payment hash
 466  
 467  	transactionsService.ConsumeEvent(context.TODO(), &events.Event{
 468  		Event: "nwc_lnclient_payment_sent",
 469  		Properties: &lnclient.Transaction{
 470  			Type:            tests.MockLNClientTransaction.Type,
 471  			Invoice:         tests.MockLNClientTransaction.Invoice,
 472  			Description:     tests.MockLNClientTransaction.Description,
 473  			DescriptionHash: tests.MockLNClientTransaction.DescriptionHash,
 474  			Preimage:        tests.MockLNClientTransaction.Preimage,
 475  			PaymentHash:     tests.MockLNClientTransaction.PaymentHash,
 476  			AmountMsat:      tests.MockLNClientTransaction.AmountMsat,
 477  			FeesPaidMsat:    tests.MockLNClientTransaction.FeesPaidMsat,
 478  		},
 479  	}, nil)
 480  
 481  	// Re-read transactions and ensure that the single returned transaction
 482  	// is now settled.
 483  	result = svc.DB.Find(&transactions, &db.Transaction{
 484  		Type:        constants.TRANSACTION_TYPE_OUTGOING,
 485  		PaymentHash: tests.MockLNClientTransaction.PaymentHash,
 486  	})
 487  	assert.NoError(t, result.Error)
 488  	assert.Equal(t, 1, len(transactions))
 489  
 490  	transaction = &transactions[0]
 491  	assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, transaction.State)
 492  }
 493