diff --git a/transactions/payments_test.go b/transactions/payments_test.go index 5c56d36c..4e006dbe 100644 --- a/transactions/payments_test.go +++ b/transactions/payments_test.go @@ -82,6 +82,31 @@ func TestMarkSettled_Sent(t *testing.T) { assert.Equal(t, &dbTransaction, settledTransaction) } +func TestMarkSettled_SentNoPreimage(t *testing.T) { + defer tests.RemoveTestService() + svc, err := tests.CreateTestService() + assert.NoError(t, err) + + dbTransaction := db.Transaction{ + State: constants.TRANSACTION_STATE_PENDING, + Type: constants.TRANSACTION_TYPE_OUTGOING, + PaymentHash: tests.MockLNClientTransaction.PaymentHash, + AmountMsat: 123000, + } + svc.DB.Create(&dbTransaction) + + mockEventConsumer := tests.NewMockEventConsumer() + svc.EventPublisher.RegisterSubscriber(mockEventConsumer) + transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher) + err = svc.DB.Transaction(func(tx *gorm.DB) error { + _, err = transactionsService.markTransactionSettled(tx, &dbTransaction, "", 0, false) + return err + }) + + assert.Error(t, err) + assert.ErrorContains(t, err, "no preimage in payment") +} + func TestMarkSettled_Received(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() @@ -111,6 +136,36 @@ func TestMarkSettled_Received(t *testing.T) { assert.Equal(t, &dbTransaction, settledTransaction) } +func TestMarkSettled_ReceivedNoPreimage(t *testing.T) { + defer tests.RemoveTestService() + svc, err := tests.CreateTestService() + assert.NoError(t, err) + + dbTransaction := db.Transaction{ + State: constants.TRANSACTION_STATE_PENDING, + Type: constants.TRANSACTION_TYPE_INCOMING, + PaymentHash: tests.MockLNClientTransaction.PaymentHash, + AmountMsat: 123000, + } + svc.DB.Create(&dbTransaction) + + mockEventConsumer := tests.NewMockEventConsumer() + svc.EventPublisher.RegisterSubscriber(mockEventConsumer) + transactionsService := NewTransactionsService(svc.DB, svc.EventPublisher) + err = svc.DB.Transaction(func(tx *gorm.DB) error { + _, err = transactionsService.markTransactionSettled(tx, &dbTransaction, "", 0, false) + return err + }) + + // incoming payment does not necessarily need preimage + assert.Nil(t, err) + assert.Equal(t, constants.TRANSACTION_STATE_SETTLED, dbTransaction.State) + assert.Equal(t, 1, len(mockEventConsumer.GetConsumeEvents())) + assert.Equal(t, "nwc_payment_received", mockEventConsumer.GetConsumeEvents()[0].Event) + settledTransaction := mockEventConsumer.GetConsumeEvents()[0].Properties.(*db.Transaction) + assert.Equal(t, &dbTransaction, settledTransaction) +} + func TestDoNotMarkSettledTwice(t *testing.T) { defer tests.RemoveTestService() svc, err := tests.CreateTestService() diff --git a/transactions/transactions_service.go b/transactions/transactions_service.go index 40f4ca4f..130ab890 100644 --- a/transactions/transactions_service.go +++ b/transactions/transactions_service.go @@ -897,7 +897,13 @@ func (svc *transactionsService) markTransactionSettled(tx *gorm.DB, dbTransactio } if preimage == "" { - return nil, errors.New("no preimage in payment") + // outgoing payments MUST have a preimage + if dbTransaction.Type == constants.TRANSACTION_TYPE_OUTGOING { + return nil, errors.New("no preimage in payment") + } + // incoming payments SHOULD have a preimage + // (currently cashu backend does not) + logger.Logger.WithField("payment_hash", dbTransaction.PaymentHash).Warn("no preimage in settled incoming transaction") } now := time.Now()