From 9332600343a74121b8eea6b4d1b6989cc6bf980d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Lewandowski?= Date: Fri, 24 Nov 2023 09:34:45 +0100 Subject: [PATCH] feat(BUX-322): save inputs from BEEF tx --- beef_tx.go | 69 +++++++++++++++++++++++++++++++++++++ paymail_service_provider.go | 17 +++++++++ 2 files changed, 86 insertions(+) diff --git a/beef_tx.go b/beef_tx.go index b8b60e69..0a185a74 100644 --- a/beef_tx.go +++ b/beef_tx.go @@ -84,3 +84,72 @@ func hydrateTransaction(ctx context.Context, tx *Transaction) error { return nil } + +func getParentTransactionsForInput(ctx context.Context, client ClientInterface, input *TransactionInput) ([]*bt.Tx, error) { + inputTx, err := client.GetTransactionByID(ctx, input.UtxoPointer.TransactionID) + if err != nil { + return nil, err + } + + if inputTx.MerkleProof.TxOrID != "" { + inputBtTx, err := bt.NewTxFromString(inputTx.Hex) + if err != nil { + return nil, fmt.Errorf("cannot convert to bt.Tx from hex (tx.ID: %s). Reason: %w", inputTx.ID, err) + } + + return []*bt.Tx{inputBtTx}, nil + } + + 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 1d50c7be..9cd19e1b 100644 --- a/paymail_service_provider.go +++ b/paymail_service_provider.go @@ -5,6 +5,7 @@ import ( "database/sql" "encoding/hex" "fmt" + "reflect" "time" "github.com/bitcoin-sv/go-paymail" @@ -173,6 +174,22 @@ func (p *PaymailDefaultServiceProvider) RecordTransaction(ctx context.Context, return nil, err } + if p2pTx.DecodedBeef == nil { + return &paymail.P2PTransactionPayload{ + Note: p2pTx.MetaData.Note, + TxID: transaction.ID, + }, 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) + } + } + } + // Return the response from the p2p request return &paymail.P2PTransactionPayload{ Note: p2pTx.MetaData.Note,