From fb41eeffdd0124cb9039fb10d8eac5dd7a0c8cd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20B=C3=B6ckli?= <42514703+boecklim@users.noreply.github.com> Date: Wed, 20 Nov 2024 14:54:48 +0100 Subject: [PATCH] refactor: Reduce duplicated code in metamorph client (#653) --- pkg/metamorph/client.go | 161 ++++++++++++++++------------------------ 1 file changed, 62 insertions(+), 99 deletions(-) diff --git a/pkg/metamorph/client.go b/pkg/metamorph/client.go index d41f931e6..5c58dd7f6 100644 --- a/pkg/metamorph/client.go +++ b/pkg/metamorph/client.go @@ -244,23 +244,10 @@ func (m *Metamorph) SubmitTransaction(ctx context.Context, tx *sdkTx.Transaction } var response *metamorph_api.TransactionStatus + var txStatus *TransactionStatus + var getStatusErr error var err error - response, err = m.client.PutTransaction(ctx, request) - if err == nil { - return &TransactionStatus{ - TxID: response.GetTxid(), - Status: response.GetStatus().String(), - ExtraInfo: response.GetRejectReason(), - CompetingTxs: response.GetCompetingTxs(), - BlockHash: response.GetBlockHash(), - BlockHeight: response.GetBlockHeight(), - MerklePath: response.GetMerklePath(), - Timestamp: m.now().Unix(), - }, nil - } - m.logger.ErrorContext(ctx, "Failed to put transaction", slog.String("err", err.Error())) - // in case of error try PutTransaction until timeout expires maxTimeout := max(time.Duration(request.MaxTimeout)*time.Second, m.maxTimeout) @@ -269,44 +256,42 @@ func (m *Metamorph) SubmitTransaction(ctx context.Context, tx *sdkTx.Transaction timeoutTimer := time.NewTimer(maxTimeout) -retryLoop: for { - select { - case <-timeoutTimer.C: - return nil, err - - case <-retryTicker.C: - response, err = m.client.PutTransaction(ctx, request) - if err == nil { - break retryLoop + response, err = m.client.PutTransaction(ctx, request) + if err == nil { + txStatus = &TransactionStatus{ + TxID: response.GetTxid(), + Status: response.GetStatus().String(), + ExtraInfo: response.GetRejectReason(), + CompetingTxs: response.GetCompetingTxs(), + BlockHash: response.GetBlockHash(), + BlockHeight: response.GetBlockHeight(), + MerklePath: response.GetMerklePath(), + Timestamp: m.now().Unix(), } + break + } - m.logger.ErrorContext(ctx, "Failed to put transaction", slog.String("err", err.Error())) - - if status.Code(err) != codes.Code(code.Code_DEADLINE_EXCEEDED) { - continue - } + m.logger.ErrorContext(ctx, "Failed to put transaction", slog.String("err", err.Error())) + if status.Code(err) == codes.Code(code.Code_DEADLINE_EXCEEDED) { // if error is deadline exceeded, check tx status to avoid false negatives - txStatus, getStatusErr := m.GetTransactionStatus(ctx, tx.TxID()) - if getStatusErr != nil { - continue + txStatus, getStatusErr = m.GetTransactionStatus(ctx, tx.TxID()) + if getStatusErr == nil { + break } + } + + select { + case <-timeoutTimer.C: + return nil, err - return txStatus, nil + case <-retryTicker.C: + continue } } - return &TransactionStatus{ - TxID: response.GetTxid(), - Status: response.GetStatus().String(), - ExtraInfo: response.GetRejectReason(), - CompetingTxs: response.GetCompetingTxs(), - BlockHash: response.GetBlockHash(), - BlockHeight: response.GetBlockHeight(), - MerklePath: response.GetMerklePath(), - Timestamp: m.now().Unix(), - }, nil + return txStatus, nil } // SubmitTransactions submits transactions to the bitcoin network and returns the transaction in raw format. @@ -342,29 +327,9 @@ func (m *Metamorph) SubmitTransactions(ctx context.Context, txs sdkTx.Transactio return ret, nil } var responses *metamorph_api.TransactionStatuses + var txStatuses []*TransactionStatus var err error - responses, err = m.client.PutTransactions(ctx, in) - if err == nil { - // parse response and return to user - ret := make([]*TransactionStatus, 0) - for _, response := range responses.GetStatuses() { - ret = append(ret, &TransactionStatus{ - TxID: response.GetTxid(), - MerklePath: response.GetMerklePath(), - Status: response.GetStatus().String(), - ExtraInfo: response.GetRejectReason(), - CompetingTxs: response.GetCompetingTxs(), - BlockHash: response.GetBlockHash(), - BlockHeight: response.GetBlockHeight(), - Timestamp: m.now().Unix(), - }) - } - - return ret, nil - } - m.logger.ErrorContext(ctx, "Failed to put transactions", slog.String("err", err.Error())) - // in case of error try PutTransaction until timeout expires maxTimeout := max(time.Duration(in.Transactions[0].MaxTimeout)*time.Second, m.maxTimeout) @@ -373,57 +338,55 @@ func (m *Metamorph) SubmitTransactions(ctx context.Context, txs sdkTx.Transactio timeoutTimer := time.NewTimer(maxTimeout) -retryLoop: for { - select { - case <-timeoutTimer.C: - return nil, err - - case <-retryTicker.C: - responses, err = m.client.PutTransactions(ctx, in) - if err == nil { - break retryLoop - } - - m.logger.ErrorContext(ctx, "Failed to put transactions", slog.String("err", err.Error())) - - if status.Code(err) != codes.Code(code.Code_DEADLINE_EXCEEDED) { - continue + responses, err = m.client.PutTransactions(ctx, in) + if err == nil { + for _, response := range responses.GetStatuses() { + txStatuses = append(txStatuses, &TransactionStatus{ + TxID: response.GetTxid(), + MerklePath: response.GetMerklePath(), + Status: response.GetStatus().String(), + ExtraInfo: response.GetRejectReason(), + CompetingTxs: response.GetCompetingTxs(), + BlockHash: response.GetBlockHash(), + BlockHeight: response.GetBlockHeight(), + Timestamp: m.now().Unix(), + }) } + break + } - // if error is deadline exceeded, check tx status to avoid false negatives + m.logger.ErrorContext(ctx, "Failed to put transactions", slog.String("err", err.Error())) - // Todo: Create and use here client.GetTransactionStatuses rpc function - txStatuses := make([]*TransactionStatus, 0) + // if error is deadline exceeded, check tx status to avoid false negatives + if status.Code(err) == codes.Code(code.Code_DEADLINE_EXCEEDED) { + completedErrorFree := true for _, tx := range txs { + // Todo: Create and use here client.GetTransactionStatuses rpc function txStatus, getStatusErr := m.GetTransactionStatus(ctx, tx.TxID()) if getStatusErr != nil { - continue retryLoop + completedErrorFree = false + break } txStatuses = append(txStatuses, txStatus) } - return txStatuses, nil + if completedErrorFree { + break + } } - } - // parse response and return to user - ret := make([]*TransactionStatus, 0) - for _, response := range responses.GetStatuses() { - ret = append(ret, &TransactionStatus{ - TxID: response.GetTxid(), - MerklePath: response.GetMerklePath(), - Status: response.GetStatus().String(), - ExtraInfo: response.GetRejectReason(), - CompetingTxs: response.GetCompetingTxs(), - BlockHash: response.GetBlockHash(), - BlockHeight: response.GetBlockHeight(), - Timestamp: m.now().Unix(), - }) + select { + case <-timeoutTimer.C: + return nil, err + + case <-retryTicker.C: + continue + } } - return ret, nil + return txStatuses, nil } func (m *Metamorph) ClearData(ctx context.Context, retentionDays int32) (int64, error) {