From 410bebb2ac8e4533e921ac503c4189d0a12a40c2 Mon Sep 17 00:00:00 2001 From: gagliardetto Date: Tue, 20 Feb 2024 16:30:59 +0100 Subject: [PATCH 1/4] Fix error response --- multiepoch-getTransaction.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/multiepoch-getTransaction.go b/multiepoch-getTransaction.go index 0fc1ad8e..dff50c66 100644 --- a/multiepoch-getTransaction.go +++ b/multiepoch-getTransaction.go @@ -135,7 +135,7 @@ func (multi *MultiEpoch) handleGetTransaction(ctx context.Context, conn *request if errors.Is(err, ErrNotFound) { return &jsonrpc2.Error{ Code: CodeNotFound, - Message: fmt.Sprintf("Epoch %d is not available from this RPC", epochNumber), + Message: "Signature not found", }, fmt.Errorf("failed to find epoch number from signature %s: %v", sig, err) } return &jsonrpc2.Error{ From 69edfd40831a35ab0821c729132fe1195b97aa2c Mon Sep 17 00:00:00 2001 From: gagliardetto Date: Tue, 20 Feb 2024 16:36:49 +0100 Subject: [PATCH 2/4] Add comments --- multiepoch-getTransaction.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/multiepoch-getTransaction.go b/multiepoch-getTransaction.go index dff50c66..c8f881af 100644 --- a/multiepoch-getTransaction.go +++ b/multiepoch-getTransaction.go @@ -133,9 +133,10 @@ func (multi *MultiEpoch) handleGetTransaction(ctx context.Context, conn *request epochNumber, err := multi.findEpochNumberFromSignature(ctx, sig) if err != nil { if errors.Is(err, ErrNotFound) { + // TODO: solana just returns null here in case of transaction not found: {"jsonrpc":"2.0","result":null,"id":1} return &jsonrpc2.Error{ Code: CodeNotFound, - Message: "Signature not found", + Message: "Transaction not found", }, fmt.Errorf("failed to find epoch number from signature %s: %v", sig, err) } return &jsonrpc2.Error{ @@ -156,7 +157,7 @@ func (multi *MultiEpoch) handleGetTransaction(ctx context.Context, conn *request transactionNode, transactionCid, err := epochHandler.GetTransaction(WithSubrapghPrefetch(ctx, true), sig) if err != nil { if errors.Is(err, compactindexsized.ErrNotFound) { - // NOTE: solana just returns null here in case of transaction not found + // NOTE: solana just returns null here in case of transaction not found: {"jsonrpc":"2.0","result":null,"id":1} return &jsonrpc2.Error{ Code: CodeNotFound, Message: "Transaction not found", From 71a391476dfdacab7eb866cdfcfcd351d39d7fb6 Mon Sep 17 00:00:00 2001 From: gagliardetto Date: Tue, 20 Feb 2024 16:39:28 +0100 Subject: [PATCH 3/4] Fix error formatting --- multiepoch-getTransaction.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/multiepoch-getTransaction.go b/multiepoch-getTransaction.go index c8f881af..ad194acb 100644 --- a/multiepoch-getTransaction.go +++ b/multiepoch-getTransaction.go @@ -56,7 +56,7 @@ func (multi *MultiEpoch) findEpochNumberFromSignature(ctx context.Context, sig s continue } if has, err := bucket.Has(sig); err != nil { - return 0, fmt.Errorf("failed to check if signature exists in bucket: %v", err) + return 0, fmt.Errorf("failed to check if signature exists in bucket: %w", err) } else if has { found = append(found, epochNumber) } @@ -81,7 +81,7 @@ func (multi *MultiEpoch) findEpochNumberFromSignature(ctx context.Context, sig s wg.Spawn(func() (any, error) { epoch, err := multi.GetEpoch(epochNumber) if err != nil { - return nil, fmt.Errorf("failed to get epoch %d: %v", epochNumber, err) + return nil, fmt.Errorf("failed to get epoch %d: %w", epochNumber, err) } if _, err := epoch.FindCidFromSignature(ctx, sig); err == nil { return epochNumber, nil @@ -118,7 +118,7 @@ func (multi *MultiEpoch) handleGetTransaction(ctx context.Context, conn *request return &jsonrpc2.Error{ Code: jsonrpc2.CodeInvalidParams, Message: "Invalid params", - }, fmt.Errorf("failed to parse params: %v", err) + }, fmt.Errorf("failed to parse params: %w", err) } if err := params.Validate(); err != nil { return &jsonrpc2.Error{ @@ -137,12 +137,12 @@ func (multi *MultiEpoch) handleGetTransaction(ctx context.Context, conn *request return &jsonrpc2.Error{ Code: CodeNotFound, Message: "Transaction not found", - }, fmt.Errorf("failed to find epoch number from signature %s: %v", sig, err) + }, fmt.Errorf("failed to find epoch number from signature %s: %w", sig, err) } return &jsonrpc2.Error{ Code: jsonrpc2.CodeInternalError, Message: "Internal error", - }, fmt.Errorf("failed to get epoch for signature %s: %v", sig, err) + }, fmt.Errorf("failed to get epoch for signature %s: %w", sig, err) } klog.V(4).Infof("Found signature %s in epoch %d in %s", sig, epochNumber, time.Since(startedEpochLookupAt)) @@ -166,7 +166,7 @@ func (multi *MultiEpoch) handleGetTransaction(ctx context.Context, conn *request return &jsonrpc2.Error{ Code: jsonrpc2.CodeInternalError, Message: "Internal error", - }, fmt.Errorf("failed to get Transaction: %v", err) + }, fmt.Errorf("failed to get Transaction: %w", err) } { conn.ctx.Response.Header.Set("DAG-Root-CID", transactionCid.String()) @@ -181,7 +181,7 @@ func (multi *MultiEpoch) handleGetTransaction(ctx context.Context, conn *request return &jsonrpc2.Error{ Code: jsonrpc2.CodeInternalError, Message: "Internal error", - }, fmt.Errorf("failed to get block: %v", err) + }, fmt.Errorf("failed to get block: %w", err) } blocktime := uint64(block.Meta.Blocktime) if blocktime != 0 { @@ -199,7 +199,7 @@ func (multi *MultiEpoch) handleGetTransaction(ctx context.Context, conn *request return &jsonrpc2.Error{ Code: jsonrpc2.CodeInternalError, Message: "Internal error", - }, fmt.Errorf("failed to decode transaction: %v", err) + }, fmt.Errorf("failed to decode transaction: %w", err) } response.Signatures = tx.Signatures if tx.Message.IsVersioned() { @@ -214,7 +214,7 @@ func (multi *MultiEpoch) handleGetTransaction(ctx context.Context, conn *request return &jsonrpc2.Error{ Code: jsonrpc2.CodeInternalError, Message: "Internal error", - }, fmt.Errorf("failed to encode transaction: %v", err) + }, fmt.Errorf("failed to encode transaction: %w", err) } response.Transaction = encodedTx } From 5059d8715a45eb3b4f53e0a2aea97b7651cd36f0 Mon Sep 17 00:00:00 2001 From: gagliardetto Date: Tue, 20 Feb 2024 16:52:59 +0100 Subject: [PATCH 4/4] If tx not found, return `"result": null` like solana does --- multiepoch-getTransaction.go | 2 +- multiepoch.go | 20 +++++++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/multiepoch-getTransaction.go b/multiepoch-getTransaction.go index ad194acb..34a375a2 100644 --- a/multiepoch-getTransaction.go +++ b/multiepoch-getTransaction.go @@ -133,7 +133,7 @@ func (multi *MultiEpoch) handleGetTransaction(ctx context.Context, conn *request epochNumber, err := multi.findEpochNumberFromSignature(ctx, sig) if err != nil { if errors.Is(err, ErrNotFound) { - // TODO: solana just returns null here in case of transaction not found: {"jsonrpc":"2.0","result":null,"id":1} + // solana just returns null here in case of transaction not found: {"jsonrpc":"2.0","result":null,"id":1} return &jsonrpc2.Error{ Code: CodeNotFound, Message: "Transaction not found", diff --git a/multiepoch.go b/multiepoch.go index 06008e0a..2eb3e13c 100644 --- a/multiepoch.go +++ b/multiepoch.go @@ -2,6 +2,7 @@ package main import ( "context" + "errors" "fmt" "net/http" "sort" @@ -401,11 +402,20 @@ func newMultiEpochHandler(handler *MultiEpoch, lsConf *ListenerConfig) func(ctx metrics_methodToNumProxied.WithLabelValues(sanitizeMethod(method)).Inc() return } else { - rqCtx.ReplyWithError( - reqCtx, - rpcRequest.ID, - errorResp, - ) + if errors.Is(err, ErrNotFound) { + // reply with null result + rqCtx.ReplyRaw( + reqCtx, + rpcRequest.ID, + nil, + ) + } else { + rqCtx.ReplyWithError( + reqCtx, + rpcRequest.ID, + errorResp, + ) + } } return }