mirror of
https://github.com/vacp2p/status-rln-prover.git
synced 2026-01-08 05:03:54 -05:00
Initial code for tracing + oltp (#19)
* Initial code for tracing + oltp * Add tracing for all grpc endpoints + proof services + epoch service * Trace result and errors for grpc endpoints
This commit is contained in:
209
Cargo.lock
generated
209
Cargo.lock
generated
@@ -1493,6 +1493,12 @@ version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "cfg_aliases"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.41"
|
||||
@@ -2326,8 +2332,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2337,9 +2345,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"r-efi",
|
||||
"wasi 0.14.2+wasi-0.2.4",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3021,6 +3031,12 @@ dependencies = [
|
||||
"hashbrown 0.15.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lru-slab"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
|
||||
|
||||
[[package]]
|
||||
name = "lz4-sys"
|
||||
version = "1.11.1+lz4-1.10.0"
|
||||
@@ -3371,6 +3387,82 @@ dependencies = [
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry"
|
||||
version = "0.30.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aaf416e4cb72756655126f7dd7bb0af49c674f4c1b9903e80c009e0c37e552e6"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"js-sys",
|
||||
"pin-project-lite",
|
||||
"thiserror 2.0.12",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry-http"
|
||||
version = "0.30.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50f6639e842a97dbea8886e3439710ae463120091e2e064518ba8e716e6ac36d"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
"http",
|
||||
"opentelemetry",
|
||||
"reqwest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry-otlp"
|
||||
version = "0.30.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbee664a43e07615731afc539ca60c6d9f1a9425e25ca09c57bc36c87c55852b"
|
||||
dependencies = [
|
||||
"http",
|
||||
"opentelemetry",
|
||||
"opentelemetry-http",
|
||||
"opentelemetry-proto",
|
||||
"opentelemetry_sdk",
|
||||
"prost",
|
||||
"reqwest",
|
||||
"thiserror 2.0.12",
|
||||
"tokio",
|
||||
"tonic",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry-proto"
|
||||
version = "0.30.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e046fd7660710fe5a05e8748e70d9058dc15c94ba914e7c4faa7c728f0e8ddc"
|
||||
dependencies = [
|
||||
"opentelemetry",
|
||||
"opentelemetry_sdk",
|
||||
"prost",
|
||||
"tonic",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opentelemetry_sdk"
|
||||
version = "0.30.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11f644aa9e5e31d11896e024305d7e3c98a88884d9f8919dbf37a9991bc47a4b"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-executor",
|
||||
"futures-util",
|
||||
"opentelemetry",
|
||||
"percent-encoding",
|
||||
"rand 0.9.1",
|
||||
"serde_json",
|
||||
"thiserror 2.0.12",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ordered-float"
|
||||
version = "4.6.0"
|
||||
@@ -3796,10 +3888,14 @@ name = "prover_cli"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"opentelemetry",
|
||||
"opentelemetry-otlp",
|
||||
"opentelemetry_sdk",
|
||||
"prover",
|
||||
"tokio",
|
||||
"toml",
|
||||
"tracing",
|
||||
"tracing-opentelemetry",
|
||||
"tracing-subscriber 0.3.19",
|
||||
"tracing-test",
|
||||
]
|
||||
@@ -3809,7 +3905,9 @@ name = "prover_client"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"alloy",
|
||||
"clap",
|
||||
"prost",
|
||||
"sha2",
|
||||
"tokio",
|
||||
"tonic",
|
||||
"tonic-build",
|
||||
@@ -3836,6 +3934,61 @@ version = "1.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
||||
|
||||
[[package]]
|
||||
name = "quinn"
|
||||
version = "0.11.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "626214629cda6781b6dc1d316ba307189c85ba657213ce642d9c77670f8202c8"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"cfg_aliases",
|
||||
"pin-project-lite",
|
||||
"quinn-proto",
|
||||
"quinn-udp",
|
||||
"rustc-hash 2.1.1",
|
||||
"rustls",
|
||||
"socket2",
|
||||
"thiserror 2.0.12",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"web-time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quinn-proto"
|
||||
version = "0.11.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49df843a9161c85bb8aae55f101bc0bac8bcafd637a620d9122fd7e0b2f7422e"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"getrandom 0.3.2",
|
||||
"lru-slab",
|
||||
"rand 0.9.1",
|
||||
"ring",
|
||||
"rustc-hash 2.1.1",
|
||||
"rustls",
|
||||
"rustls-pki-types",
|
||||
"slab",
|
||||
"thiserror 2.0.12",
|
||||
"tinyvec",
|
||||
"tracing",
|
||||
"web-time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quinn-udp"
|
||||
version = "0.5.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcebb1209ee276352ef14ff8732e24cc2b02bbac986cd74a4c81bcb2f9881970"
|
||||
dependencies = [
|
||||
"cfg_aliases",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"socket2",
|
||||
"tracing",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.40"
|
||||
@@ -4046,12 +4199,14 @@ checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"http",
|
||||
"http-body",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
"hyper-rustls",
|
||||
"hyper-tls",
|
||||
"hyper-util",
|
||||
"ipnet",
|
||||
@@ -4062,13 +4217,18 @@ dependencies = [
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"quinn",
|
||||
"rustls",
|
||||
"rustls-native-certs",
|
||||
"rustls-pemfile",
|
||||
"rustls-pki-types",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"sync_wrapper",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tokio-rustls",
|
||||
"tower",
|
||||
"tower-service",
|
||||
"url",
|
||||
@@ -4272,6 +4432,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "730944ca083c1c233a75c09f199e973ca499344a2b7ba9e755c457e86fb4a321"
|
||||
dependencies = [
|
||||
"aws-lc-rs",
|
||||
"log",
|
||||
"once_cell",
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
@@ -4306,6 +4467,9 @@ name = "rustls-pki-types"
|
||||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c"
|
||||
dependencies = [
|
||||
"web-time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
@@ -4948,6 +5112,21 @@ dependencies = [
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71"
|
||||
dependencies = [
|
||||
"tinyvec_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec_macros"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.46.0"
|
||||
@@ -5093,8 +5272,10 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
"pin-project",
|
||||
"prost",
|
||||
"rustls-native-certs",
|
||||
"socket2",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
"tokio-stream",
|
||||
"tower",
|
||||
"tower-layer",
|
||||
@@ -5247,6 +5428,24 @@ dependencies = [
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-opentelemetry"
|
||||
version = "0.31.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ddcf5959f39507d0d04d6413119c04f33b623f4f951ebcbdddddfad2d0623a9c"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"once_cell",
|
||||
"opentelemetry",
|
||||
"opentelemetry_sdk",
|
||||
"smallvec",
|
||||
"tracing",
|
||||
"tracing-core",
|
||||
"tracing-log",
|
||||
"tracing-subscriber 0.3.19",
|
||||
"web-time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.2.25"
|
||||
@@ -5569,6 +5768,16 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-time"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.26.11"
|
||||
|
||||
15
Readme.md
15
Readme.md
@@ -3,17 +3,24 @@
|
||||
## Docker
|
||||
|
||||
* docker build --progress=plain --no-cache -t prover .
|
||||
* sudo docker run -p 50051:50051 prover --mock-sc true --mock-user mock/mock_user_1.json
|
||||
* docker run -p 50051:50051 prover --mock-sc true --mock-user mock/mock_user_1.json
|
||||
|
||||
## Run prover
|
||||
|
||||
RUST_LOG=debug cargo run -p prover_cli -- -i 127.0.0.1 -r "wss://eth-mainnet.g.alchemy.com/v2/__MY_TOKEN__"
|
||||
|
||||
## Run prover + Mock
|
||||
### Run prover + Mock
|
||||
|
||||
RUST_LOG=debug cargo run -p prover_cli -- -i 127.0.0.1 --metrics-ip 127.0.0.1 --mock-sc true --mock-user mock/mock_user_1.json
|
||||
RUST_LOG=debug cargo run -p prover_cli -- -i 127.0.0.1 --metrics-ip 127.0.0.1 --mock-sc true --mock-user mock/mock_user_1.json
|
||||
|
||||
## Run prover client (for tests)
|
||||
### Run prover + opentelemetry
|
||||
|
||||
* Run jaeger (locally, port 16686 -> Web ui, port 4317 -> otlp/grpc, port 4318 -> otlp/http)
|
||||
* docker run -d --name jaeger -e COLLECTOR_OTLP_ENABLED=true -p 16686:16686 -p 4317:4317 -p 4318:4318 jaegertracing/all-in-one:latest
|
||||
* Run prover:
|
||||
* OTEL_EXPORTER_OTLP_PROTOCOL=grpc RUST_LOG=debug cargo run -p prover_cli -- -i 127.0.0.1 --metrics-ip 127.0.0.1 --mock-sc true --mock-user mock/mock_user_1.json
|
||||
|
||||
### Run prover client (for tests)
|
||||
|
||||
RUST_LOG=debug cargo run -p prover_client
|
||||
|
||||
|
||||
@@ -10,7 +10,9 @@ use tokio::sync::Notify;
|
||||
use tracing::{debug, error};
|
||||
// internal
|
||||
use crate::error::AppError;
|
||||
use crate::metrics::{EPOCH_SERVICE_CURRENT_EPOCH, EPOCH_SERVICE_CURRENT_EPOCH_SLICE, EPOCH_SERVICE_DRIFT_MILLIS};
|
||||
use crate::metrics::{
|
||||
EPOCH_SERVICE_CURRENT_EPOCH, EPOCH_SERVICE_CURRENT_EPOCH_SLICE, EPOCH_SERVICE_DRIFT_MILLIS,
|
||||
};
|
||||
|
||||
/// Duration of an epoch (1 day)
|
||||
const EPOCH_DURATION: Duration = Duration::from_secs(TimeDelta::days(1).num_seconds() as u64);
|
||||
@@ -39,6 +41,9 @@ pub struct EpochService {
|
||||
}
|
||||
|
||||
impl EpochService {
|
||||
// Note: listen_for_new_epoch never ends so no log will happen with #[instrument]
|
||||
// + metrics already tracks the current epoch / epoch_slice
|
||||
// #[instrument(skip(self), fields(self.epoch_slice_duration, self.genesis, self.current_epoch))]
|
||||
pub(crate) async fn listen_for_new_epoch(&self) -> Result<(), AppError> {
|
||||
let epoch_slice_count =
|
||||
Self::compute_epoch_slice_count(EPOCH_DURATION, self.epoch_slice_duration);
|
||||
@@ -91,7 +96,8 @@ impl EpochService {
|
||||
{
|
||||
let now_ = tokio::time::Instant::now();
|
||||
debug!("awake at: {:?}, drift by: {:?}", now_, now_ - wait_until);
|
||||
histogram!(EPOCH_SERVICE_DRIFT_MILLIS.name, "prover" => "epoch service").record(now_ - wait_until);
|
||||
histogram!(EPOCH_SERVICE_DRIFT_MILLIS.name, "prover" => "epoch service")
|
||||
.record(now_ - wait_until);
|
||||
}
|
||||
|
||||
// Note: could use checked_add() here, but it's quite impossible to have an overflow here
|
||||
@@ -112,8 +118,10 @@ impl EpochService {
|
||||
|
||||
// Note: based on this link https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions
|
||||
// "Casting from an integer to float will produce the closest possible float *"
|
||||
gauge!(EPOCH_SERVICE_CURRENT_EPOCH.name, "prover" => "epoch service").set(i64::from(current_epoch) as f64);
|
||||
gauge!(EPOCH_SERVICE_CURRENT_EPOCH_SLICE.name, "prover" => "epoch service").set(i64::from(current_epoch_slice) as f64);
|
||||
gauge!(EPOCH_SERVICE_CURRENT_EPOCH.name, "prover" => "epoch service")
|
||||
.set(current_epoch as f64);
|
||||
gauge!(EPOCH_SERVICE_CURRENT_EPOCH_SLICE.name, "prover" => "epoch service")
|
||||
.set(current_epoch_slice as f64);
|
||||
|
||||
// println!("Epoch changed: {}", current_epoch);
|
||||
self.epoch_changes.notify_one();
|
||||
|
||||
@@ -20,9 +20,12 @@ use tracing::debug;
|
||||
use url::Url;
|
||||
// internal
|
||||
use crate::error::{AppError, ProofGenerationStringError};
|
||||
use crate::metrics::{
|
||||
GET_PROOFS_LISTENERS, GET_USER_TIER_INFO_REQUESTS, GaugeWrapper, SEND_TRANSACTION_REQUESTS,
|
||||
USER_REGISTERED, USER_REGISTERED_REQUESTS,
|
||||
};
|
||||
use crate::proof_generation::{ProofGenerationData, ProofSendingData};
|
||||
use crate::user_db::{UserDb, UserTierInfo};
|
||||
use crate::metrics::{USER_REGISTERED, USER_REGISTERED_REQUESTS, SEND_TRANSACTION_REQUESTS, GET_USER_TIER_INFO_REQUESTS, GET_PROOFS_LISTENERS, GaugeWrapper};
|
||||
use crate::user_db_error::RegisterError;
|
||||
use rln_proof::RlnIdentifier;
|
||||
use smart_contract::{
|
||||
@@ -98,11 +101,11 @@ where
|
||||
RLNSC: RLNRegister + Send + Sync + 'static,
|
||||
RLNSC::Error: std::error::Error + Send + Sync + 'static,
|
||||
{
|
||||
#[tracing::instrument(skip(self), err, ret)]
|
||||
async fn send_transaction(
|
||||
&self,
|
||||
request: Request<SendTransactionRequest>,
|
||||
) -> Result<Response<SendTransactionReply>, Status> {
|
||||
|
||||
counter!(SEND_TRANSACTION_REQUESTS.name, "service" => "grpc").increment(1);
|
||||
debug!("send_transaction request: {:?}", request);
|
||||
let req = request.into_inner();
|
||||
@@ -153,6 +156,7 @@ where
|
||||
Ok(Response::new(reply))
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self), err, ret)]
|
||||
async fn register_user(
|
||||
&self,
|
||||
request: Request<RegisterUserRequest>,
|
||||
@@ -204,11 +208,11 @@ where
|
||||
|
||||
type GetProofsStream = ReceiverStream<Result<RlnProofReply, Status>>;
|
||||
|
||||
#[tracing::instrument(skip(self), err, ret)]
|
||||
async fn get_proofs(
|
||||
&self,
|
||||
request: Request<RlnProofFilter>,
|
||||
) -> Result<Response<Self::GetProofsStream>, Status> {
|
||||
|
||||
debug!("get_proofs request: {:?}", request);
|
||||
let gauge = GaugeWrapper::new(GET_PROOFS_LISTENERS.name, "service", "grpc");
|
||||
|
||||
@@ -217,7 +221,6 @@ where
|
||||
// Channel to receive a RLN proof (from one proof service)
|
||||
let mut rx2 = self.broadcast_channel.0.subscribe();
|
||||
tokio::spawn(async move {
|
||||
|
||||
// FIXME: Should we send the error here?
|
||||
|
||||
let gauge_ = gauge;
|
||||
@@ -246,11 +249,11 @@ where
|
||||
Ok(Response::new(ReceiverStream::new(rx)))
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self), err, ret)]
|
||||
async fn get_user_tier_info(
|
||||
&self,
|
||||
request: Request<GetUserTierInfoRequest>,
|
||||
) -> Result<Response<GetUserTierInfoReply>, Status> {
|
||||
|
||||
debug!("request: {:?}", request);
|
||||
counter!(GET_USER_TIER_INFO_REQUESTS.name, "service" => "grpc").increment(1);
|
||||
|
||||
|
||||
@@ -38,12 +38,12 @@ use crate::proof_service::ProofService;
|
||||
use crate::registry_listener::RegistryListener;
|
||||
use crate::tier::TierLimits;
|
||||
use crate::tiers_listener::TiersListener;
|
||||
use crate::user_db_error::RegisterError;
|
||||
use crate::user_db_service::UserDbService;
|
||||
use crate::user_db_types::RateLimit;
|
||||
use rln_proof::RlnIdentifier;
|
||||
use smart_contract::KarmaTiersSC::KarmaTiersSCInstance;
|
||||
use smart_contract::TIER_LIMITS;
|
||||
use crate::user_db_error::RegisterError;
|
||||
|
||||
const RLN_IDENTIFIER_NAME: &[u8] = b"test-rln-identifier";
|
||||
const PROVER_SPAM_LIMIT: RateLimit = RateLimit::new(10_000u64);
|
||||
@@ -54,7 +54,6 @@ const PROVER_MINIMAL_AMOUNT_FOR_REGISTRATION: U256 =
|
||||
pub async fn run_prover(
|
||||
app_args: AppArgs,
|
||||
) -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
|
||||
|
||||
// Epoch
|
||||
let epoch_service = EpochService::try_from((Duration::from_secs(60 * 2), GENESIS))
|
||||
.expect("Failed to create epoch service");
|
||||
@@ -92,7 +91,6 @@ pub async fn run_prover(
|
||||
let mock_users = read_mock_user(user_filepath)?;
|
||||
debug!("Mock - will register {} users", mock_users.len());
|
||||
for mock_user in mock_users {
|
||||
|
||||
debug!(
|
||||
"Registering user address: {} - tx count: {}",
|
||||
mock_user.address, mock_user.tx_count
|
||||
@@ -103,14 +101,13 @@ pub async fn run_prover(
|
||||
match e {
|
||||
RegisterError::AlreadyRegistered(_) => {
|
||||
debug!("User {} already registered", mock_user.address);
|
||||
},
|
||||
}
|
||||
_ => {
|
||||
return Err(Box::new(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
user_db
|
||||
.on_new_tx(&mock_user.address, Some(mock_user.tx_count))?;
|
||||
user_db.on_new_tx(&mock_user.address, Some(mock_user.tx_count))?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use std::net::{IpAddr, SocketAddr};
|
||||
use metrics::gauge;
|
||||
use std::net::{IpAddr, SocketAddr};
|
||||
// third-party
|
||||
use metrics_exporter_prometheus::PrometheusBuilder;
|
||||
// use metrics_util::MetricKindMask;
|
||||
@@ -49,7 +49,7 @@ pub const EPOCH_SERVICE_DRIFT_MILLIS: Metric = Metric {
|
||||
|
||||
pub const PROOF_SERVICE_GEN_PROOF_TIME: Metric = Metric {
|
||||
name: "proof_service_gen_proof_time",
|
||||
description: "Generation time of a proof in milliseconds",
|
||||
description: "Generation time of a proof in seconds",
|
||||
};
|
||||
|
||||
pub const GET_PROOFS_LISTENERS: Metric = Metric {
|
||||
@@ -61,7 +61,7 @@ pub const COUNTERS: [Metric; 4] = [
|
||||
USER_REGISTERED,
|
||||
USER_REGISTERED_REQUESTS,
|
||||
SEND_TRANSACTION_REQUESTS,
|
||||
GET_USER_TIER_INFO_REQUESTS
|
||||
GET_USER_TIER_INFO_REQUESTS,
|
||||
];
|
||||
pub const GAUGES: [Metric; 3] = [
|
||||
EPOCH_SERVICE_CURRENT_EPOCH,
|
||||
@@ -118,8 +118,8 @@ fn register_histogram(metric: Metric) {
|
||||
let _histogram = ::metrics::histogram!(metric.name);
|
||||
}
|
||||
|
||||
/// A Wrapper around a metric gauge
|
||||
///
|
||||
/// A Wrapper around a metric gauge
|
||||
///
|
||||
/// Increment the given metric gauge on a new and decrement on drop
|
||||
/// Useful in a closure (or an async closure)
|
||||
pub struct GaugeWrapper {
|
||||
@@ -129,7 +129,11 @@ pub struct GaugeWrapper {
|
||||
}
|
||||
|
||||
impl GaugeWrapper {
|
||||
pub fn new(gauge_name: &'static str, gauge_app: &'static str, gauge_label: &'static str) -> Self {
|
||||
pub fn new(
|
||||
gauge_name: &'static str,
|
||||
gauge_app: &'static str,
|
||||
gauge_label: &'static str,
|
||||
) -> Self {
|
||||
gauge!(gauge_name, gauge_app => gauge_label).increment(1.0);
|
||||
Self {
|
||||
gauge_name,
|
||||
@@ -143,4 +147,4 @@ impl Drop for GaugeWrapper {
|
||||
fn drop(&mut self) {
|
||||
gauge!(self.gauge_name, self.gauge_app => self.gauge_label).decrement(1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,15 +8,15 @@ use metrics::histogram;
|
||||
use parking_lot::RwLock;
|
||||
use rln::hashers::hash_to_field;
|
||||
use rln::protocol::serialize_proof_values;
|
||||
use tracing::{debug, info};
|
||||
use tracing::{Instrument, debug, debug_span, info};
|
||||
// internal
|
||||
use crate::epoch_service::{Epoch, EpochSlice};
|
||||
use crate::error::{AppError, ProofGenerationError, ProofGenerationStringError};
|
||||
use crate::metrics::PROOF_SERVICE_GEN_PROOF_TIME;
|
||||
use crate::proof_generation::{ProofGenerationData, ProofSendingData};
|
||||
use crate::user_db::UserDb;
|
||||
use crate::user_db_types::RateLimit;
|
||||
use rln_proof::{RlnData, compute_rln_proof_and_values};
|
||||
use crate::metrics::PROOF_SERVICE_GEN_PROOF_TIME;
|
||||
|
||||
const PROOF_SIZE: usize = 512;
|
||||
|
||||
@@ -51,7 +51,6 @@ impl ProofService {
|
||||
}
|
||||
|
||||
pub(crate) async fn serve(&self) -> Result<(), AppError> {
|
||||
|
||||
loop {
|
||||
let received = self.receiver.recv().await;
|
||||
|
||||
@@ -69,7 +68,6 @@ impl ProofService {
|
||||
|
||||
// Move to a task (as generating the proof can take quite some time)
|
||||
let blocking_task = tokio::task::spawn_blocking(move || {
|
||||
|
||||
let proof_generation_start = std::time::Instant::now();
|
||||
|
||||
let message_id = {
|
||||
@@ -124,7 +122,7 @@ impl ProofService {
|
||||
Ok::<Vec<u8>, ProofGenerationError>(output_buffer.into_inner())
|
||||
});
|
||||
|
||||
let result = blocking_task.await;
|
||||
let result = blocking_task.instrument(debug_span!("compute proof")).await;
|
||||
// Result (1st) is a JoinError (and should not happen)
|
||||
// Result (2nd) is a ProofGenerationError
|
||||
let result = result.unwrap(); // Should never happen (but should panic if it does)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::epoch_service::{Epoch, EpochSlice};
|
||||
use claims::debug_assert_ge;
|
||||
// use claims::debug_assert_ge;
|
||||
use nom::{
|
||||
IResult,
|
||||
error::ContextError,
|
||||
|
||||
@@ -11,5 +11,11 @@ tracing = "0.1.41"
|
||||
toml = "0.8"
|
||||
prover = { path = "../prover" }
|
||||
|
||||
opentelemetry = { version = "0.30", default-features = false, features = ["trace"]}
|
||||
opentelemetry_sdk = { version = "0.30", features = ["rt-tokio"] }
|
||||
opentelemetry-otlp = { version = "0.30", features = ["grpc-tonic", "reqwest-client", "reqwest-rustls", "http-proto", "tls", "tls-roots"]}
|
||||
tracing-opentelemetry = "0.31"
|
||||
|
||||
|
||||
[dev-dependencies]
|
||||
tracing-test = "0.2.5"
|
||||
|
||||
@@ -8,20 +8,41 @@ use tracing::{
|
||||
// error,
|
||||
// info
|
||||
};
|
||||
use tracing_subscriber::{EnvFilter, fmt, layer::SubscriberExt, util::SubscriberInitExt};
|
||||
use tracing_subscriber::{EnvFilter, layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
||||
use opentelemetry::trace::TracerProvider;
|
||||
use opentelemetry_otlp::WithTonicConfig;
|
||||
use opentelemetry_sdk::Resource;
|
||||
// internal
|
||||
use prover::{AppArgs, AppArgsConfig, metrics::init_metrics, run_prover};
|
||||
|
||||
const APP_NAME: &str = "prover-cli";
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
|
||||
// debug!("Args: {:?}", std::env::args());
|
||||
|
||||
// tracing
|
||||
let filter = EnvFilter::builder()
|
||||
.with_default_directive(LevelFilter::INFO.into())
|
||||
.from_env_lossy();
|
||||
.from_env_lossy()
|
||||
// TODO: Add a way to disable this for maximum log?
|
||||
.add_directive("h2=error".parse()?)
|
||||
.add_directive("sled::pagecache=error".parse()?)
|
||||
.add_directive("opentelemetry_sdk=error".parse()?);
|
||||
|
||||
let fmt_layer = tracing_subscriber::fmt::layer();
|
||||
|
||||
let telemetry_layer = match create_otlp_tracer_provider() {
|
||||
Some(tracer_provider) => {
|
||||
let tracer = tracer_provider.tracer(APP_NAME);
|
||||
Some(tracing_opentelemetry::OpenTelemetryLayer::new(tracer))
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
|
||||
tracing_subscriber::registry()
|
||||
.with(fmt::layer())
|
||||
.with(fmt_layer)
|
||||
.with(filter)
|
||||
.with(telemetry_layer)
|
||||
.init();
|
||||
|
||||
// let app_args = AppArgs::parse();
|
||||
@@ -60,3 +81,46 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>
|
||||
|
||||
run_prover(app_args).await
|
||||
}
|
||||
|
||||
fn create_otlp_tracer_provider() -> Option<opentelemetry_sdk::trace::SdkTracerProvider> {
|
||||
if !std::env::vars().any(|(name, _)| name.starts_with("OTEL_")) {
|
||||
return None;
|
||||
}
|
||||
let protocol = std::env::var("OTEL_EXPORTER_OTLP_PROTOCOL").unwrap_or("grpc".to_string());
|
||||
|
||||
let exporter = match protocol.as_str() {
|
||||
"grpc" => {
|
||||
// Note - Performance:
|
||||
// https://docs.rs/opentelemetry-otlp/latest/opentelemetry_otlp/index.html#performance
|
||||
let mut exporter = opentelemetry_otlp::SpanExporter::builder()
|
||||
.with_tonic()
|
||||
//.with_endpoint(...)
|
||||
;
|
||||
|
||||
// Check if we need TLS
|
||||
if let Ok(endpoint) = std::env::var("OTEL_EXPORTER_OTLP_ENDPOINT") {
|
||||
if endpoint.starts_with("https") {
|
||||
exporter = exporter.with_tls_config(
|
||||
opentelemetry_otlp::tonic_types::transport::ClientTlsConfig::default()
|
||||
.with_enabled_roots(),
|
||||
);
|
||||
}
|
||||
}
|
||||
exporter.build().expect("Failed to create tonic exporter")
|
||||
}
|
||||
"http/protobuf" => opentelemetry_otlp::SpanExporter::builder()
|
||||
.with_http()
|
||||
.build()
|
||||
.expect("Failed to create http/protobuf exporter"),
|
||||
p => panic!("Unsupported protocol {p}"),
|
||||
};
|
||||
|
||||
let resource = Resource::builder().with_service_name(APP_NAME).build();
|
||||
|
||||
Some(
|
||||
opentelemetry_sdk::trace::SdkTracerProvider::builder()
|
||||
.with_resource(resource)
|
||||
.with_batch_exporter(exporter)
|
||||
.build(),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -9,7 +9,9 @@ tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
|
||||
# TODO: workspace?
|
||||
tonic = "0.13.1"
|
||||
prost = "0.13"
|
||||
clap = { version = "4.5.40", features = ["derive", "wrap_help"] }
|
||||
alloy.workspace = true
|
||||
sha2 = "0.10"
|
||||
|
||||
[build-dependencies]
|
||||
tonic-build = "*"
|
||||
|
||||
@@ -1,40 +1,139 @@
|
||||
use alloy::primitives::Address;
|
||||
use std::str::FromStr;
|
||||
use alloy::primitives::{Address, U256};
|
||||
use clap::{Args, Parser, Subcommand};
|
||||
use sha2::Digest;
|
||||
use std::net::IpAddr;
|
||||
use tonic::Response;
|
||||
|
||||
pub mod prover_proto {
|
||||
|
||||
// Include generated code (see build.rs)
|
||||
tonic::include_proto!("prover");
|
||||
}
|
||||
|
||||
use crate::prover_proto::{GetUserTierInfoReply, GetUserTierInfoRequest, RegistrationStatus};
|
||||
use prover_proto::{
|
||||
Address as GrpcAddress, RegisterUserReply, RegisterUserRequest,
|
||||
Address as GrpcAddress,
|
||||
RegisterUserReply,
|
||||
RegisterUserRequest,
|
||||
SendTransactionReply,
|
||||
SendTransactionRequest,
|
||||
U256 as GrpcU256,
|
||||
Wei as GrpcWei,
|
||||
// RegistrationStatus,
|
||||
rln_prover_client::RlnProverClient,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Parser)]
|
||||
#[command(about = "RLN prover client", long_about = None)]
|
||||
pub struct AppArgs {
|
||||
#[arg(short = 'i', long = "ip", default_value = "::1", help = "Service ip")]
|
||||
pub ip: IpAddr,
|
||||
#[arg(
|
||||
short = 'p',
|
||||
long = "port",
|
||||
default_value = "50051",
|
||||
help = "Service port"
|
||||
)]
|
||||
pub port: u16,
|
||||
#[arg(
|
||||
short = 'a',
|
||||
long = "address",
|
||||
default_value = "0xb20a608c624Ca5003905aA834De7156C68b2E1d0",
|
||||
help = "User address"
|
||||
)]
|
||||
pub address: Address,
|
||||
#[command(subcommand)]
|
||||
command: Commands,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Subcommand)]
|
||||
pub(crate) enum Commands {
|
||||
#[command(about = "Register a new user")]
|
||||
RegisterUser, // (RegisterUserArgs),
|
||||
#[command(about = "Send a transaction")]
|
||||
SendTransaction(SendTransactionArgs),
|
||||
#[command(about = "Get user tier info")]
|
||||
GetUserTierInfo,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Args)]
|
||||
pub struct SendTransactionArgs {
|
||||
#[arg(short = 'c', long = "chain-id", help = "Chain id", default_value = "1")]
|
||||
chain_id: U256,
|
||||
#[arg(short = 'w', long = "wei", help = "Tx fee", default_value = "1000")]
|
||||
wei: U256,
|
||||
#[arg(short = 't', long = "tx-hash", help = "Tx hash", default_value = "foo")]
|
||||
tx_hash: String,
|
||||
#[arg(
|
||||
long = "invalid-tx-hash",
|
||||
default_missing_value = "false",
|
||||
help = "Send an invalid tx hash"
|
||||
)]
|
||||
invalid_hash: bool,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
// FIXME: clap
|
||||
let url = "http://127.0.0.1:42942";
|
||||
let addr = "0xb20a608c624Ca5003905aA834De7156C68b2E1d0";
|
||||
|
||||
let addr = Address::from_str(addr).unwrap();
|
||||
|
||||
let grpc_addr = GrpcAddress {
|
||||
value: addr.to_vec(),
|
||||
};
|
||||
let app_args = AppArgs::parse();
|
||||
|
||||
let url = format!("http://{}:{}", app_args.ip, app_args.port);
|
||||
println!("url: {url}");
|
||||
let mut client = RlnProverClient::connect(url).await.unwrap();
|
||||
let request_0 = RegisterUserRequest {
|
||||
user: Some(grpc_addr),
|
||||
let grpc_addr = GrpcAddress {
|
||||
value: app_args.address.to_vec(),
|
||||
};
|
||||
let request = tonic::Request::new(request_0);
|
||||
let response: Response<RegisterUserReply> = client.register_user(request).await.unwrap();
|
||||
|
||||
println!(
|
||||
"RegisterUSerReply status: {:?}",
|
||||
response.into_inner().status
|
||||
);
|
||||
match app_args.command {
|
||||
Commands::RegisterUser => {
|
||||
let request_0 = RegisterUserRequest {
|
||||
user: Some(grpc_addr),
|
||||
};
|
||||
let request = tonic::Request::new(request_0);
|
||||
let response: Response<RegisterUserReply> =
|
||||
client.register_user(request).await.unwrap();
|
||||
|
||||
println!(
|
||||
"RegisterUSerReply status: {:?}",
|
||||
RegistrationStatus::try_from(response.into_inner().status)
|
||||
);
|
||||
}
|
||||
Commands::SendTransaction(send_transaction_args) => {
|
||||
let chain_id = GrpcU256 {
|
||||
// FIXME: LE or BE?
|
||||
value: send_transaction_args.chain_id.to_le_bytes::<32>().to_vec(),
|
||||
};
|
||||
let wei = GrpcWei {
|
||||
// FIXME: LE or BE?
|
||||
value: send_transaction_args.wei.to_le_bytes::<32>().to_vec(),
|
||||
};
|
||||
|
||||
let tx_hash = if send_transaction_args.invalid_hash {
|
||||
vec![]
|
||||
} else {
|
||||
// U256::from(42).to_le_bytes::<32>().to_vec()
|
||||
sha2::Sha256::digest(send_transaction_args.tx_hash).to_vec()
|
||||
};
|
||||
|
||||
let request_0 = SendTransactionRequest {
|
||||
gas_price: Some(wei),
|
||||
sender: Some(grpc_addr),
|
||||
chain_id: Some(chain_id),
|
||||
transaction_hash: tx_hash,
|
||||
};
|
||||
let request = tonic::Request::new(request_0);
|
||||
let response: Response<SendTransactionReply> =
|
||||
client.send_transaction(request).await.unwrap();
|
||||
|
||||
println!("SendTransactionReply status: {:?}", response.into_inner());
|
||||
}
|
||||
Commands::GetUserTierInfo => {
|
||||
let request_0 = GetUserTierInfoRequest {
|
||||
user: Some(grpc_addr),
|
||||
};
|
||||
let request = tonic::Request::new(request_0);
|
||||
let response: Response<GetUserTierInfoReply> =
|
||||
client.get_user_tier_info(request).await.unwrap();
|
||||
|
||||
println!("GetUserTierInfoReply: {:?}", response.into_inner());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user