(ctx context.Context, networkId string, nq *common.NormalizedRequest)
| 99 | } |
| 100 | |
| 101 | func (p *PreparedProject) Forward(ctx context.Context, networkId string, nq *common.NormalizedRequest) (*common.NormalizedResponse, error) { |
| 102 | start := time.Now() |
| 103 | ctx, span := common.StartDetailSpan(ctx, "Project.Forward") |
| 104 | defer span.End() |
| 105 | |
| 106 | network, err := p.networksRegistry.GetNetwork(ctx, networkId) |
| 107 | if err != nil { |
| 108 | common.SetTraceSpanError(span, err) |
| 109 | return nil, err |
| 110 | } |
| 111 | // Ensure project label is available for budget decision metrics by setting network on request early |
| 112 | nq.SetNetwork(network) |
| 113 | if err := p.AcquireRateLimitPermit(ctx, nq); err != nil { |
| 114 | common.SetTraceSpanError(span, err) |
| 115 | return nil, err |
| 116 | } |
| 117 | |
| 118 | method, _ := nq.Method() |
| 119 | |
| 120 | // Get initial finality from request |
| 121 | reqFinality := nq.Finality(ctx) |
| 122 | |
| 123 | telemetry.CounterHandle(telemetry.MetricNetworkRequestsReceived, |
| 124 | p.Config.Id, network.Label(), method, reqFinality.String(), nq.UserId(), nq.AgentName(), |
| 125 | ).Inc() |
| 126 | lg := p.Logger.With(). |
| 127 | Str("component", "proxy"). |
| 128 | Str("projectId", p.Config.Id). |
| 129 | Str("networkId", network.Id()). |
| 130 | Str("method", method). |
| 131 | Interface("id", nq.ID()). |
| 132 | Str("ptr", fmt.Sprintf("%p", nq)). |
| 133 | Logger() |
| 134 | |
| 135 | resp, err := p.doForward(ctx, network, nq) |
| 136 | |
| 137 | shadowUpstreams := network.ShadowUpstreams() |
| 138 | if len(shadowUpstreams) > 0 { |
| 139 | if resp != nil { |
| 140 | jrr, jerr := resp.JsonRpcResponse(ctx) |
| 141 | if jerr != nil || jrr == nil { |
| 142 | if jerr != nil { |
| 143 | lg.Error().Err(jerr).Msgf("failed to parse response for shadow requests") |
| 144 | } else { |
| 145 | lg.Error().Msgf("failed to parse response for shadow requests: nil jsonRpcResponse") |
| 146 | } |
| 147 | } else { |
| 148 | jrc, cerr := jrr.Clone() |
| 149 | if cerr != nil { |
| 150 | lg.Error().Err(cerr).Msgf("failed to clone json-rpc response for shadow requests") |
| 151 | } else { |
| 152 | cloneResp := common.NewNormalizedResponse().WithRequest(nq).WithJsonRpcResponse(jrc) |
| 153 | cloneResp.SetUpstream(resp.Upstream()) |
| 154 | cloneResp.SetFromCache(resp.FromCache()) |
| 155 | cloneResp.SetAttempts(resp.Attempts()) |
| 156 | cloneResp.SetRetries(resp.Retries()) |
| 157 | cloneResp.SetHedges(resp.Hedges()) |
| 158 | cloneResp.SetEvmBlockRef(resp.EvmBlockRef()) |
nothing calls this directly
no test coverage detected