-
Notifications
You must be signed in to change notification settings - Fork 1
feat(relay): dual-write transactions to sos.audius.co #736
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,7 @@ import ( | |
| "api.audius.co/trashid" | ||
| "connectrpc.com/connect" | ||
| v1 "github.com/OpenAudio/go-openaudio/pkg/api/core/v1" | ||
| "github.com/OpenAudio/go-openaudio/pkg/sdk" | ||
| cconfig "github.com/OpenAudio/go-openaudio/pkg/core/config" | ||
| "github.com/OpenAudio/go-openaudio/pkg/core/server" | ||
| eth_gen "github.com/OpenAudio/go-openaudio/pkg/eth/contracts/gen" | ||
|
|
@@ -259,37 +260,43 @@ func (app *ApiServer) relay(c *fiber.Ctx) error { | |
| }) | ||
| } | ||
|
|
||
| const sosEndpoint = "https://sos.audius.co" | ||
|
|
||
| func (app *ApiServer) handleRelay(ctx context.Context, logger *zap.Logger, decodedTx *v1.ManageEntityLegacy) (*v1.Transaction, error) { | ||
| allClients := app.openAudioPool.GetAll() | ||
| if len(allClients) == 0 { | ||
| logger.Error("no OpenAudio clients configured") | ||
| return nil, fmt.Errorf("no OpenAudio clients configured") | ||
| } | ||
|
|
||
| var lastErr error | ||
| for i, clientInfo := range allClients { | ||
| endpointLogger := logger.With(zap.String("openaudio_endpoint", clientInfo.Endpoint), zap.Int("attempt", i+1)) | ||
| res, err := clientInfo.Client.Core.SendTransaction(ctx, connect.NewRequest(&v1.SendTransactionRequest{ | ||
| Transaction: &v1.SignedTransaction{ | ||
| Transaction: &v1.SignedTransaction_ManageEntity{ | ||
| ManageEntity: decodedTx, | ||
| }, | ||
| req := &v1.SendTransactionRequest{ | ||
| Transaction: &v1.SignedTransaction{ | ||
| Transaction: &v1.SignedTransaction_ManageEntity{ | ||
| ManageEntity: decodedTx, | ||
| }, | ||
| })) | ||
|
|
||
| if err != nil { | ||
| lastErr = err | ||
| endpointLogger.Warn("transaction failed, trying next", zap.Error(err)) | ||
| continue | ||
| }, | ||
| } | ||
|
|
||
| // mainnet | ||
| go func() { | ||
| allClients := app.openAudioPool.GetAll() | ||
| for i, clientInfo := range allClients { | ||
| endpointLogger := logger.With(zap.String("openaudio_endpoint", clientInfo.Endpoint), zap.Int("attempt", i+1)) | ||
| res, err := clientInfo.Client.Core.SendTransaction(context.Background(), connect.NewRequest(req)) | ||
| if err != nil { | ||
| endpointLogger.Warn("transaction failed, trying next", zap.Error(err)) | ||
| continue | ||
| } | ||
| endpointLogger.Info("transaction confirmed", zap.String("hash", res.Msg.Transaction.GetHash())) | ||
| return | ||
| } | ||
| logger.Error("all mainnet endpoints failed") | ||
| }() | ||
|
|
||
| msg := res.Msg.Transaction | ||
| endpointLogger.Info("transaction confirmed", zap.String("hash", msg.GetHash())) | ||
| return msg, nil | ||
| // sos | ||
| sosClient := sdk.NewOpenAudioSDK(sosEndpoint) | ||
| sosLogger := logger.With(zap.String("openaudio_endpoint", sosEndpoint)) | ||
| res, err := sosClient.Core.SendTransaction(ctx, connect.NewRequest(req)) | ||
| if err != nil { | ||
| sosLogger.Warn("sos dual-write failed", zap.Error(err)) | ||
| return nil, err | ||
| } | ||
|
Comment on lines
+293
to
297
|
||
|
|
||
| logger.Error("all OpenAudio endpoints failed", zap.Error(lastErr)) | ||
| return nil, fmt.Errorf("all endpoints failed, last error: %w", lastErr) | ||
| sosLogger.Info("sos dual-write confirmed", zap.String("hash", res.Msg.Transaction.GetHash())) | ||
| return res.Msg.Transaction, nil | ||
| } | ||
|
|
||
| func transactionToReceipt(tx *v1.Transaction, wallet string) map[string]interface{} { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The mainnet send is launched as a goroutine using
context.Background()with no timeout. Under load, this can create unbounded concurrent goroutines and potentially hang indefinitely if an endpoint stalls (since it won't be canceled when the request ctx is canceled). Consider using a bounded context with timeout (e.g.,context.WithTimeout) and/or a background worker/queue to control concurrency.