Skip to content

Commit 9eef61c

Browse files
committed
refactor: use metrics middleware in request handler
Signed-off-by: Gustavo Inacio <[email protected]>
1 parent 6f9b909 commit 9eef61c

File tree

4 files changed

+57
-65
lines changed

4 files changed

+57
-65
lines changed

crates/service/src/error.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,6 @@ pub enum IndexerServiceError {
3030
#[error("Failed to sign attestation")]
3131
FailedToSignAttestation,
3232

33-
#[error("Could not decode signer: {0}")]
34-
CouldNotDecodeSigner(tap_core::Error),
35-
3633
#[error("There was an error while accessing escrow account: {0}")]
3734
EscrowAccount(#[from] EscrowAccountsError),
3835
}
@@ -54,7 +51,6 @@ impl IntoResponse for IndexerServiceError {
5451
ReceiptError(_)
5552
| InvalidRequest(_)
5653
| InvalidFreeQueryAuthToken
57-
| CouldNotDecodeSigner(_)
5854
| EscrowAccount(_)
5955
| ProcessingError(_) => StatusCode::BAD_REQUEST,
6056
};

crates/service/src/middleware.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,10 @@ mod inject_labels;
77
mod inject_receipt;
88
mod inject_sender;
99
mod metrics;
10+
11+
pub use inject_allocation::{allocation_middleware, AllocationState};
12+
pub use inject_deployment::deployment_middleware;
13+
pub use inject_labels::labels_middleware;
14+
pub use inject_receipt::receipt_middleware;
15+
pub use inject_sender::{sender_middleware, SenderState, Sender};
16+
pub use metrics::MetricsMiddlewareLayer;

crates/service/src/routes/request_handler.rs

Lines changed: 6 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33

44
use std::sync::Arc;
55

6-
use crate::{error::IndexerServiceError, metrics::{FAILED_RECEIPT, HANDLER_FAILURE, HANDLER_HISTOGRAM}, tap::AgoraQuery};
6+
use crate::{
7+
error::IndexerServiceError, metrics::FAILED_RECEIPT, middleware::Sender, tap::AgoraQuery,
8+
};
79
use axum::{
810
extract::{Path, State},
911
http::HeaderMap,
1012
response::IntoResponse,
13+
Extension,
1114
};
1215
use axum_extra::TypedHeader;
1316
use reqwest::StatusCode;
@@ -20,23 +23,8 @@ use crate::service::{AttestationOutput, IndexerServiceResponse, IndexerServiceSt
2023

2124
pub async fn request_handler(
2225
Path(manifest_id): Path<DeploymentId>,
23-
typed_header: TypedHeader<TapReceipt>,
24-
state: State<Arc<IndexerServiceState>>,
25-
headers: HeaderMap,
26-
body: String,
27-
) -> Result<impl IntoResponse, IndexerServiceError> {
28-
_request_handler(manifest_id, typed_header, state, headers, body)
29-
.await
30-
.inspect_err(|_| {
31-
HANDLER_FAILURE
32-
.with_label_values(&[&manifest_id.to_string()])
33-
.inc()
34-
})
35-
}
36-
37-
async fn _request_handler(
38-
manifest_id: DeploymentId,
3926
TypedHeader(receipt): TypedHeader<TapReceipt>,
27+
Extension(sender): Extension<Sender>,
4028
State(state): State<Arc<IndexerServiceState>>,
4129
headers: HeaderMap,
4230
req: String,
@@ -87,30 +75,6 @@ async fn _request_handler(
8775
variables,
8876
});
8977

90-
// recover the signer address
91-
// get escrow accounts from channel
92-
// return sender from signer
93-
//
94-
// TODO: We are currently doing this process twice.
95-
// One here and other on common/src/tap/checks/sender_balance_check.rs
96-
// We'll get back to normal once we have attachable context to `verify_and_store_receipt`
97-
let signer = receipt
98-
.recover_signer(&state.domain_separator)
99-
.map_err(IndexerServiceError::CouldNotDecodeSigner)?;
100-
let sender = state
101-
.escrow_accounts
102-
.borrow()
103-
.get_sender_for_signer(&signer)
104-
.map_err(IndexerServiceError::EscrowAccount)?;
105-
106-
let _metric = HANDLER_HISTOGRAM
107-
.with_label_values(&[
108-
&manifest_id.to_string(),
109-
&allocation_id.to_string(),
110-
&sender.to_string(),
111-
])
112-
.start_timer();
113-
11478
// Verify the receipt and store it in the database
11579
state
11680
.tap_manager
@@ -121,7 +85,7 @@ async fn _request_handler(
12185
.with_label_values(&[
12286
&manifest_id.to_string(),
12387
&allocation_id.to_string(),
124-
&sender.to_string(),
88+
&sender.0.to_string(),
12589
])
12690
.inc()
12791
})

crates/service/src/service/indexer_service.rs

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
// Copyright 2023-, Edge & Node, GraphOps, and Semiotic Labs.
22
// SPDX-License-Identifier: Apache-2.0
33

4-
use alloy::dyn_abi::Eip712Domain;
54
use anyhow;
65
use axum::extract::MatchedPath;
76
use axum::extract::Request as ExtractRequest;
8-
use axum::http::{Method, Request};
97
use axum::{
8+
http::{Method, Request},
9+
middleware::{from_fn, from_fn_with_state},
1010
response::IntoResponse,
1111
routing::{get, post},
12-
Json, Router,
12+
serve, Json, Router, ServiceExt,
1313
};
14-
use axum::{serve, ServiceExt};
1514
use build_info::BuildInfo;
1615
use indexer_attestation::AttestationSigner;
1716
use indexer_monitor::{
18-
attestation_signers, dispute_manager, escrow_accounts, indexer_allocations, DeploymentDetails,
19-
EscrowAccounts, SubgraphClient,
17+
attestation_signers, deployment_to_allocation, dispute_manager, escrow_accounts,
18+
indexer_allocations, DeploymentDetails, SubgraphClient,
2019
};
2120
use prometheus::TextEncoder;
2221
use reqwest::StatusCode;
@@ -30,17 +29,23 @@ use thegraph_core::{Address, Attestation};
3029
use tokio::net::TcpListener;
3130
use tokio::signal;
3231
use tokio::sync::watch::Receiver;
32+
use tower::ServiceBuilder;
3333
use tower_governor::{governor::GovernorConfigBuilder, GovernorLayer};
3434
use tower_http::validate_request::ValidateRequestHeaderLayer;
3535
use tower_http::{cors, cors::CorsLayer, normalize_path::NormalizePath, trace::TraceLayer};
3636
use tracing::warn;
3737
use tracing::{error, info, info_span};
3838

39-
use crate::routes::health;
40-
use crate::routes::request_handler;
41-
use crate::routes::static_subgraph_request_handler;
42-
use crate::tap::IndexerTapContext;
43-
use crate::wallet::public_key;
39+
use crate::{
40+
metrics::{HANDLER_FAILURE, HANDLER_HISTOGRAM},
41+
middleware::{
42+
allocation_middleware, deployment_middleware, labels_middleware, receipt_middleware,
43+
sender_middleware, AllocationState, MetricsMiddlewareLayer, SenderState,
44+
},
45+
routes::{health, request_handler, static_subgraph_request_handler},
46+
tap::IndexerTapContext,
47+
wallet::public_key,
48+
};
4449
use indexer_config::Config;
4550

4651
use super::SubgraphService;
@@ -93,10 +98,6 @@ pub struct IndexerServiceState {
9398
pub attestation_signers: Receiver<HashMap<Address, AttestationSigner>>,
9499
pub tap_manager: Manager<IndexerTapContext>,
95100
pub service_impl: SubgraphService,
96-
97-
// tap
98-
pub escrow_accounts: Receiver<EscrowAccounts>,
99-
pub domain_separator: Eip712Domain,
100101
}
101102

102103
const HTTP_CLIENT_TIMEOUT: Duration = Duration::from_secs(30);
@@ -257,7 +258,7 @@ pub async fn run(options: IndexerServiceOptions) -> Result<(), anyhow::Error> {
257258

258259
let checks = IndexerTapContext::get_checks(
259260
database,
260-
allocations,
261+
allocations.clone(),
261262
escrow_accounts.clone(),
262263
domain_separator.clone(),
263264
timestamp_error_tolerance,
@@ -276,8 +277,6 @@ pub async fn run(options: IndexerServiceOptions) -> Result<(), anyhow::Error> {
276277
attestation_signers,
277278
tap_manager,
278279
service_impl: options.service_impl,
279-
escrow_accounts,
280-
domain_separator,
281280
});
282281

283282
// Rate limits by allowing bursts of 10 requests and requiring 100ms of
@@ -362,13 +361,39 @@ pub async fn run(options: IndexerServiceOptions) -> Result<(), anyhow::Error> {
362361

363362
misc_routes = misc_routes.with_state(state.clone());
364363

364+
let deployment_to_allocation = deployment_to_allocation(allocations);
365+
let allocation_state = AllocationState {
366+
deployment_to_allocation,
367+
};
368+
let sender_state = SenderState {
369+
escrow_accounts,
370+
domain_separator,
371+
};
372+
373+
let service_builder = ServiceBuilder::new()
374+
// inject deployment id
375+
.layer(from_fn(deployment_middleware))
376+
// inject receipt
377+
.layer(from_fn(receipt_middleware))
378+
// inject allocation id
379+
.layer(from_fn_with_state(allocation_state, allocation_middleware))
380+
// inject sender
381+
.layer(from_fn_with_state(sender_state, sender_middleware))
382+
// inject metrics labels
383+
.layer(from_fn(labels_middleware))
384+
// metrics for histogram and failure
385+
.layer(MetricsMiddlewareLayer::new(
386+
HANDLER_HISTOGRAM.clone(),
387+
HANDLER_FAILURE.clone(),
388+
));
389+
365390
let data_routes = Router::new()
366391
.route(
367392
PathBuf::from(&options.config.service.url_prefix)
368393
.join(format!("{}/id/:id", options.url_namespace))
369394
.to_str()
370395
.expect("Failed to set up `/{url_namespace}/id/:id` route"),
371-
post(request_handler),
396+
post(request_handler).route_layer(service_builder),
372397
)
373398
.with_state(state.clone());
374399

0 commit comments

Comments
 (0)