From 749bae2ac4cdb6c9d1f1bea07e57d387facaa3b9 Mon Sep 17 00:00:00 2001 From: arkadiuszos4chain Date: Fri, 10 Nov 2023 14:30:23 +0100 Subject: [PATCH] fix --- paymail_service_provider.go | 6 +++--- record_tx.go | 15 +++++++++++--- record_tx_strategy_outgoing_tx.go | 33 +++++++++++++++++++------------ 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/paymail_service_provider.go b/paymail_service_provider.go index 3ce95cc5..20fd729c 100644 --- a/paymail_service_provider.go +++ b/paymail_service_provider.go @@ -156,15 +156,15 @@ func (p *PaymailDefaultServiceProvider) RecordTransaction(ctx context.Context, metadata[ReferenceIDField] = p2pTx.Reference // Record the transaction - rts, err := getRecordTxStrategy(ctx, p.client, "", p2pTx.Hex, "") + rts, err := getIncomingTxRecordStrategy(ctx, p.client, p2pTx.Hex) if err != nil { return nil, err } - rts.(recordIncomingTxStrategy).ForceBroadcast(true) + rts.ForceBroadcast(true) if p2pTx.Beef != "" { - rts.(recordIncomingTxStrategy).FailOnBroadcastError(true) + rts.FailOnBroadcastError(true) } transaction, err := recordTransaction(ctx, p.client, rts, WithMetadatas(metadata)) diff --git a/record_tx.go b/record_tx.go index 87914919..9cb32960 100644 --- a/record_tx.go +++ b/record_tx.go @@ -13,6 +13,7 @@ type recordTxStrategy interface { } type recordIncomingTxStrategy interface { + recordTxStrategy ForceBroadcast(force bool) FailOnBroadcastError(forceFail bool) } @@ -53,13 +54,13 @@ func getOutgoingTxRecordStrategy(xPubKey, txHex, draftID string) recordTxStrateg } } -func getIncomingTxRecordStrategy(ctx context.Context, c ClientInterface, txHex string) (recordTxStrategy, error) { +func getIncomingTxRecordStrategy(ctx context.Context, c ClientInterface, txHex string) (recordIncomingTxStrategy, error) { tx, err := getTransactionByHex(ctx, txHex, c.DefaultModelOptions()...) if err != nil { return nil, err } - var rts recordTxStrategy + var rts recordIncomingTxStrategy if tx != nil { rts = &internalIncomingTx{ @@ -84,15 +85,23 @@ func waitForRecordTxWriteLock(ctx context.Context, c ClientInterface, key string // Create the lock and set the release for after the function completes // Waits for the moment when the transaction is unlocked and creates a new lock // Relevant for bux to bux transactions, as we have 1 tx but need to record 2 txs - outgoing and incoming + + c.Logger().Info(ctx, fmt.Sprintf("record: try add write lock %s", fmt.Sprintf(lockKeyRecordTx, key))) + for { + unlock, err = newWriteLock( ctx, fmt.Sprintf(lockKeyRecordTx, key), c.Cachestore(), ) if err == nil { + c.Logger().Info(ctx, fmt.Sprintf("record: added write lock %s", fmt.Sprintf(lockKeyRecordTx, key))) break } time.Sleep(time.Second * 1) } - return unlock + return func() { + c.Logger().Info(ctx, "unlock") + unlock() + } } diff --git a/record_tx_strategy_outgoing_tx.go b/record_tx_strategy_outgoing_tx.go index b33efe3e..8856db5b 100644 --- a/record_tx_strategy_outgoing_tx.go +++ b/record_tx_strategy_outgoing_tx.go @@ -15,31 +15,38 @@ type outgoingTx struct { XPubKey string } -func (tx *outgoingTx) Execute(ctx context.Context, c ClientInterface, opts []ModelOps) (*Transaction, error) { +func (strategy *outgoingTx) Execute(ctx context.Context, c ClientInterface, opts []ModelOps) (*Transaction, error) { logger := c.Logger() + logger.Info(ctx, fmt.Sprintf("OutgoingTx.Execute(): start, TxID: %s", strategy.TxID())) - // process - transaction, err := _createOutgoingTxToRecord(ctx, tx, c, opts) - - logger.Info(ctx, fmt.Sprintf("OutgoingTx.Execute(): start, TxID: %s", transaction.ID)) - + // create + transaction, err := _createOutgoingTxToRecord(ctx, strategy, c, opts) if err != nil { return nil, fmt.Errorf("OutgoingTx.Execute(): creation of outgoing tx failed. Reason: %w", err) } + // record + if err = transaction.Save(ctx); err != nil { + return nil, fmt.Errorf("OutgoingTx.Execute(): saving of Transaction failed. Reason: %w", err) + } + + // process if transaction.syncTransaction.P2PStatus == SyncStatusReady { if err = _outgoingNotifyP2p(ctx, logger, transaction); err != nil { - return nil, err // reject transaction if P2P notification failed + // reject transaction if P2P notification failed + logger.Error(ctx, fmt.Sprintf("OutgoingTx.Execute(): transaction rejected by P2P provider. Reason: %s", err)) + logger.Info(ctx, fmt.Sprintf("OutgoingTx.Execute(): try to revert transaction.")) + + if revertErr := c.RevertTransaction(ctx, transaction.ID); revertErr != nil { + logger.Error(ctx, fmt.Sprintf("OutgoingTx.Execute(): FATAL! Reverting transaction after failed P2P notification failed. Reason: %s", err)) + } + + return nil, err } } if transaction.syncTransaction.BroadcastStatus == SyncStatusReady { - _outgoingBroadcast(ctx, logger, transaction) // ignore error, transaction will be broadcasted by cron task - } - - // record - if err = transaction.Save(ctx); err != nil { - return nil, fmt.Errorf("OutgoingTx.Execute(): saving of Transaction failed. Reason: %w", err) + _outgoingBroadcast(ctx, logger, transaction) // ignore error } logger.Info(ctx, fmt.Sprintf("OutgoingTx.Execute(): complete, TxID: %s", transaction.ID))