From 977073283a3344c3d0fa9c52c820b140a11b5508 Mon Sep 17 00:00:00 2001 From: elraphty Date: Fri, 18 Oct 2024 21:26:39 +0100 Subject: [PATCH] removed unused poll invoice code --- db/interface.go | 2 +- db/workspaces.go | 69 +++++++++++--------- handlers/bounty.go | 144 ++++++----------------------------------- handlers/workspaces.go | 15 ++++- mocks/Database.go | 21 +++--- 5 files changed, 84 insertions(+), 167 deletions(-) diff --git a/db/interface.go b/db/interface.go index d3d621e8a..d3473f6bd 100644 --- a/db/interface.go +++ b/db/interface.go @@ -106,7 +106,7 @@ type Database interface { GetWorkspaceBudget(workspace_uuid string) NewBountyBudget GetWorkspaceStatusBudget(workspace_uuid string) StatusBudget GetWorkspaceBudgetHistory(workspace_uuid string) []BudgetHistoryData - ProcessUpdateBudget(invoice NewInvoiceList, getLightningInvoice func(payment_request string) (InvoiceResult, InvoiceError)) error + ProcessUpdateBudget(invoice NewInvoiceList) error AddAndUpdateBudget(invoice NewInvoiceList) NewPaymentHistory WithdrawBudget(sender_pubkey string, workspace_uuid string, amount uint) AddPaymentHistory(payment NewPaymentHistory) NewPaymentHistory diff --git a/db/workspaces.go b/db/workspaces.go index 2d4549546..4b352a1a7 100644 --- a/db/workspaces.go +++ b/db/workspaces.go @@ -264,7 +264,7 @@ func (db database) GetWorkspaceBudgetHistory(workspace_uuid string) []BudgetHist return budgetHistory } -func (db database) ProcessUpdateBudget(invoice NewInvoiceList, getLightningInvoice func(payment_request string) (InvoiceResult, InvoiceError)) error { +func (db database) ProcessUpdateBudget(non_tx_invoice NewInvoiceList) error { // Start db transaction tx := db.db.Begin() @@ -280,32 +280,25 @@ func (db database) ProcessUpdateBudget(invoice NewInvoiceList, getLightningInvoi return err } - created := invoice.Created - workspace_uuid := invoice.WorkspaceUuid + created := non_tx_invoice.Created + workspace_uuid := non_tx_invoice.WorkspaceUuid + + invoice := NewInvoiceList{} + tx.Where("payment_request = ?", non_tx_invoice.PaymentRequest).Find(&invoice) if invoice.Status { tx.Rollback() return errors.New("cannot process already paid invoice") } - invoiceRes, invoiceErr := getLightningInvoice(invoice.PaymentRequest) - - if invoiceErr.Error != "" { - tx.Rollback() - return errors.New("could not check invoice") - } - - if !invoiceRes.Response.Settled { - tx.Rollback() - return errors.New("invoice has not been settled") - } - if workspace_uuid == "" { return errors.New("cannot Create a Workspace Without a Workspace uuid") } // Get payment history and update budget - paymentHistory := db.GetPaymentHistoryByCreated(created, workspace_uuid) + paymentHistory := NewPaymentHistory{} + tx.Model(&NewPaymentHistory{}).Where("created = ?", created).Where("workspace_uuid = ? ", workspace_uuid).Find(&paymentHistory) + if paymentHistory.WorkspaceUuid != "" && paymentHistory.Amount != 0 { paymentHistory.Status = true @@ -315,9 +308,10 @@ func (db database) ProcessUpdateBudget(invoice NewInvoiceList, getLightningInvoi } // get Workspace budget and add payment to total budget - WorkspaceBudget := db.GetWorkspaceBudget(workspace_uuid) + workspaceBudget := NewBountyBudget{} + tx.Model(&NewBountyBudget{}).Where("workspace_uuid = ?", workspace_uuid).Find(&workspaceBudget) - if WorkspaceBudget.WorkspaceUuid == "" { + if workspaceBudget.WorkspaceUuid == "" { now := time.Now() workBudget := NewBountyBudget{ WorkspaceUuid: workspace_uuid, @@ -330,11 +324,11 @@ func (db database) ProcessUpdateBudget(invoice NewInvoiceList, getLightningInvoi tx.Rollback() } } else { - totalBudget := WorkspaceBudget.TotalBudget - WorkspaceBudget.TotalBudget = totalBudget + paymentHistory.Amount + totalBudget := workspaceBudget.TotalBudget + workspaceBudget.TotalBudget = totalBudget + paymentHistory.Amount - if err = tx.Model(&NewBountyBudget{}).Where("workspace_uuid = ?", WorkspaceBudget.WorkspaceUuid).Updates(map[string]interface{}{ - "total_budget": WorkspaceBudget.TotalBudget, + if err = tx.Model(&NewBountyBudget{}).Where("workspace_uuid = ?", workspaceBudget.WorkspaceUuid).Updates(map[string]interface{}{ + "total_budget": workspaceBudget.TotalBudget, }).Error; err != nil { tx.Rollback() } @@ -350,19 +344,24 @@ func (db database) ProcessUpdateBudget(invoice NewInvoiceList, getLightningInvoi } func (db database) AddAndUpdateBudget(invoice NewInvoiceList) NewPaymentHistory { + // Start db transaction + tx := db.db.Begin() + created := invoice.Created workspace_uuid := invoice.WorkspaceUuid - paymentHistory := db.GetPaymentHistoryByCreated(created, workspace_uuid) + paymentHistory := NewPaymentHistory{} + tx.Model(&NewPaymentHistory{}).Where("created = ?", created).Where("workspace_uuid = ? ", workspace_uuid).Find(&paymentHistory) if paymentHistory.WorkspaceUuid != "" && paymentHistory.Amount != 0 { paymentHistory.Status = true db.db.Where("created = ?", created).Where("workspace_uuid = ? ", workspace_uuid).Updates(paymentHistory) // get Workspace budget and add payment to total budget - WorkspaceBudget := db.GetWorkspaceBudget(workspace_uuid) + workspaceBudget := NewBountyBudget{} + tx.Model(&NewBountyBudget{}).Where("workspace_uuid = ?", workspace_uuid).Find(&workspaceBudget) - if WorkspaceBudget.WorkspaceUuid == "" { + if workspaceBudget.WorkspaceUuid == "" { now := time.Now() workBudget := NewBountyBudget{ WorkspaceUuid: workspace_uuid, @@ -370,14 +369,26 @@ func (db database) AddAndUpdateBudget(invoice NewInvoiceList) NewPaymentHistory Created: &now, Updated: &now, } - db.CreateWorkspaceBudget(workBudget) + + if err := tx.Create(&workBudget).Error; err != nil { + tx.Rollback() + } } else { - totalBudget := WorkspaceBudget.TotalBudget - WorkspaceBudget.TotalBudget = totalBudget + paymentHistory.Amount - db.UpdateWorkspaceBudget(WorkspaceBudget) + totalBudget := workspaceBudget.TotalBudget + workspaceBudget.TotalBudget = totalBudget + paymentHistory.Amount + + if err := tx.Model(&NewBountyBudget{}).Where("workspace_uuid = ?", workspaceBudget.WorkspaceUuid).Updates(map[string]interface{}{ + "total_budget": workspaceBudget.TotalBudget, + }).Error; err != nil { + tx.Rollback() + } } + } else { + tx.Rollback() } + tx.Commit() + return paymentHistory } diff --git a/handlers/bounty.go b/handlers/bounty.go index 2c2077410..4216a61d5 100644 --- a/handlers/bounty.go +++ b/handlers/bounty.go @@ -907,8 +907,9 @@ func (h *bountyHandler) BountyBudgetWithdraw(w http.ResponseWriter, r *http.Requ if pubKeyFromAuth == "" { fmt.Println("[bounty] no pubkey from auth") - w.WriteHeader(http.StatusUnauthorized) h.m.Unlock() + + w.WriteHeader(http.StatusUnauthorized) return } @@ -917,15 +918,17 @@ func (h *bountyHandler) BountyBudgetWithdraw(w http.ResponseWriter, r *http.Requ r.Body.Close() if err != nil { - w.WriteHeader(http.StatusNotAcceptable) h.m.Unlock() + + w.WriteHeader(http.StatusNotAcceptable) return } err = json.Unmarshal(body, &request) if err != nil { - w.WriteHeader(http.StatusNotAcceptable) h.m.Unlock() + + w.WriteHeader(http.StatusNotAcceptable) return } @@ -940,11 +943,12 @@ func (h *bountyHandler) BountyBudgetWithdraw(w http.ResponseWriter, r *http.Requ // Check that last withdraw time is greater than 1 if hoursDiff < 1 { + h.m.Unlock() + w.WriteHeader(http.StatusUnauthorized) errMsg := formatPayError("Your last withdrawal is not more than an hour ago") log.Println("Your last withdrawal is not more than an hour ago", hoursDiff, lastWithdrawal.Created, request.WorkspaceUuid) json.NewEncoder(w).Encode(errMsg) - h.m.Unlock() return } } @@ -955,10 +959,11 @@ func (h *bountyHandler) BountyBudgetWithdraw(w http.ResponseWriter, r *http.Requ // or has a withdraw bounty budget role hasRole := h.userHasAccess(pubKeyFromAuth, request.WorkspaceUuid, db.WithdrawBudget) if !hasRole { + h.m.Unlock() + w.WriteHeader(http.StatusUnauthorized) errMsg := formatPayError("You don't have appropriate permissions to withdraw bounty budget") json.NewEncoder(w).Encode(errMsg) - h.m.Unlock() return } @@ -969,10 +974,11 @@ func (h *bountyHandler) BountyBudgetWithdraw(w http.ResponseWriter, r *http.Requ // is greater than the amount orgBudget := h.db.GetWorkspaceBudget(request.WorkspaceUuid) if amount > orgBudget.TotalBudget { + h.m.Unlock() + w.WriteHeader(http.StatusForbidden) errMsg := formatPayError("Workspace budget is not enough to withdraw the amount") json.NewEncoder(w).Encode(errMsg) - h.m.Unlock() return } @@ -981,10 +987,11 @@ func (h *bountyHandler) BountyBudgetWithdraw(w http.ResponseWriter, r *http.Requ sumOfDeposits := h.db.GetSumOfDeposits(request.WorkspaceUuid) if sumOfDeposits < sumOfWithdrawals+amount { + h.m.Unlock() + w.WriteHeader(http.StatusUnauthorized) errMsg := formatPayError("Your deposits is lesser than your withdral") json.NewEncoder(w).Encode(errMsg) - h.m.Unlock() return } @@ -992,19 +999,24 @@ func (h *bountyHandler) BountyBudgetWithdraw(w http.ResponseWriter, r *http.Requ if paymentSuccess.Success { // withdraw amount from workspace budget h.db.WithdrawBudget(pubKeyFromAuth, request.WorkspaceUuid, amount) + + h.m.Unlock() + w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(paymentSuccess) } else { + h.m.Unlock() + w.WriteHeader(http.StatusBadRequest) json.NewEncoder(w).Encode(paymentError) } } else { + h.m.Unlock() + w.WriteHeader(http.StatusForbidden) errMsg := formatPayError("Could not pay lightning invoice") json.NewEncoder(w).Encode(errMsg) } - - h.m.Unlock() } func formatPayError(errorMsg string) db.InvoicePayError { @@ -1281,17 +1293,13 @@ func (h *bountyHandler) GetInvoiceData(w http.ResponseWriter, r *http.Request) { } func (h *bountyHandler) PollInvoice(w http.ResponseWriter, r *http.Request) { - h.m.Lock() - ctx := r.Context() pubKeyFromAuth, _ := ctx.Value(auth.ContextKey).(string) paymentRequest := chi.URLParam(r, "paymentRequest") - var err error if pubKeyFromAuth == "" { fmt.Println("[bounty] no pubkey from auth") w.WriteHeader(http.StatusUnauthorized) - h.m.Unlock() return } @@ -1300,126 +1308,18 @@ func (h *bountyHandler) PollInvoice(w http.ResponseWriter, r *http.Request) { if invoiceErr.Error != "" { w.WriteHeader(http.StatusForbidden) json.NewEncoder(w).Encode(invoiceErr) - h.m.Unlock() return } if invoiceRes.Response.Settled { // Todo if an invoice is settled invoice := h.db.GetInvoice(paymentRequest) - invData := h.db.GetUserInvoiceData(paymentRequest) dbInvoice := h.db.GetInvoice(paymentRequest) // Make any change only if the invoice has not been settled if !dbInvoice.Status { - amount := invData.Amount if invoice.Type == "BUDGET" { h.db.AddAndUpdateBudget(invoice) - } else if invoice.Type == "KEYSEND" { - if config.IsV2Payment { - url := fmt.Sprintf("%s/pay", config.V2BotUrl) - - // Build v2 keysend payment data - bodyData := utils.BuildV2KeysendBodyData(amount, invData.UserPubkey, invData.RouteHint, "") - jsonBody := []byte(bodyData) - - req, _ := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(jsonBody)) - req.Header.Set("x-admin-token", config.V2BotToken) - req.Header.Set("Content-Type", "application/json") - log.Printf("[bounty] Making Bounty V2 Payment PollInvoice: amount: %d, pubkey: %s, route_hint: %s", amount, invData.UserPubkey, invData.RouteHint) - - res, err := h.httpClient.Do(req) - - if err != nil { - log.Printf("[bounty] Request Failed: %s", err) - h.m.Unlock() - return - } - - defer res.Body.Close() - body, err := io.ReadAll(res.Body) - if err != nil { - fmt.Println("[read body]", err) - w.WriteHeader(http.StatusNotAcceptable) - h.m.Unlock() - return - } - - // Unmarshal result - v2KeysendRes := db.V2SendOnionRes{} - err = json.Unmarshal(body, &v2KeysendRes) - - if err != nil { - fmt.Println("[Unmarshal]", err) - w.WriteHeader(http.StatusNotAcceptable) - h.m.Unlock() - return - } - - if res.StatusCode == 200 { - fmt.Println("V2 Status Code Is 200") - // if the payment has a completed status - if v2KeysendRes.Status == db.PaymentComplete { - fmt.Println("V2 Payment Is Completed") - bounty, err := h.db.GetBountyByCreated(uint(invData.Created)) - if err == nil { - now := time.Now() - bounty.Paid = true - bounty.PaidDate = &now - bounty.Completed = true - bounty.CompletionDate = &now - } - - h.db.UpdateBounty(bounty) - } - } else { - log.Printf("[bounty] V2 Keysend Payment to %s Failed, with Error: %s", invData.UserPubkey, err) - } - } else { - url := fmt.Sprintf("%s/payment", config.RelayUrl) - - bodyData := utils.BuildKeysendBodyData(amount, invData.UserPubkey, invData.RouteHint, "") - - jsonBody := []byte(bodyData) - - req, _ := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(jsonBody)) - - req.Header.Set("x-user-token", config.RelayAuthKey) - req.Header.Set("Content-Type", "application/json") - res, _ := h.httpClient.Do(req) - - defer res.Body.Close() - - body, _ := io.ReadAll(res.Body) - - if res.StatusCode == 200 { - // Unmarshal result - keysendRes := db.KeysendSuccess{} - err = json.Unmarshal(body, &keysendRes) - - if err != nil { - w.WriteHeader(http.StatusForbidden) - json.NewEncoder(w).Encode("Could not decode keysend response") - return - } - - bounty, err := h.db.GetBountyByCreated(uint(invData.Created)) - if err == nil { - now := time.Now() - bounty.Paid = true - bounty.PaidDate = &now - bounty.Completed = true - bounty.CompletionDate = &now - } - - h.db.UpdateBounty(bounty) - } else { - // Unmarshal result - keysendError := db.KeysendError{} - err = json.Unmarshal(body, &keysendError) - log.Printf("[bounty] Keysend Payment to %s Failed, with Error: %s", invData.UserPubkey, err) - } - } } // Update the invoice status h.db.UpdateInvoice(paymentRequest) @@ -1435,8 +1335,6 @@ func (h *bountyHandler) PollInvoice(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(invoiceRes) - - h.m.Unlock() } func GetFilterCount(w http.ResponseWriter, r *http.Request) { diff --git a/handlers/workspaces.go b/handlers/workspaces.go index b132672f2..d1f487f0c 100644 --- a/handlers/workspaces.go +++ b/handlers/workspaces.go @@ -674,9 +674,18 @@ func (oh *workspaceHandler) PollBudgetInvoices(w http.ResponseWriter, r *http.Re workInvoices := oh.db.GetWorkspaceInvoices(uuid) for _, inv := range workInvoices { - if !inv.Status && inv.Type == "BUDGET" { - oh.db.ProcessUpdateBudget(inv, oh.getLightningInvoice) + invoiceRes, invoiceErr := oh.getLightningInvoice(inv.PaymentRequest) + if invoiceErr.Error != "" { + w.WriteHeader(http.StatusForbidden) + json.NewEncoder(w).Encode(invoiceErr) + return + } + + if invoiceRes.Response.Settled { + if !inv.Status && inv.Type == "BUDGET" { + oh.db.ProcessUpdateBudget(inv) + } } else { // Cheeck if time has expired isInvoiceExpired := utils.GetInvoiceExpired(inv.PaymentRequest) @@ -720,7 +729,7 @@ func (oh *workspaceHandler) PollUserWorkspacesBudget(w http.ResponseWriter, r *h if invoiceRes.Response.Settled { if !inv.Status && inv.Type == "BUDGET" { - oh.db.ProcessUpdateBudget(inv, oh.getLightningInvoice) + oh.db.ProcessUpdateBudget(inv) } } else { // Cheeck if time has expired diff --git a/mocks/Database.go b/mocks/Database.go index 4e0bf60f8..4c40aeb6b 100644 --- a/mocks/Database.go +++ b/mocks/Database.go @@ -6823,17 +6823,17 @@ func (_c *Database_ProcessDeleteWorkspace_Call) RunAndReturn(run func(string) er return _c } -// ProcessUpdateBudget provides a mock function with given fields: invoice, getLightningInvoice -func (_m *Database) ProcessUpdateBudget(invoice db.NewInvoiceList, getLightningInvoice func(string) (db.InvoiceResult, db.InvoiceError)) error { - ret := _m.Called(invoice, getLightningInvoice) +// ProcessUpdateBudget provides a mock function with given fields: invoice +func (_m *Database) ProcessUpdateBudget(invoice db.NewInvoiceList) error { + ret := _m.Called(invoice) if len(ret) == 0 { panic("no return value specified for ProcessUpdateBudget") } var r0 error - if rf, ok := ret.Get(0).(func(db.NewInvoiceList, func(string) (db.InvoiceResult, db.InvoiceError)) error); ok { - r0 = rf(invoice, getLightningInvoice) + if rf, ok := ret.Get(0).(func(db.NewInvoiceList) error); ok { + r0 = rf(invoice) } else { r0 = ret.Error(0) } @@ -6848,14 +6848,13 @@ type Database_ProcessUpdateBudget_Call struct { // ProcessUpdateBudget is a helper method to define mock.On call // - invoice db.NewInvoiceList -// - getLightningInvoice func(string)(db.InvoiceResult , db.InvoiceError) -func (_e *Database_Expecter) ProcessUpdateBudget(invoice interface{}, getLightningInvoice interface{}) *Database_ProcessUpdateBudget_Call { - return &Database_ProcessUpdateBudget_Call{Call: _e.mock.On("ProcessUpdateBudget", invoice, getLightningInvoice)} +func (_e *Database_Expecter) ProcessUpdateBudget(invoice interface{}) *Database_ProcessUpdateBudget_Call { + return &Database_ProcessUpdateBudget_Call{Call: _e.mock.On("ProcessUpdateBudget", invoice)} } -func (_c *Database_ProcessUpdateBudget_Call) Run(run func(invoice db.NewInvoiceList, getLightningInvoice func(string) (db.InvoiceResult, db.InvoiceError))) *Database_ProcessUpdateBudget_Call { +func (_c *Database_ProcessUpdateBudget_Call) Run(run func(invoice db.NewInvoiceList)) *Database_ProcessUpdateBudget_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(db.NewInvoiceList), args[1].(func(string) (db.InvoiceResult, db.InvoiceError))) + run(args[0].(db.NewInvoiceList)) }) return _c } @@ -6865,7 +6864,7 @@ func (_c *Database_ProcessUpdateBudget_Call) Return(_a0 error) *Database_Process return _c } -func (_c *Database_ProcessUpdateBudget_Call) RunAndReturn(run func(db.NewInvoiceList, func(string) (db.InvoiceResult, db.InvoiceError)) error) *Database_ProcessUpdateBudget_Call { +func (_c *Database_ProcessUpdateBudget_Call) RunAndReturn(run func(db.NewInvoiceList) error) *Database_ProcessUpdateBudget_Call { _c.Call.Return(run) return _c }