processLineage handles fund lineage tracking for a transaction. It processes both credit (incoming funds with provider tracking) and debit (fund allocation from shadow balances). Parameters: - ctx context.Context: The context for the operation. - txn *model.Transaction: The transaction being proces
(ctx context.Context, txn *model.Transaction, sourceBalance, destinationBalance *model.Balance)
| 124 | // - sourceBalance *model.Balance: The source balance for the transaction. |
| 125 | // - destinationBalance *model.Balance: The destination balance for the transaction. |
| 126 | func (l *LedgerForge) processLineage(ctx context.Context, txn *model.Transaction, sourceBalance, destinationBalance *model.Balance) { |
| 127 | ctx, span := tracer.Start(ctx, "ProcessLineage") |
| 128 | defer span.End() |
| 129 | |
| 130 | provider := l.getLineageProvider(txn) |
| 131 | |
| 132 | // Validate provider against source balance |
| 133 | // If source tracks lineage but doesn't have the provider, ignore it |
| 134 | validatedProvider, err := l.validateLineageProvider(ctx, provider, sourceBalance) |
| 135 | if err != nil { |
| 136 | span.RecordError(err) |
| 137 | logrus.Errorf("lineage provider validation failed: %v", err) |
| 138 | notification.NotifyError(err) |
| 139 | validatedProvider = "" |
| 140 | } |
| 141 | |
| 142 | if provider != "" && validatedProvider == "" && sourceBalance != nil { |
| 143 | span.AddEvent("Provider validation failed", trace.WithAttributes( |
| 144 | attribute.String("requested_provider", provider), |
| 145 | attribute.String("source_balance_id", sourceBalance.BalanceID), |
| 146 | )) |
| 147 | } |
| 148 | |
| 149 | // Credit processing requires a validated provider to know the source of funds |
| 150 | if validatedProvider != "" && destinationBalance != nil && destinationBalance.TrackFundLineage { |
| 151 | if err := l.processLineageCredit(ctx, txn, destinationBalance, validatedProvider); err != nil { |
| 152 | span.RecordError(err) |
| 153 | logrus.Errorf("lineage credit processing failed: %v", err) |
| 154 | notification.NotifyError(err) |
| 155 | } |
| 156 | } |
| 157 | |
| 158 | // Debit processing doesn't require a provider - it allocates from existing shadow balances |
| 159 | if sourceBalance != nil && sourceBalance.TrackFundLineage { |
| 160 | if err := l.processLineageDebit(ctx, txn, sourceBalance, destinationBalance); err != nil { |
| 161 | span.RecordError(err) |
| 162 | logrus.Errorf("lineage debit processing failed: %v", err) |
| 163 | notification.NotifyError(err) |
| 164 | } |
| 165 | } |
| 166 | |
| 167 | span.AddEvent("Lineage processing completed") |
| 168 | } |
| 169 | |
| 170 | // getLineageProvider extracts the fund provider from the transaction metadata. |
| 171 | // |
no test coverage detected