Skip to content

Commit bb575b1

Browse files
committed
add address to metric
1 parent e919f7e commit bb575b1

File tree

3 files changed

+94
-2
lines changed

3 files changed

+94
-2
lines changed
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
use alloy_primitives::{hex, keccak256, Bytes};
2+
use jsonrpsee::proc_macros::rpc;
3+
use jsonrpsee_core::RpcResult;
4+
use std::sync::Arc;
5+
use tokio::sync::RwLock;
6+
7+
use super::{
8+
args::FlashtestationsArgs,
9+
attestation::{AttestationConfig, get_attestation_provider},
10+
service::load_or_generate_tee_key,
11+
};
12+
13+
/// Admin API for op-rbuilder flashtestations
14+
#[rpc(server, namespace = "admin")]
15+
pub trait AdminApi {
16+
/// Get the raw attestation quote (cached after first request)
17+
#[method(name = "getAttestationQuote")]
18+
async fn get_attestation_quote(&self) -> RpcResult<Option<String>>;
19+
}
20+
21+
/// Admin RPC server implementation
22+
pub struct AdminRpcServer {
23+
flashtestations_args: FlashtestationsArgs,
24+
cached_quote: Arc<RwLock<Option<Vec<u8>>>>,
25+
}
26+
27+
impl AdminRpcServer {
28+
pub fn new(flashtestations_args: FlashtestationsArgs) -> Self {
29+
Self {
30+
flashtestations_args,
31+
cached_quote: Arc::new(RwLock::new(None)),
32+
}
33+
}
34+
}
35+
36+
#[async_trait::async_trait]
37+
impl AdminApiServer for AdminRpcServer {
38+
async fn get_attestation_quote(&self) -> RpcResult<Option<String>> {
39+
// Check if quote is already cached
40+
{
41+
let cache = self.cached_quote.read().await;
42+
if let Some(quote) = cache.as_ref() {
43+
return Ok(Some(hex::encode(quote)));
44+
}
45+
}
46+
47+
// Load TEE key using same logic as bootstrap
48+
let tee_service_signer = match load_or_generate_tee_key(
49+
&self.flashtestations_args.flashtestations_key_path,
50+
self.flashtestations_args.debug,
51+
&self.flashtestations_args.debug_tee_key_seed,
52+
) {
53+
Ok(signer) => signer,
54+
Err(e) => {
55+
tracing::error!(error = %e, "Failed to load TEE key");
56+
return Ok(None);
57+
}
58+
};
59+
60+
// Quote not cached, fetch it
61+
let attestation_provider = get_attestation_provider(AttestationConfig {
62+
debug: self.flashtestations_args.debug,
63+
quote_provider: self.flashtestations_args.quote_provider.clone(),
64+
});
65+
66+
// Prepare report data same as in bootstrap
67+
let mut report_data = [0u8; 64];
68+
let tee_address_bytes: [u8; 20] = tee_service_signer.address.into();
69+
report_data[0..20].copy_from_slice(&tee_address_bytes);
70+
71+
// Use empty ext_data same as bootstrap
72+
let ext_data = Bytes::from(b"");
73+
let ext_data_hash = keccak256(ext_data.as_ref());
74+
report_data[20..52].copy_from_slice(ext_data_hash.as_ref());
75+
76+
// Request attestation
77+
match attestation_provider.get_attestation(report_data).await {
78+
Ok(quote) => {
79+
// Cache the quote for future requests
80+
let mut cache = self.cached_quote.write().await;
81+
*cache = Some(quote.clone());
82+
Ok(Some(hex::encode(quote)))
83+
}
84+
Err(e) => {
85+
tracing::error!(error = %e, "Failed to get attestation quote");
86+
Ok(None)
87+
}
88+
}
89+
}
90+
}

crates/op-rbuilder/src/flashtestations/service.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ where
7676
let attestation = attestation_provider.get_attestation(report_data).await?;
7777

7878
// Record TEE metrics (workload ID, MRTD, RTMR0)
79-
record_tee_metrics(&attestation, tee_service_signer.address)?;
79+
record_tee_metrics(&attestation, &tee_service_signer.address)?;
8080

8181
// Use an external rpc when the builder is not the same as the builder actively building blocks onchain
8282
let registered = if let Some(rpc_url) = args.rpc_url {

crates/op-rbuilder/src/metrics.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use alloy_primitives::{Address, hex};
12
use metrics::IntoF64;
23
use reth_metrics::{
34
Metrics,
@@ -216,12 +217,13 @@ pub fn record_tee_metrics(raw_quote: &[u8], tee_address: &Address) -> eyre::Resu
216217
let mr_td_hex = hex::encode(parsed_quote.mr_td);
217218
let rt_mr0_hex = hex::encode(parsed_quote.rt_mr0);
218219

220+
let tee_address_static: &'static str = Box::leak(tee_address.to_string().into_boxed_str());
219221
let workload_id_static: &'static str = Box::leak(workload_id_hex.into_boxed_str());
220222
let mr_td_static: &'static str = Box::leak(mr_td_hex.into_boxed_str());
221223
let rt_mr0_static: &'static str = Box::leak(rt_mr0_hex.into_boxed_str());
222224

223225
// Record TEE address
224-
let tee_address_labels: [(&str, &str); 1] = [("tee_address", tee_address.to_string().as_str())];
226+
let tee_address_labels: [(&str, &str); 1] = [("tee_address", tee_address_static)];
225227
gauge!("op_rbuilder_tee_address", &tee_address_labels).set(1);
226228

227229
// Record workload ID

0 commit comments

Comments
 (0)