From 19df5480f0bee0baf06cbbc4725021782f62805f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Lewandowski?= Date: Mon, 27 Nov 2023 10:08:38 +0100 Subject: [PATCH] chore(BUX-322): refactor saving inputs methods --- beef_tx.go | 51 -------------------- paymail_service_provider.go | 92 +++++++++++++++++++++++++++++++++---- 2 files changed, 84 insertions(+), 59 deletions(-) diff --git a/beef_tx.go b/beef_tx.go index 0a185a74..cccb928e 100644 --- a/beef_tx.go +++ b/beef_tx.go @@ -102,54 +102,3 @@ func getParentTransactionsForInput(ctx context.Context, client ClientInterface, return nil, fmt.Errorf("transaction is not mined yet (tx.ID: %s)", inputTx.ID) // TODO: handle it in next iterration } - -func saveBeefTransactionInput(ctx context.Context, c ClientInterface, input *bt.Tx) error { - inputTx, err := c.GetTransactionByID(ctx, input.TxID()) - if err != nil && err != ErrMissingTransaction { - return fmt.Errorf("error in saveBeefTransactionInput during getting transaction: %s", err.Error()) - } - - if inputTx != nil { - if inputTx.BUMP.BlockHeight > 0 { - fmt.Println("input exist in db and has BUMP") - return nil - } - fmt.Println("input exist in db and has no BUMP") - - // Sync tx if BUMP is empty - err = _syncTxDataFromChain(ctx, inputTx.syncTransaction, inputTx) - if err != nil { - return fmt.Errorf("error in saveBeefTransactionInput during syncing transaction: %s", err.Error()) - } - return nil - } - - fmt.Println("input not exist in db") - - newOpts := c.DefaultModelOptions(New()) - inputTx = newTransaction(input.String(), newOpts...) - - err = inputTx.Save(ctx) - if err != nil { - return fmt.Errorf("error in saveBeefTransactionInput during saving tx: %s", err.Error()) - } - - sync := newSyncTransaction( - inputTx.GetID(), - inputTx.Client().DefaultSyncConfig(), - inputTx.GetOptions(true)..., - ) - sync.BroadcastStatus = SyncStatusSkipped - sync.P2PStatus = SyncStatusSkipped - sync.SyncStatus = SyncStatusReady - - if err = sync.Save(ctx); err != nil { - return fmt.Errorf("error in saveBeefTransactionInput during saving sync tx: %s", err.Error()) - } - - err = _syncTxDataFromChain(ctx, sync, inputTx) - if err != nil { - return fmt.Errorf("error in saveBeefTransactionInput during syncing transaction: %s", err.Error()) - } - return nil -} diff --git a/paymail_service_provider.go b/paymail_service_provider.go index 9cd19e1b..4e1c95cc 100644 --- a/paymail_service_provider.go +++ b/paymail_service_provider.go @@ -5,6 +5,7 @@ import ( "database/sql" "encoding/hex" "fmt" + "github.com/libsv/go-bt/v2" "reflect" "time" @@ -181,14 +182,7 @@ func (p *PaymailDefaultServiceProvider) RecordTransaction(ctx context.Context, }, nil } - if reflect.TypeOf(rts) == reflect.TypeOf(&externalIncomingTx{}) { - for _, input := range p2pTx.DecodedBeef.InputsTxData { - err = saveBeefTransactionInput(ctx, p.client, input.Transaction) - if err != nil { - p.client.Logger().Error(ctx, "error in saveBeefTransactionInput", err) - } - } - } + saveBEEFTxInputs(ctx, p.client, p2pTx, rts) // Return the response from the p2p request return &paymail.P2PTransactionPayload{ @@ -323,3 +317,85 @@ func deriveKey(rawXPubKey string, num uint32) (k *derivedPubKey, err error) { k.pubKey = hex.EncodeToString(k.ecPubKey.SerialiseCompressed()) return } + +func saveBEEFTxInputs(ctx context.Context, c ClientInterface, p2pTx *paymail.P2PTransaction, rts recordIncomingTxStrategy) { + if reflect.TypeOf(rts) != reflect.TypeOf(&externalIncomingTx{}) { + return + } + + inputsToAdd, err := getInputsWhichAreNotInDb(ctx, c, p2pTx) + if err != nil { + c.Logger().Error(ctx, "error in saveBEEFTxInputs", err) + } + + for _, input := range inputsToAdd { + err := saveBeefTransactionInput(ctx, c, input) + if err != nil { + c.Logger().Error(ctx, "error in saveBEEFTxInputs", err) + } + } + +} + +func getInputsWhichAreNotInDb(ctx context.Context, c ClientInterface, p2pTx *paymail.P2PTransaction) ([]*bt.Tx, error) { + var txIDs []string + for _, tx := range p2pTx.DecodedBeef.Transactions { + txIDs = append(txIDs, tx.GetTxID()) + } + dbTxs, err := c.GetTransactionsByIDs(ctx, txIDs) + if err != nil { + return nil, fmt.Errorf("error during getting txs from db: %s", err) + } + + txs := make([]*bt.Tx, 0) + + if len(dbTxs) == len(txIDs) { + return txs, nil + } + + for _, input := range p2pTx.DecodedBeef.Transactions { + found := false + for _, dbTx := range dbTxs { + if dbTx.GetID() == input.GetTxID() { + found = true + break + } + } + if !found { + txs = append(txs, input.Transaction) + } + } + + return txs, nil +} + +func saveBeefTransactionInput(ctx context.Context, c ClientInterface, input *bt.Tx) error { + inputTx, err := c.GetTransactionByID(ctx, input.TxID()) + if err != nil && err != ErrMissingTransaction { + return fmt.Errorf("error in saveBeefTransactionInput during getting transaction: %s", err.Error()) + } + + if inputTx != nil { + return nil + } + + newOpts := c.DefaultModelOptions(New()) + inputTx = newTransaction(input.String(), newOpts...) + + sync := newSyncTransaction( + inputTx.GetID(), + inputTx.Client().DefaultSyncConfig(), + inputTx.GetOptions(true)..., + ) + sync.BroadcastStatus = SyncStatusSkipped + sync.P2PStatus = SyncStatusSkipped + sync.SyncStatus = SyncStatusReady + + inputTx.syncTransaction = sync + + err = inputTx.Save(ctx) + if err != nil { + return fmt.Errorf("error in saveBeefTransactionInput during saving tx: %s", err.Error()) + } + return nil +}