From 6f3b6e214aa93ee69adbea7d26369e611e3e6f3c Mon Sep 17 00:00:00 2001 From: gagliardetto Date: Tue, 20 Feb 2024 12:45:12 +0100 Subject: [PATCH] Add DAG-Root-CID header for getBlock and getTransaction responses --- epoch.go | 20 ++++++++++---------- multiepoch-getBlock.go | 9 +++++++-- multiepoch-getBlockTime.go | 2 +- multiepoch-getSignaturesForAddress.go | 4 ++-- multiepoch-getTransaction.go | 7 +++++-- 5 files changed, 25 insertions(+), 17 deletions(-) diff --git a/epoch.go b/epoch.go index 78eb1249..f7f15ac8 100644 --- a/epoch.go +++ b/epoch.go @@ -785,11 +785,11 @@ func (ser *Epoch) FindOffsetAndSizeFromCid(ctx context.Context, cid cid.Cid) (os return found, nil } -func (ser *Epoch) GetBlock(ctx context.Context, slot uint64) (*ipldbindcode.Block, error) { +func (ser *Epoch) GetBlock(ctx context.Context, slot uint64) (*ipldbindcode.Block, cid.Cid, error) { // get the slot by slot number wantedCid, err := ser.FindCidFromSlot(ctx, slot) if err != nil { - return nil, fmt.Errorf("failed to find CID for slot %d: %w", slot, err) + return nil, cid.Cid{}, fmt.Errorf("failed to find CID for slot %d: %w", slot, err) } { doPrefetch := getValueFromContext(ctx, "prefetch") @@ -801,14 +801,14 @@ func (ser *Epoch) GetBlock(ctx context.Context, slot uint64) (*ipldbindcode.Bloc // get the block by CID data, err := ser.GetNodeByCid(ctx, wantedCid) if err != nil { - return nil, fmt.Errorf("failed to get node by cid %s: %w", wantedCid, err) + return nil, cid.Cid{}, fmt.Errorf("failed to get node by cid %s: %w", wantedCid, err) } // try parsing the data as a Block node. decoded, err := iplddecoders.DecodeBlock(data) if err != nil { - return nil, fmt.Errorf("failed to decode block with CID %s: %w", wantedCid, err) + return nil, cid.Cid{}, fmt.Errorf("failed to decode block with CID %s: %w", wantedCid, err) } - return decoded, nil + return decoded, wantedCid, nil } func (ser *Epoch) GetEntryByCid(ctx context.Context, wantedCid cid.Cid) (*ipldbindcode.Entry, error) { @@ -863,11 +863,11 @@ func (ser *Epoch) GetRewardsByCid(ctx context.Context, wantedCid cid.Cid) (*ipld return decoded, nil } -func (ser *Epoch) GetTransaction(ctx context.Context, sig solana.Signature) (*ipldbindcode.Transaction, error) { +func (ser *Epoch) GetTransaction(ctx context.Context, sig solana.Signature) (*ipldbindcode.Transaction, cid.Cid, error) { // get the CID by signature wantedCid, err := ser.FindCidFromSignature(ctx, sig) if err != nil { - return nil, fmt.Errorf("failed to find CID for signature %s: %w", sig, err) + return nil, cid.Cid{}, fmt.Errorf("failed to find CID for signature %s: %w", sig, err) } { doPrefetch := getValueFromContext(ctx, "prefetch") @@ -879,12 +879,12 @@ func (ser *Epoch) GetTransaction(ctx context.Context, sig solana.Signature) (*ip // get the transaction by CID data, err := ser.GetNodeByCid(ctx, wantedCid) if err != nil { - return nil, fmt.Errorf("failed to get node by cid %s: %w", wantedCid, err) + return nil, cid.Cid{}, fmt.Errorf("failed to get node by cid %s: %w", wantedCid, err) } // try parsing the data as a Transaction node. decoded, err := iplddecoders.DecodeTransaction(data) if err != nil { - return nil, fmt.Errorf("failed to decode transaction with CID %s: %w", wantedCid, err) + return nil, cid.Cid{}, fmt.Errorf("failed to decode transaction with CID %s: %w", wantedCid, err) } - return decoded, nil + return decoded, wantedCid, nil } diff --git a/multiepoch-getBlock.go b/multiepoch-getBlock.go index 4c91cc70..ac7bc3b7 100644 --- a/multiepoch-getBlock.go +++ b/multiepoch-getBlock.go @@ -70,7 +70,7 @@ func (multi *MultiEpoch) handleGetBlock(ctx context.Context, conn *requestContex }, fmt.Errorf("failed to get epoch %d: %w", epochNumber, err) } - block, err := epochHandler.GetBlock(WithSubrapghPrefetch(ctx, true), slot) + block, blockCid, err := epochHandler.GetBlock(WithSubrapghPrefetch(ctx, true), slot) if err != nil { if errors.Is(err, compactindexsized.ErrNotFound) { return &jsonrpc2.Error{ @@ -84,6 +84,11 @@ func (multi *MultiEpoch) handleGetBlock(ctx context.Context, conn *requestContex }, fmt.Errorf("failed to get block: %w", err) } } + // set the headers: + { + conn.ctx.Response.Header.Set("DAG-Root-CID", blockCid.String()) + } + tim.time("GetBlock") { prefetcherFromCar := func() error { @@ -448,7 +453,7 @@ func (multi *MultiEpoch) handleGetBlock(ctx context.Context, conn *requestContex if (parentSlot != 0 || slot == 1) && CalcEpochForSlot(parentSlot) == epochNumber { // NOTE: if the parent is in the same epoch, we can get it from the same epoch handler as the block; // otherwise, we need to get it from the previous epoch (TODO: implement this) - parentBlock, err := epochHandler.GetBlock(WithSubrapghPrefetch(ctx, false), parentSlot) + parentBlock, _, err := epochHandler.GetBlock(WithSubrapghPrefetch(ctx, false), parentSlot) if err != nil { return &jsonrpc2.Error{ Code: jsonrpc2.CodeInternalError, diff --git a/multiepoch-getBlockTime.go b/multiepoch-getBlockTime.go index dbcb047b..c9b87172 100644 --- a/multiepoch-getBlockTime.go +++ b/multiepoch-getBlockTime.go @@ -28,7 +28,7 @@ func (multi *MultiEpoch) handleGetBlockTime(ctx context.Context, conn *requestCo }, fmt.Errorf("failed to get epoch %d: %w", epochNumber, err) } - block, err := epochHandler.GetBlock(WithSubrapghPrefetch(ctx, false), blockNum) + block, _, err := epochHandler.GetBlock(WithSubrapghPrefetch(ctx, false), blockNum) if err != nil { if errors.Is(err, compactindexsized.ErrNotFound) { return &jsonrpc2.Error{ diff --git a/multiepoch-getSignaturesForAddress.go b/multiepoch-getSignaturesForAddress.go index 3e5d2f54..6aaf85ff 100644 --- a/multiepoch-getSignaturesForAddress.go +++ b/multiepoch-getSignaturesForAddress.go @@ -123,7 +123,7 @@ func (multi *MultiEpoch) handleGetSignaturesForAddress(ctx context.Context, conn if blockTime, ok := blockTimeCache.m[slot]; ok { return blockTime } - block, err := ser.GetBlock(ctx, slot) + block, _, err := ser.GetBlock(ctx, slot) if err != nil { klog.Errorf("failed to get block time for slot %d: %v", slot, err) return 0 @@ -158,7 +158,7 @@ func (multi *MultiEpoch) handleGetSignaturesForAddress(ctx context.Context, conn if signaturesOnly { return nil } - transactionNode, err := ser.GetTransaction(ctx, sig) + transactionNode, _, err := ser.GetTransaction(ctx, sig) if err != nil { klog.Errorf("failed to get tx %s: %v", sig, err) return nil diff --git a/multiepoch-getTransaction.go b/multiepoch-getTransaction.go index e5da594e..0fc1ad8e 100644 --- a/multiepoch-getTransaction.go +++ b/multiepoch-getTransaction.go @@ -153,7 +153,7 @@ func (multi *MultiEpoch) handleGetTransaction(ctx context.Context, conn *request }, fmt.Errorf("failed to get handler for epoch %d: %w", epochNumber, err) } - transactionNode, err := epochHandler.GetTransaction(WithSubrapghPrefetch(ctx, true), sig) + 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 @@ -167,12 +167,15 @@ func (multi *MultiEpoch) handleGetTransaction(ctx context.Context, conn *request Message: "Internal error", }, fmt.Errorf("failed to get Transaction: %v", err) } + { + conn.ctx.Response.Header.Set("DAG-Root-CID", transactionCid.String()) + } var response GetTransactionResponse response.Slot = ptrToUint64(uint64(transactionNode.Slot)) { - block, err := epochHandler.GetBlock(ctx, uint64(transactionNode.Slot)) + block, _, err := epochHandler.GetBlock(ctx, uint64(transactionNode.Slot)) if err != nil { return &jsonrpc2.Error{ Code: jsonrpc2.CodeInternalError,