mirror of
https://github.com/vacp2p/status-rln-prover.git
synced 2026-01-08 21:18:05 -05:00
Initial code to use Zerokit 0.9 + disable parallel feature (#36)
* Initial code to use Zerokit 0.9 + disable parallel feature * Support IdSecret for user identity secret hash * Fix clippy + bench * Use PmTreeConfig builder * Improve prover_bench perf * Fix prover_bench 2nd assert * Fix prover_bench 2nd assert 2 * Can now enable trace for bench prover_bench * Use anyhow for error handling (+ error context) in prover_cli (#42) * Use anyhow for error handling (+ error context) in prover_cli * Cargo fmt pass * Feature/feature/init user db ser de 2 (#45) * Add user db serializer && deserializer init & re-use
This commit is contained in:
25
Cargo.lock
generated
25
Cargo.lock
generated
@@ -850,7 +850,6 @@ dependencies = [
|
|||||||
"digest 0.10.7",
|
"digest 0.10.7",
|
||||||
"fnv",
|
"fnv",
|
||||||
"merlin",
|
"merlin",
|
||||||
"rayon",
|
|
||||||
"sha2",
|
"sha2",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -883,7 +882,6 @@ dependencies = [
|
|||||||
"num-bigint",
|
"num-bigint",
|
||||||
"num-integer",
|
"num-integer",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"rayon",
|
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -942,7 +940,6 @@ dependencies = [
|
|||||||
"num-bigint",
|
"num-bigint",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"paste",
|
"paste",
|
||||||
"rayon",
|
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1027,7 +1024,6 @@ dependencies = [
|
|||||||
"ark-relations",
|
"ark-relations",
|
||||||
"ark-serialize 0.5.0",
|
"ark-serialize 0.5.0",
|
||||||
"ark-std 0.5.0",
|
"ark-std 0.5.0",
|
||||||
"rayon",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1043,7 +1039,6 @@ dependencies = [
|
|||||||
"educe",
|
"educe",
|
||||||
"fnv",
|
"fnv",
|
||||||
"hashbrown 0.15.5",
|
"hashbrown 0.15.5",
|
||||||
"rayon",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1107,7 +1102,6 @@ dependencies = [
|
|||||||
"arrayvec",
|
"arrayvec",
|
||||||
"digest 0.10.7",
|
"digest 0.10.7",
|
||||||
"num-bigint",
|
"num-bigint",
|
||||||
"rayon",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1161,7 +1155,6 @@ checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
"rayon",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3937,6 +3930,7 @@ dependencies = [
|
|||||||
"derive_more",
|
"derive_more",
|
||||||
"futures",
|
"futures",
|
||||||
"http",
|
"http",
|
||||||
|
"lazy_static",
|
||||||
"metrics",
|
"metrics",
|
||||||
"metrics-exporter-prometheus",
|
"metrics-exporter-prometheus",
|
||||||
"metrics-util",
|
"metrics-util",
|
||||||
@@ -3973,6 +3967,7 @@ dependencies = [
|
|||||||
name = "prover_cli"
|
name = "prover_cli"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
"opentelemetry",
|
"opentelemetry",
|
||||||
"opentelemetry-otlp",
|
"opentelemetry-otlp",
|
||||||
@@ -4388,8 +4383,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "rln"
|
name = "rln"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/vacp2p/zerokit/#0b00c639a059a2cfde74bcf68fdf75db3b6898a4"
|
||||||
checksum = "9a03834bc168adfee6f49c885fabb0ad6897be11d97258e9375d98f30d2c9878"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ark-bn254",
|
"ark-bn254",
|
||||||
"ark-ec",
|
"ark-ec",
|
||||||
@@ -4405,14 +4399,16 @@ dependencies = [
|
|||||||
"num-bigint",
|
"num-bigint",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"prost 0.13.5",
|
"prost 0.14.1",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
"rand_chacha 0.3.1",
|
"rand_chacha 0.3.1",
|
||||||
"ruint",
|
"ruint",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"tempfile",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tiny-keccak",
|
"tiny-keccak",
|
||||||
|
"zeroize",
|
||||||
"zerokit_utils",
|
"zerokit_utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -5125,15 +5121,15 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tempfile"
|
name = "tempfile"
|
||||||
version = "3.20.0"
|
version = "3.21.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1"
|
checksum = "15b61f8f20e3a6f7e0649d825294eaf317edce30f82cf6026e7e4cb9222a7d1e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fastrand",
|
"fastrand",
|
||||||
"getrandom 0.3.3",
|
"getrandom 0.3.3",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rustix 1.0.8",
|
"rustix 1.0.8",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.60.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -6388,8 +6384,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "zerokit_utils"
|
name = "zerokit_utils"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/vacp2p/zerokit/#0b00c639a059a2cfde74bcf68fdf75db3b6898a4"
|
||||||
checksum = "a21d5ee8dd5cba6c9e39c7391e3fe968d479b6f1eb51c82556b2bb9b2924f572"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ark-ff 0.5.0",
|
"ark-ff 0.5.0",
|
||||||
"hex",
|
"hex",
|
||||||
|
|||||||
16
Cargo.toml
16
Cargo.toml
@@ -9,13 +9,19 @@ members = [
|
|||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
rln = { version = "0.8.0", features = ["pmtree-ft"] }
|
# rln = { version = "0.8.0", features = ["pmtree-ft"] }
|
||||||
zerokit_utils = { version = "0.6.0", features = ["pmtree-ft"] }
|
rln = { git = "https://github.com/vacp2p/zerokit/", default-features = false, features = ["pmtree-ft"] }
|
||||||
|
# zerokit_utils = { version = "0.6.0", features = ["pmtree-ft"] }
|
||||||
|
zerokit_utils = { git = "https://github.com/vacp2p/zerokit/", default-features = false, features = ["pmtree-ft"] }
|
||||||
|
|
||||||
ark-bn254 = { version = "0.5.0", features = ["std"] }
|
ark-bn254 = { version = "0.5.0", features = ["std"] }
|
||||||
ark-relations = { version = "0.5.1", features = ["std"] }
|
ark-relations = { version = "0.5.1", features = ["std"] }
|
||||||
ark-ff = { version = "0.5.0", features = ["parallel"] }
|
# ark-ff = { version = "0.5.0", features = ["parallel"] }
|
||||||
ark-groth16 = { version = "0.5.0", features = ["parallel"] }
|
ark-ff = { version = "0.5.0", features = ["asm"] }
|
||||||
ark-serialize = { version = "0.5.0", features = ["parallel"] }
|
# ark-groth16 = { version = "0.5.0", features = ["parallel"] }
|
||||||
|
ark-groth16 = { version = "0.5.0", default-features = false, features = [] }
|
||||||
|
# ark-serialize = { version = "0.5.0", features = ["parallel"] }
|
||||||
|
ark-serialize = { version = "0.5.0", default-features = false, features = [] }
|
||||||
tokio = { version = "1.47.1", features = ["macros", "rt-multi-thread"] }
|
tokio = { version = "1.47.1", features = ["macros", "rt-multi-thread"] }
|
||||||
clap = { version = "4.5.46", features = ["derive", "wrap_help"] }
|
clap = { version = "4.5.46", features = ["derive", "wrap_help"] }
|
||||||
url = { version = "2.5.7", features = ["serde"] }
|
url = { version = "2.5.7", features = ["serde"] }
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ clap_config = "0.1"
|
|||||||
metrics = "0.24"
|
metrics = "0.24"
|
||||||
metrics-exporter-prometheus = "0.17"
|
metrics-exporter-prometheus = "0.17"
|
||||||
metrics-util = "0.20"
|
metrics-util = "0.20"
|
||||||
rayon = "1.7"
|
rayon = "1.10"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
tonic-prost-build.workspace = true
|
tonic-prost-build.workspace = true
|
||||||
@@ -52,8 +52,9 @@ tonic-prost-build.workspace = true
|
|||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
criterion.workspace = true
|
criterion.workspace = true
|
||||||
ark-groth16.workspace = true
|
ark-groth16.workspace = true
|
||||||
tempfile = "3.20"
|
tempfile = "3.21"
|
||||||
tracing-test = "0.2.5"
|
tracing-test = "0.2.5"
|
||||||
|
lazy_static = "1.5.0"
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "prover_bench"
|
name = "prover_bench"
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ use std::time::Duration;
|
|||||||
// third-party
|
// third-party
|
||||||
use alloy::primitives::{Address, U256};
|
use alloy::primitives::{Address, U256};
|
||||||
use futures::FutureExt;
|
use futures::FutureExt;
|
||||||
use parking_lot::RwLock;
|
|
||||||
use tempfile::NamedTempFile;
|
use tempfile::NamedTempFile;
|
||||||
use tokio::sync::Notify;
|
use tokio::sync::Notify;
|
||||||
use tokio::task::JoinSet;
|
use tokio::task::JoinSet;
|
||||||
@@ -29,6 +28,29 @@ use prover_proto::{
|
|||||||
SendTransactionRequest, U256 as GrpcU256, Wei as GrpcWei, rln_prover_client::RlnProverClient,
|
SendTransactionRequest, U256 as GrpcU256, Wei as GrpcWei, rln_prover_client::RlnProverClient,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use std::sync::Once;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref TRACING_INIT: Once = Once::new();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn setup_tracing() {
|
||||||
|
TRACING_INIT.call_once(|| {
|
||||||
|
let filter = tracing_subscriber::EnvFilter::from_default_env()
|
||||||
|
.add_directive("h2=error".parse().unwrap())
|
||||||
|
.add_directive("sled::pagecache=error".parse().unwrap())
|
||||||
|
.add_directive("opentelemetry_sdk=error".parse().unwrap());
|
||||||
|
|
||||||
|
tracing_subscriber::fmt()
|
||||||
|
.with_env_filter(filter)
|
||||||
|
.with_line_number(true)
|
||||||
|
.with_file(true)
|
||||||
|
.with_span_events(tracing_subscriber::fmt::format::FmtSpan::CLOSE)
|
||||||
|
.init();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async fn proof_sender(port: u16, addresses: Vec<Address>, proof_count: usize) {
|
async fn proof_sender(port: u16, addresses: Vec<Address>, proof_count: usize) {
|
||||||
let chain_id = GrpcU256 {
|
let chain_id = GrpcU256 {
|
||||||
// FIXME: LE or BE?
|
// FIXME: LE or BE?
|
||||||
@@ -59,12 +81,15 @@ async fn proof_sender(port: u16, addresses: Vec<Address>, proof_count: usize) {
|
|||||||
let request = tonic::Request::new(request_0);
|
let request = tonic::Request::new(request_0);
|
||||||
let response: Response<SendTransactionReply> =
|
let response: Response<SendTransactionReply> =
|
||||||
client.send_transaction(request).await.unwrap();
|
client.send_transaction(request).await.unwrap();
|
||||||
|
|
||||||
assert!(response.into_inner().result);
|
assert!(response.into_inner().result);
|
||||||
}
|
}
|
||||||
|
// println!("[proof_sender] returning...");
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn proof_collector(port: u16, proof_count: usize) -> Vec<RlnProofReply> {
|
async fn proof_collector(port: u16, proof_count: usize) -> Option<Vec<RlnProofReply>> {
|
||||||
let result = Arc::new(RwLock::new(Vec::with_capacity(proof_count)));
|
// let result = Arc::new(RwLock::new(Vec::with_capacity(proof_count)));
|
||||||
|
let mut result = Vec::with_capacity(proof_count);
|
||||||
|
|
||||||
let url = format!("http://127.0.0.1:{port}");
|
let url = format!("http://127.0.0.1:{port}");
|
||||||
let mut client = RlnProverClient::connect(url).await.unwrap();
|
let mut client = RlnProverClient::connect(url).await.unwrap();
|
||||||
@@ -74,20 +99,37 @@ async fn proof_collector(port: u16, proof_count: usize) -> Vec<RlnProofReply> {
|
|||||||
let request = tonic::Request::new(request_0);
|
let request = tonic::Request::new(request_0);
|
||||||
let stream_ = client.get_proofs(request).await.unwrap();
|
let stream_ = client.get_proofs(request).await.unwrap();
|
||||||
let mut stream = stream_.into_inner();
|
let mut stream = stream_.into_inner();
|
||||||
let result_2 = result.clone();
|
// let result_2 = result.clone();
|
||||||
let mut proof_received = 0;
|
let mut proof_received = 0;
|
||||||
while let Some(response) = stream.message().await.unwrap() {
|
|
||||||
result_2.write().push(response);
|
loop {
|
||||||
|
let response = stream.message().await;
|
||||||
|
if let Err(_e) = response {
|
||||||
|
// println!("[proof_collector] error: {:?}", _e);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let response = response.unwrap();
|
||||||
|
|
||||||
|
if response.is_none() {
|
||||||
|
// println!("[proof_collector] response is None");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.push(response.unwrap());
|
||||||
proof_received += 1;
|
proof_received += 1;
|
||||||
if proof_received >= proof_count {
|
if proof_received >= proof_count {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::mem::take(&mut *result.write())
|
// println!("[proof_collector] returning after received: {:?} proof replies", result.len());
|
||||||
|
Some(std::mem::take(&mut result))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn proof_generation_bench(c: &mut Criterion) {
|
fn proof_generation_bench(c: &mut Criterion) {
|
||||||
|
// setup_tracing();
|
||||||
|
|
||||||
let rayon_num_threads = std::env::var("RAYON_NUM_THREADS").unwrap_or("".to_string());
|
let rayon_num_threads = std::env::var("RAYON_NUM_THREADS").unwrap_or("".to_string());
|
||||||
let proof_service_count_default = 4;
|
let proof_service_count_default = 4;
|
||||||
let proof_service_count = std::env::var("PROOF_SERVICE_COUNT")
|
let proof_service_count = std::env::var("PROOF_SERVICE_COUNT")
|
||||||
@@ -140,10 +182,10 @@ fn proof_generation_bench(c: &mut Criterion) {
|
|||||||
no_config: true,
|
no_config: true,
|
||||||
metrics_ip: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
|
metrics_ip: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
|
||||||
metrics_port: 30051,
|
metrics_port: 30051,
|
||||||
broadcast_channel_size: 100,
|
broadcast_channel_size: 500,
|
||||||
proof_service_count,
|
proof_service_count,
|
||||||
transaction_channel_size: 100,
|
transaction_channel_size: 500,
|
||||||
proof_sender_channel_size: 100,
|
proof_sender_channel_size: 500,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Tokio notify - wait for some time after spawning run_prover then notify it's ready to accept
|
// Tokio notify - wait for some time after spawning run_prover then notify it's ready to accept
|
||||||
@@ -190,14 +232,20 @@ fn proof_generation_bench(c: &mut Criterion) {
|
|||||||
b.to_async(&rt).iter(|| {
|
b.to_async(&rt).iter(|| {
|
||||||
async {
|
async {
|
||||||
let mut set = JoinSet::new();
|
let mut set = JoinSet::new();
|
||||||
set.spawn(proof_collector(port, proof_count));
|
set.spawn(proof_collector(port, proof_count)); // return Option<Vec<...>>
|
||||||
set.spawn(proof_sender(port, addresses.clone(), proof_count).map(|_r| vec![]));
|
set.spawn(proof_sender(port, addresses.clone(), proof_count).map(|_r| None)); // Map to None
|
||||||
// Wait for proof_sender + proof_collector to complete
|
// Wait for proof_sender + proof_collector to complete
|
||||||
let res = set.join_all().await;
|
let res = set.join_all().await;
|
||||||
// Check proof_sender return an empty vec
|
assert_eq!(res.len(), 2);
|
||||||
assert_eq!(res.iter().filter(|r| r.is_empty()).count(), 1);
|
// Check proof_sender return None
|
||||||
|
assert_eq!(res.iter().filter(|r| r.is_none()).count(), 1);
|
||||||
// Check we receive enough proofs
|
// Check we receive enough proofs
|
||||||
assert_eq!(res.iter().filter(|r| r.len() == proof_count).count(), 1);
|
assert_eq!(
|
||||||
|
res.iter()
|
||||||
|
.filter(|r| { r.as_ref().map(|v| v.len()).unwrap_or(0) == proof_count })
|
||||||
|
.count(),
|
||||||
|
1
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ const ARGS_DEFAULT_PROOF_SERVICE_COUNT: &str = "8";
|
|||||||
///
|
///
|
||||||
/// Used by grpc service to send the transaction to one of the proof services. A too low value could stall
|
/// Used by grpc service to send the transaction to one of the proof services. A too low value could stall
|
||||||
/// the grpc service when it receives a transaction.
|
/// the grpc service when it receives a transaction.
|
||||||
const ARGS_DEFAULT_TRANSACTION_CHANNEL_SIZE: &str = "100";
|
const ARGS_DEFAULT_TRANSACTION_CHANNEL_SIZE: &str = "256";
|
||||||
/// Proof sender channel size
|
/// Proof sender channel size
|
||||||
///
|
///
|
||||||
/// Used by grpc service to send the generated proof to the Verifier. A too low value could stall
|
/// Used by grpc service to send the generated proof to the Verifier. A too low value could stall
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
|
use alloy::signers::local::LocalSignerError;
|
||||||
use alloy::transports::{RpcError, TransportErrorKind};
|
use alloy::transports::{RpcError, TransportErrorKind};
|
||||||
use ark_serialize::SerializationError;
|
use ark_serialize::SerializationError;
|
||||||
use rln::error::ProofError;
|
use rln::error::ProofError;
|
||||||
use smart_contract::{KarmaScError, KarmaTiersError, RlnScError};
|
use smart_contract::{KarmaScError, KarmaTiersError, RlnScError};
|
||||||
// internal
|
// internal
|
||||||
use crate::epoch_service::WaitUntilError;
|
use crate::epoch_service::WaitUntilError;
|
||||||
use crate::user_db_error::{RegisterError, UserMerkleTreeIndexError};
|
use crate::tier::ValidateTierLimitsError;
|
||||||
|
use crate::user_db_error::{
|
||||||
|
RegisterError, TxCounterError, UserDbOpenError, UserMerkleTreeIndexError,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
pub enum AppError {
|
pub enum AppError {
|
||||||
@@ -26,6 +30,16 @@ pub enum AppError {
|
|||||||
KarmaTiersError(#[from] KarmaTiersError),
|
KarmaTiersError(#[from] KarmaTiersError),
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
RlnScError(#[from] RlnScError),
|
RlnScError(#[from] RlnScError),
|
||||||
|
#[error(transparent)]
|
||||||
|
SignerInitError(#[from] LocalSignerError),
|
||||||
|
#[error(transparent)]
|
||||||
|
ValidateTierError(#[from] ValidateTierLimitsError),
|
||||||
|
#[error(transparent)]
|
||||||
|
UserDbOpenError(#[from] UserDbOpenError),
|
||||||
|
#[error(transparent)]
|
||||||
|
MockUserRegisterError(#[from] RegisterError),
|
||||||
|
#[error(transparent)]
|
||||||
|
MockUserTxCounterError(#[from] TxCounterError),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
|
|||||||
@@ -32,15 +32,12 @@ use alloy::providers::{ProviderBuilder, WsConnect};
|
|||||||
use alloy::signers::local::PrivateKeySigner;
|
use alloy::signers::local::PrivateKeySigner;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use tokio::task::JoinSet;
|
use tokio::task::JoinSet;
|
||||||
use tracing::{
|
use tracing::{debug, info};
|
||||||
debug,
|
|
||||||
// error,
|
|
||||||
// info
|
|
||||||
};
|
|
||||||
use zeroize::Zeroizing;
|
use zeroize::Zeroizing;
|
||||||
// internal
|
// internal
|
||||||
pub use crate::args::{AppArgs, AppArgsConfig};
|
pub use crate::args::{AppArgs, AppArgsConfig};
|
||||||
use crate::epoch_service::EpochService;
|
use crate::epoch_service::EpochService;
|
||||||
|
use crate::error::AppError;
|
||||||
use crate::grpc_service::GrpcProverService;
|
use crate::grpc_service::GrpcProverService;
|
||||||
pub use crate::mock::MockUser;
|
pub use crate::mock::MockUser;
|
||||||
use crate::mock::read_mock_user;
|
use crate::mock::read_mock_user;
|
||||||
@@ -61,9 +58,7 @@ const GENESIS: DateTime<Utc> = DateTime::from_timestamp(1431648000, 0).unwrap();
|
|||||||
const PROVER_MINIMAL_AMOUNT_FOR_REGISTRATION: U256 =
|
const PROVER_MINIMAL_AMOUNT_FOR_REGISTRATION: U256 =
|
||||||
U256::from_le_slice(10u64.to_le_bytes().as_slice());
|
U256::from_le_slice(10u64.to_le_bytes().as_slice());
|
||||||
|
|
||||||
pub async fn run_prover(
|
pub async fn run_prover(app_args: AppArgs) -> Result<(), AppError> {
|
||||||
app_args: AppArgs,
|
|
||||||
) -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
|
|
||||||
// Epoch
|
// Epoch
|
||||||
let epoch_service = EpochService::try_from((Duration::from_secs(60 * 2), GENESIS))
|
let epoch_service = EpochService::try_from((Duration::from_secs(60 * 2), GENESIS))
|
||||||
.expect("Failed to create epoch service");
|
.expect("Failed to create epoch service");
|
||||||
@@ -71,10 +66,7 @@ pub async fn run_prover(
|
|||||||
// Alloy provider (Smart contract provider)
|
// Alloy provider (Smart contract provider)
|
||||||
let provider = if app_args.ws_rpc_url.is_some() {
|
let provider = if app_args.ws_rpc_url.is_some() {
|
||||||
let ws = WsConnect::new(app_args.ws_rpc_url.clone().unwrap().as_str());
|
let ws = WsConnect::new(app_args.ws_rpc_url.clone().unwrap().as_str());
|
||||||
let provider = ProviderBuilder::new()
|
let provider = ProviderBuilder::new().connect_ws(ws).await?;
|
||||||
.connect_ws(ws)
|
|
||||||
.await
|
|
||||||
.map_err(KarmaTiersError::RpcTransportError)?;
|
|
||||||
Some(provider)
|
Some(provider)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@@ -146,7 +138,7 @@ pub async fn run_prover(
|
|||||||
debug!("User {} already registered", mock_user.address);
|
debug!("User {} already registered", mock_user.address);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Box::new(e));
|
return Err(AppError::from(e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -155,9 +147,8 @@ pub async fn run_prover(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Smart contract
|
// Smart contract
|
||||||
// FIXME: use provider
|
|
||||||
let registry_listener = if app_args.mock_sc.is_some() {
|
let registry_listener = if app_args.mock_sc.is_some() {
|
||||||
// debug!("No registry listener when mock is enabled");
|
// No registry listener when mock is enabled
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(RegistryListener::new(
|
Some(RegistryListener::new(
|
||||||
@@ -185,7 +176,7 @@ pub async fn run_prover(
|
|||||||
|
|
||||||
let rln_identifier = RlnIdentifier::new(RLN_IDENTIFIER_NAME);
|
let rln_identifier = RlnIdentifier::new(RLN_IDENTIFIER_NAME);
|
||||||
let addr = SocketAddr::new(app_args.ip, app_args.port);
|
let addr = SocketAddr::new(app_args.ip, app_args.port);
|
||||||
debug!("Listening on: {}", addr);
|
info!("Listening on: {}", addr);
|
||||||
let prover_grpc_service = {
|
let prover_grpc_service = {
|
||||||
let mut service = GrpcProverService {
|
let mut service = GrpcProverService {
|
||||||
proof_sender,
|
proof_sender,
|
||||||
@@ -242,11 +233,17 @@ pub async fn run_prover(
|
|||||||
if app_args.ws_rpc_url.is_some() {
|
if app_args.ws_rpc_url.is_some() {
|
||||||
set.spawn(async move { prover_grpc_service.serve().await });
|
set.spawn(async move { prover_grpc_service.serve().await });
|
||||||
} else {
|
} else {
|
||||||
debug!("Grpc service started with mocked smart contracts");
|
info!("Grpc service started with mocked smart contracts");
|
||||||
set.spawn(async move { prover_grpc_service.serve_with_mock().await });
|
set.spawn(async move { prover_grpc_service.serve_with_mock().await });
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: handle error
|
let res = set.join_all().await;
|
||||||
let _ = set.join_all().await;
|
// Print all errors from services (if any)
|
||||||
|
// We expect that the Prover should never stop unexpectedly, but printing error can help to debug
|
||||||
|
res.iter().for_each(|r| {
|
||||||
|
if r.is_err() {
|
||||||
|
info!("Error: {:?}", r);
|
||||||
|
}
|
||||||
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use ark_serialize::CanonicalSerialize;
|
|||||||
use async_channel::Receiver;
|
use async_channel::Receiver;
|
||||||
use metrics::{counter, histogram};
|
use metrics::{counter, histogram};
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use rln::hashers::hash_to_field;
|
use rln::hashers::hash_to_field_le;
|
||||||
use rln::protocol::serialize_proof_values;
|
use rln::protocol::serialize_proof_values;
|
||||||
use tracing::{
|
use tracing::{
|
||||||
Instrument, // debug,
|
Instrument, // debug,
|
||||||
@@ -101,7 +101,7 @@ impl ProofService {
|
|||||||
|
|
||||||
let rln_data = RlnData {
|
let rln_data = RlnData {
|
||||||
message_id: Fr::from(message_id),
|
message_id: Fr::from(message_id),
|
||||||
data: hash_to_field(proof_generation_data.tx_hash.as_slice()),
|
data: hash_to_field_le(proof_generation_data.tx_hash.as_slice()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let epoch_bytes = {
|
let epoch_bytes = {
|
||||||
@@ -109,7 +109,7 @@ impl ProofService {
|
|||||||
v.extend(current_epoch_slice.to_le_bytes());
|
v.extend(current_epoch_slice.to_le_bytes());
|
||||||
v
|
v
|
||||||
};
|
};
|
||||||
let epoch = hash_to_field(epoch_bytes.as_slice());
|
let epoch = hash_to_field_le(epoch_bytes.as_slice());
|
||||||
|
|
||||||
let merkle_proof = match user_db.get_merkle_proof(&proof_generation_data.tx_sender)
|
let merkle_proof = match user_db.get_merkle_proof(&proof_generation_data.tx_sender)
|
||||||
{
|
{
|
||||||
@@ -159,6 +159,15 @@ impl ProofService {
|
|||||||
let _ = send.send(Ok::<Vec<u8>, ProofGenerationError>(
|
let _ = send.send(Ok::<Vec<u8>, ProofGenerationError>(
|
||||||
output_buffer.into_inner(),
|
output_buffer.into_inner(),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
/*
|
||||||
|
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||||
|
let mut output_buffer = Cursor::new(Vec::with_capacity(PROOF_SIZE));
|
||||||
|
// Send the result back to Tokio.
|
||||||
|
let _ = send.send(Ok::<Vec<u8>, ProofGenerationError>(
|
||||||
|
output_buffer.into_inner(),
|
||||||
|
));
|
||||||
|
*/
|
||||||
});
|
});
|
||||||
|
|
||||||
// Wait for the rayon task.
|
// Wait for the rayon task.
|
||||||
@@ -271,7 +280,7 @@ mod tests {
|
|||||||
debug!("Starting broadcast receiver...");
|
debug!("Starting broadcast receiver...");
|
||||||
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
tokio::time::sleep(std::time::Duration::from_secs(1)).await;
|
||||||
let res =
|
let res =
|
||||||
tokio::time::timeout(std::time::Duration::from_secs(5), broadcast_receiver.recv())
|
tokio::time::timeout(std::time::Duration::from_secs(7), broadcast_receiver.recv())
|
||||||
.await
|
.await
|
||||||
.map_err(|_e| AppErrorExt::Elapsed)?;
|
.map_err(|_e| AppErrorExt::Elapsed)?;
|
||||||
debug!("res: {:?}", res);
|
debug!("res: {:?}", res);
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ mod tests {
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
// third-party
|
// third-party
|
||||||
use alloy::primitives::{Address, address};
|
use alloy::primitives::{Address, address};
|
||||||
use ark_bn254::Fr;
|
|
||||||
use ark_groth16::{Proof as ArkProof, Proof, VerifyingKey};
|
use ark_groth16::{Proof as ArkProof, Proof, VerifyingKey};
|
||||||
use ark_serialize::CanonicalDeserialize;
|
use ark_serialize::CanonicalDeserialize;
|
||||||
use claims::assert_matches;
|
use claims::assert_matches;
|
||||||
@@ -14,6 +13,7 @@ mod tests {
|
|||||||
use rln::circuit::{Curve, zkey_from_folder};
|
use rln::circuit::{Curve, zkey_from_folder};
|
||||||
use rln::error::ComputeIdSecretError;
|
use rln::error::ComputeIdSecretError;
|
||||||
use rln::protocol::{compute_id_secret, deserialize_proof_values, verify_proof};
|
use rln::protocol::{compute_id_secret, deserialize_proof_values, verify_proof};
|
||||||
|
use rln::utils::IdSecret;
|
||||||
use tokio::sync::broadcast;
|
use tokio::sync::broadcast;
|
||||||
use tracing::{debug, info};
|
use tracing::{debug, info};
|
||||||
// internal
|
// internal
|
||||||
@@ -50,7 +50,7 @@ mod tests {
|
|||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
RecoverSecretFailed(ComputeIdSecretError),
|
RecoverSecretFailed(ComputeIdSecretError),
|
||||||
#[error("Recovered secret")]
|
#[error("Recovered secret")]
|
||||||
RecoveredSecret(Fr),
|
RecoveredSecret(IdSecret),
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn proof_sender(
|
async fn proof_sender(
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ impl EpochCounterSerializer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct EpochCounterDeserializer {}
|
pub struct EpochCounterDeserializer {}
|
||||||
|
|
||||||
impl EpochCounterDeserializer {
|
impl EpochCounterDeserializer {
|
||||||
@@ -86,6 +87,7 @@ pub struct EpochIncr {
|
|||||||
pub incr_value: u64,
|
pub incr_value: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct EpochIncrSerializer {}
|
pub struct EpochIncrSerializer {}
|
||||||
|
|
||||||
impl EpochIncrSerializer {
|
impl EpochIncrSerializer {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::str::FromStr;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
// third-party
|
// third-party
|
||||||
use alloy::primitives::{Address, U256};
|
use alloy::primitives::{Address, U256};
|
||||||
@@ -15,8 +14,8 @@ use rln::{
|
|||||||
use rocksdb::{
|
use rocksdb::{
|
||||||
ColumnFamily, ColumnFamilyDescriptor, DB, Options, ReadOptions, WriteBatch, WriteBatchWithIndex,
|
ColumnFamily, ColumnFamilyDescriptor, DB, Options, ReadOptions, WriteBatch, WriteBatchWithIndex,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
use zerokit_utils::Mode::HighThroughput;
|
||||||
use zerokit_utils::{
|
use zerokit_utils::{
|
||||||
error::ZerokitMerkleTreeError,
|
error::ZerokitMerkleTreeError,
|
||||||
pmtree::{PmtreeErrorKind, TreeErrorKind},
|
pmtree::{PmtreeErrorKind, TreeErrorKind},
|
||||||
@@ -62,22 +61,20 @@ pub struct UserTierInfo {
|
|||||||
pub(crate) tier_limit: Option<TierLimit>,
|
pub(crate) tier_limit: Option<TierLimit>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
|
||||||
struct PmTreeConfigJson {
|
|
||||||
path: PathBuf,
|
|
||||||
temporary: bool,
|
|
||||||
cache_capacity: u64,
|
|
||||||
flush_every_ms: u64,
|
|
||||||
mode: String,
|
|
||||||
use_compression: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub(crate) struct UserDb {
|
pub(crate) struct UserDb {
|
||||||
db: Arc<DB>,
|
db: Arc<DB>,
|
||||||
merkle_tree: Arc<RwLock<PoseidonTree>>,
|
merkle_tree: Arc<RwLock<PoseidonTree>>,
|
||||||
rate_limit: RateLimit,
|
rate_limit: RateLimit,
|
||||||
pub(crate) epoch_store: Arc<RwLock<(Epoch, EpochSlice)>>,
|
pub(crate) epoch_store: Arc<RwLock<(Epoch, EpochSlice)>>,
|
||||||
|
rln_identity_serializer: RlnUserIdentitySerializer,
|
||||||
|
rln_identity_deserializer: RlnUserIdentityDeserializer,
|
||||||
|
merkle_index_serializer: MerkleTreeIndexSerializer,
|
||||||
|
merkle_index_deserializer: MerkleTreeIndexDeserializer,
|
||||||
|
epoch_increase_serializer: EpochIncrSerializer,
|
||||||
|
epoch_counter_deserializer: EpochCounterDeserializer,
|
||||||
|
tier_limits_serializer: TierLimitsSerializer,
|
||||||
|
tier_limits_deserializer: TierLimitsDeserializer,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Debug for UserDb {
|
impl std::fmt::Debug for UserDb {
|
||||||
@@ -144,7 +141,10 @@ impl UserDb {
|
|||||||
// merkle tree index
|
// merkle tree index
|
||||||
|
|
||||||
let cf_mtree = db.cf_handle(MERKLE_TREE_COUNTER_CF).unwrap();
|
let cf_mtree = db.cf_handle(MERKLE_TREE_COUNTER_CF).unwrap();
|
||||||
if let Err(e) = Self::get_merkle_tree_index_(db.clone(), cf_mtree) {
|
let merkle_index_deserializer = MerkleTreeIndexDeserializer {};
|
||||||
|
if let Err(e) =
|
||||||
|
Self::get_merkle_tree_index_(db.clone(), cf_mtree, &merkle_index_deserializer)
|
||||||
|
{
|
||||||
match e {
|
match e {
|
||||||
MerkleTreeIndexError::DbUninitialized => {
|
MerkleTreeIndexError::DbUninitialized => {
|
||||||
// Check if the value is already there (e.g. after a restart)
|
// Check if the value is already there (e.g. after a restart)
|
||||||
@@ -156,25 +156,32 @@ impl UserDb {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// merkle tree
|
// merkle tree
|
||||||
|
let tree_config = PmtreeConfig::builder()
|
||||||
|
.path(merkle_tree_path)
|
||||||
|
.temporary(false)
|
||||||
|
.cache_capacity(100_000)
|
||||||
|
.flush_every_ms(12_000)
|
||||||
|
.mode(HighThroughput)
|
||||||
|
.use_compression(false)
|
||||||
|
.build()?;
|
||||||
|
let tree = PoseidonTree::new(MERKLE_TREE_HEIGHT, Default::default(), tree_config)?;
|
||||||
|
|
||||||
let config_ = PmTreeConfigJson {
|
let tier_limits_deserializer = TierLimitsDeserializer {
|
||||||
path: merkle_tree_path,
|
tier_deserializer: TierDeserializer {},
|
||||||
temporary: false,
|
|
||||||
cache_capacity: 100_000,
|
|
||||||
flush_every_ms: 12_000,
|
|
||||||
mode: "HighThroughput".to_string(),
|
|
||||||
use_compression: false,
|
|
||||||
};
|
};
|
||||||
let config_str = serde_json::to_string(&config_)?;
|
|
||||||
// Note: in Zerokit 0.8 this is the only way to initialize a PmTreeConfig
|
|
||||||
let config = PmtreeConfig::from_str(config_str.as_str())?;
|
|
||||||
let tree = PoseidonTree::new(MERKLE_TREE_HEIGHT, Default::default(), config)?;
|
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
db,
|
db,
|
||||||
merkle_tree: Arc::new(RwLock::new(tree)),
|
merkle_tree: Arc::new(RwLock::new(tree)),
|
||||||
rate_limit,
|
rate_limit,
|
||||||
epoch_store,
|
epoch_store,
|
||||||
|
rln_identity_serializer: RlnUserIdentitySerializer {},
|
||||||
|
rln_identity_deserializer: RlnUserIdentityDeserializer {},
|
||||||
|
merkle_index_serializer: MerkleTreeIndexSerializer {},
|
||||||
|
merkle_index_deserializer,
|
||||||
|
epoch_increase_serializer: EpochIncrSerializer {},
|
||||||
|
epoch_counter_deserializer: EpochCounterDeserializer {},
|
||||||
|
tier_limits_serializer,
|
||||||
|
tier_limits_deserializer,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,24 +206,23 @@ impl UserDb {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn register(&self, address: Address) -> Result<Fr, RegisterError> {
|
pub(crate) fn register(&self, address: Address) -> Result<Fr, RegisterError> {
|
||||||
let rln_identity_serializer = RlnUserIdentitySerializer {};
|
|
||||||
let merkle_index_serializer = MerkleTreeIndexSerializer {};
|
|
||||||
let merkle_index_deserializer = MerkleTreeIndexDeserializer {};
|
|
||||||
|
|
||||||
let (identity_secret_hash, id_commitment) = keygen();
|
let (identity_secret_hash, id_commitment) = keygen();
|
||||||
|
|
||||||
let rln_identity = RlnUserIdentity::from((
|
let rln_identity = RlnUserIdentity::from((
|
||||||
identity_secret_hash,
|
|
||||||
id_commitment,
|
id_commitment,
|
||||||
|
identity_secret_hash,
|
||||||
Fr::from(self.rate_limit),
|
Fr::from(self.rate_limit),
|
||||||
));
|
));
|
||||||
|
|
||||||
let key = address.as_slice();
|
let key = address.as_slice();
|
||||||
let mut buffer =
|
let mut buffer = vec![
|
||||||
vec![0; rln_identity_serializer.size_hint() + merkle_index_serializer.size_hint()];
|
0;
|
||||||
|
self.rln_identity_serializer.size_hint()
|
||||||
|
+ self.merkle_index_serializer.size_hint()
|
||||||
|
];
|
||||||
|
|
||||||
// unwrap safe - this is serialized by the Prover + RlnUserIdentitySerializer is unit tested
|
// unwrap safe - this is serialized by the Prover + RlnUserIdentitySerializer is unit tested
|
||||||
rln_identity_serializer
|
self.rln_identity_serializer
|
||||||
.serialize(&rln_identity, &mut buffer)
|
.serialize(&rln_identity, &mut buffer)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -257,7 +263,8 @@ impl UserDb {
|
|||||||
// Increase merkle tree index
|
// Increase merkle tree index
|
||||||
db_batch.merge_cf(cf_mtree, MERKLE_TREE_INDEX_KEY, 1i64.to_le_bytes());
|
db_batch.merge_cf(cf_mtree, MERKLE_TREE_INDEX_KEY, 1i64.to_le_bytes());
|
||||||
// Unwrap safe - serialization is handled by the prover
|
// Unwrap safe - serialization is handled by the prover
|
||||||
let (_, new_index) = merkle_index_deserializer
|
let (_, new_index) = self
|
||||||
|
.merkle_index_deserializer
|
||||||
.deserialize(batch_read.as_slice())
|
.deserialize(batch_read.as_slice())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -281,7 +288,8 @@ impl UserDb {
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Add index for user
|
// Add index for user
|
||||||
merkle_index_serializer.serialize(&new_index, &mut buffer);
|
self.merkle_index_serializer
|
||||||
|
.serialize(&new_index, &mut buffer);
|
||||||
// Put user
|
// Put user
|
||||||
db_batch.put_cf(cf_user, key, buffer.as_slice());
|
db_batch.put_cf(cf_user, key, buffer.as_slice());
|
||||||
// Put user tx counter
|
// Put user tx counter
|
||||||
@@ -311,11 +319,10 @@ impl UserDb {
|
|||||||
|
|
||||||
pub fn get_user(&self, address: &Address) -> Option<RlnUserIdentity> {
|
pub fn get_user(&self, address: &Address) -> Option<RlnUserIdentity> {
|
||||||
let cf_user = self.get_user_cf();
|
let cf_user = self.get_user_cf();
|
||||||
let rln_identity_deserializer = RlnUserIdentityDeserializer {};
|
|
||||||
match self.db.get_pinned_cf(cf_user, address.as_slice()) {
|
match self.db.get_pinned_cf(cf_user, address.as_slice()) {
|
||||||
Ok(Some(value)) => {
|
Ok(Some(value)) => {
|
||||||
// Here we silence the error - this is safe as the prover controls this
|
// Here we silence the error - this is safe as the prover controls this
|
||||||
rln_identity_deserializer.deserialize(&value).ok()
|
self.rln_identity_deserializer.deserialize(&value).ok()
|
||||||
}
|
}
|
||||||
Ok(None) => None,
|
Ok(None) => None,
|
||||||
Err(_e) => None,
|
Err(_e) => None,
|
||||||
@@ -327,13 +334,12 @@ impl UserDb {
|
|||||||
address: &Address,
|
address: &Address,
|
||||||
) -> Result<MerkleTreeIndex, UserMerkleTreeIndexError> {
|
) -> Result<MerkleTreeIndex, UserMerkleTreeIndexError> {
|
||||||
let cf_user = self.get_user_cf();
|
let cf_user = self.get_user_cf();
|
||||||
let rln_identity_serializer = RlnUserIdentitySerializer {};
|
|
||||||
let merkle_tree_index_deserializer = MerkleTreeIndexDeserializer {};
|
|
||||||
match self.db.get_pinned_cf(cf_user, address.as_slice()) {
|
match self.db.get_pinned_cf(cf_user, address.as_slice()) {
|
||||||
Ok(Some(buffer)) => {
|
Ok(Some(buffer)) => {
|
||||||
// Here we silence the error - this is safe as the prover controls this
|
// Here we silence the error - this is safe as the prover controls this
|
||||||
let start = rln_identity_serializer.size_hint();
|
let start = self.rln_identity_serializer.size_hint();
|
||||||
let (_, index) = merkle_tree_index_deserializer
|
let (_, index) = self
|
||||||
|
.merkle_index_deserializer
|
||||||
.deserialize(&buffer[start..])
|
.deserialize(&buffer[start..])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
Ok(index)
|
Ok(index)
|
||||||
@@ -398,9 +404,8 @@ impl UserDb {
|
|||||||
epoch_slice,
|
epoch_slice,
|
||||||
incr_value,
|
incr_value,
|
||||||
};
|
};
|
||||||
let incr_ser = EpochIncrSerializer {};
|
let mut buffer = Vec::with_capacity(self.epoch_increase_serializer.size_hint());
|
||||||
let mut buffer = Vec::with_capacity(incr_ser.size_hint());
|
self.epoch_increase_serializer.serialize(&incr, &mut buffer);
|
||||||
incr_ser.serialize(&incr, &mut buffer);
|
|
||||||
|
|
||||||
// Create a transaction
|
// Create a transaction
|
||||||
// By using a WriteBatchWithIndex, we can "read your own writes" so here we incr then read the new value
|
// By using a WriteBatchWithIndex, we can "read your own writes" so here we incr then read the new value
|
||||||
@@ -435,11 +440,9 @@ impl UserDb {
|
|||||||
address: &Address,
|
address: &Address,
|
||||||
key: Option<Vec<u8>>,
|
key: Option<Vec<u8>>,
|
||||||
) -> Result<(EpochCounter, EpochSliceCounter), TxCounterError> {
|
) -> Result<(EpochCounter, EpochSliceCounter), TxCounterError> {
|
||||||
let deserializer = EpochCounterDeserializer {};
|
|
||||||
|
|
||||||
match key {
|
match key {
|
||||||
Some(value) => {
|
Some(value) => {
|
||||||
let (_, counter) = deserializer.deserialize(&value).unwrap();
|
let (_, counter) = self.epoch_counter_deserializer.deserialize(&value).unwrap();
|
||||||
let (epoch, epoch_slice) = *self.epoch_store.read();
|
let (epoch, epoch_slice) = *self.epoch_store.read();
|
||||||
|
|
||||||
let cmp = (counter.epoch == epoch, counter.epoch_slice == epoch_slice);
|
let cmp = (counter.epoch == epoch, counter.epoch_slice == epoch_slice);
|
||||||
@@ -490,19 +493,20 @@ impl UserDb {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) fn get_merkle_tree_index(&self) -> Result<MerkleTreeIndex, MerkleTreeIndexError> {
|
pub(crate) fn get_merkle_tree_index(&self) -> Result<MerkleTreeIndex, MerkleTreeIndexError> {
|
||||||
let cf_mtree = self.get_mtree_cf();
|
let cf_mtree = self.get_mtree_cf();
|
||||||
Self::get_merkle_tree_index_(self.db.clone(), cf_mtree)
|
Self::get_merkle_tree_index_(self.db.clone(), cf_mtree, &self.merkle_index_deserializer)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_merkle_tree_index_(
|
fn get_merkle_tree_index_(
|
||||||
db: Arc<DB>,
|
db: Arc<DB>,
|
||||||
cf: &ColumnFamily,
|
cf: &ColumnFamily,
|
||||||
|
merkle_tree_index_deserializer: &MerkleTreeIndexDeserializer,
|
||||||
) -> Result<MerkleTreeIndex, MerkleTreeIndexError> {
|
) -> Result<MerkleTreeIndex, MerkleTreeIndexError> {
|
||||||
let deserializer = MerkleTreeIndexDeserializer {};
|
|
||||||
|
|
||||||
match db.get_cf(cf, MERKLE_TREE_INDEX_KEY) {
|
match db.get_cf(cf, MERKLE_TREE_INDEX_KEY) {
|
||||||
Ok(Some(v)) => {
|
Ok(Some(v)) => {
|
||||||
// Unwrap safe - serialization is done by the prover
|
// Unwrap safe - serialization is done by the prover
|
||||||
let (_, index) = deserializer.deserialize(v.as_slice()).unwrap();
|
let (_, index) = merkle_tree_index_deserializer
|
||||||
|
.deserialize(v.as_slice())
|
||||||
|
.unwrap();
|
||||||
Ok(index)
|
Ok(index)
|
||||||
}
|
}
|
||||||
Ok(None) => Err(MerkleTreeIndexError::DbUninitialized),
|
Ok(None) => Err(MerkleTreeIndexError::DbUninitialized),
|
||||||
@@ -541,12 +545,8 @@ impl UserDb {
|
|||||||
let cf = self.get_tier_limits_cf();
|
let cf = self.get_tier_limits_cf();
|
||||||
// Unwrap safe - Db is initialized with valid tier limits
|
// Unwrap safe - Db is initialized with valid tier limits
|
||||||
let buffer = self.db.get_cf(cf, TIER_LIMITS_KEY.as_slice())?.unwrap();
|
let buffer = self.db.get_cf(cf, TIER_LIMITS_KEY.as_slice())?.unwrap();
|
||||||
let tier_limits_deserializer = TierLimitsDeserializer {
|
|
||||||
tier_deserializer: TierDeserializer {},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Unwrap safe - serialized by the prover (should always deserialize)
|
// Unwrap safe - serialized by the prover (should always deserialize)
|
||||||
let (_, tier_limits) = tier_limits_deserializer.deserialize(&buffer).unwrap();
|
let (_, tier_limits) = self.tier_limits_deserializer.deserialize(&buffer).unwrap();
|
||||||
Ok(tier_limits)
|
Ok(tier_limits)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -557,10 +557,10 @@ impl UserDb {
|
|||||||
tier_limits.validate()?;
|
tier_limits.validate()?;
|
||||||
|
|
||||||
// Serialize
|
// Serialize
|
||||||
let tier_limits_serializer = TierLimitsSerializer::default();
|
let mut buffer =
|
||||||
let mut buffer = Vec::with_capacity(tier_limits_serializer.size_hint(tier_limits.len()));
|
Vec::with_capacity(self.tier_limits_serializer.size_hint(tier_limits.len()));
|
||||||
// Unwrap safe - already validated - should always serialize
|
// Unwrap safe - already validated - should always serialize
|
||||||
tier_limits_serializer
|
self.tier_limits_serializer
|
||||||
.serialize(&tier_limits, &mut buffer)
|
.serialize(&tier_limits, &mut buffer)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -798,16 +798,15 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let temp_folder_tree_2 = tempfile::tempdir().unwrap();
|
let temp_folder_tree_2 = tempfile::tempdir().unwrap();
|
||||||
let config_ = PmTreeConfigJson {
|
let config = PmtreeConfig::builder()
|
||||||
path: temp_folder_tree_2.path().to_path_buf(),
|
.path(temp_folder_tree_2.path().to_path_buf())
|
||||||
temporary: false,
|
.temporary(false)
|
||||||
cache_capacity: 100_000,
|
.cache_capacity(100_000)
|
||||||
flush_every_ms: 12_000,
|
.flush_every_ms(12_000)
|
||||||
mode: "HighThroughput".to_string(),
|
.mode(HighThroughput)
|
||||||
use_compression: false,
|
.use_compression(false)
|
||||||
};
|
.build()
|
||||||
let config_str = serde_json::to_string(&config_).unwrap();
|
.unwrap();
|
||||||
let config = PmtreeConfig::from_str(config_str.as_str()).unwrap();
|
|
||||||
let tree = PoseidonTree::new(1, Default::default(), config).unwrap();
|
let tree = PoseidonTree::new(1, Default::default(), config).unwrap();
|
||||||
let tree = Arc::new(RwLock::new(tree));
|
let tree = Arc::new(RwLock::new(tree));
|
||||||
user_db.merkle_tree = tree.clone();
|
user_db.merkle_tree = tree.clone();
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use zerokit_utils::error::{FromConfigError, ZerokitMerkleTreeError};
|
|||||||
use crate::tier::ValidateTierLimitsError;
|
use crate::tier::ValidateTierLimitsError;
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
pub(crate) enum UserDbOpenError {
|
pub enum UserDbOpenError {
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
RocksDb(#[from] rocksdb::Error),
|
RocksDb(#[from] rocksdb::Error),
|
||||||
#[error("Serialization error: {0}")]
|
#[error("Serialization error: {0}")]
|
||||||
|
|||||||
@@ -12,12 +12,14 @@ use nom::{
|
|||||||
multi::length_count,
|
multi::length_count,
|
||||||
number::complete::{le_u32, le_u64},
|
number::complete::{le_u32, le_u64},
|
||||||
};
|
};
|
||||||
|
use rln::utils::IdSecret;
|
||||||
use rln_proof::RlnUserIdentity;
|
use rln_proof::RlnUserIdentity;
|
||||||
// internal
|
// internal
|
||||||
use crate::tier::TierLimits;
|
use crate::tier::TierLimits;
|
||||||
use crate::user_db_types::MerkleTreeIndex;
|
use crate::user_db_types::MerkleTreeIndex;
|
||||||
use smart_contract::Tier;
|
use smart_contract::Tier;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub(crate) struct RlnUserIdentitySerializer {}
|
pub(crate) struct RlnUserIdentitySerializer {}
|
||||||
|
|
||||||
impl RlnUserIdentitySerializer {
|
impl RlnUserIdentitySerializer {
|
||||||
@@ -41,6 +43,7 @@ impl RlnUserIdentitySerializer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub(crate) struct RlnUserIdentityDeserializer {}
|
pub(crate) struct RlnUserIdentityDeserializer {}
|
||||||
|
|
||||||
impl RlnUserIdentityDeserializer {
|
impl RlnUserIdentityDeserializer {
|
||||||
@@ -49,8 +52,8 @@ impl RlnUserIdentityDeserializer {
|
|||||||
let (co_buffer, rem_buffer) = buffer.split_at(compressed_size);
|
let (co_buffer, rem_buffer) = buffer.split_at(compressed_size);
|
||||||
let commitment: Fr = CanonicalDeserialize::deserialize_compressed(co_buffer)?;
|
let commitment: Fr = CanonicalDeserialize::deserialize_compressed(co_buffer)?;
|
||||||
let (secret_buffer, user_limit_buffer) = rem_buffer.split_at(compressed_size);
|
let (secret_buffer, user_limit_buffer) = rem_buffer.split_at(compressed_size);
|
||||||
// TODO: IdSecret (wait for Zerokit PR: https://github.com/vacp2p/zerokit/pull/320)
|
let mut secret_hash_: Fr = CanonicalDeserialize::deserialize_compressed(secret_buffer)?;
|
||||||
let secret_hash: Fr = CanonicalDeserialize::deserialize_compressed(secret_buffer)?;
|
let secret_hash = IdSecret::from(&mut secret_hash_);
|
||||||
let user_limit: Fr = CanonicalDeserialize::deserialize_compressed(user_limit_buffer)?;
|
let user_limit: Fr = CanonicalDeserialize::deserialize_compressed(user_limit_buffer)?;
|
||||||
|
|
||||||
Ok({
|
Ok({
|
||||||
@@ -63,6 +66,7 @@ impl RlnUserIdentityDeserializer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub(crate) struct MerkleTreeIndexSerializer {}
|
pub(crate) struct MerkleTreeIndexSerializer {}
|
||||||
|
|
||||||
impl MerkleTreeIndexSerializer {
|
impl MerkleTreeIndexSerializer {
|
||||||
@@ -77,6 +81,7 @@ impl MerkleTreeIndexSerializer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub(crate) struct MerkleTreeIndexDeserializer {}
|
pub(crate) struct MerkleTreeIndexDeserializer {}
|
||||||
|
|
||||||
impl MerkleTreeIndexDeserializer {
|
impl MerkleTreeIndexDeserializer {
|
||||||
@@ -88,7 +93,7 @@ impl MerkleTreeIndexDeserializer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, Clone)]
|
||||||
pub(crate) struct TierSerializer {}
|
pub(crate) struct TierSerializer {}
|
||||||
|
|
||||||
impl TierSerializer {
|
impl TierSerializer {
|
||||||
@@ -113,7 +118,7 @@ impl TierSerializer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, Clone)]
|
||||||
pub(crate) struct TierDeserializer {}
|
pub(crate) struct TierDeserializer {}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
@@ -166,7 +171,7 @@ impl TierDeserializer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, Clone)]
|
||||||
pub(crate) struct TierLimitsSerializer {
|
pub(crate) struct TierLimitsSerializer {
|
||||||
tier_serializer: TierSerializer,
|
tier_serializer: TierSerializer,
|
||||||
}
|
}
|
||||||
@@ -193,7 +198,7 @@ impl TierLimitsSerializer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default, Clone)]
|
||||||
pub(crate) struct TierLimitsDeserializer {
|
pub(crate) struct TierLimitsDeserializer {
|
||||||
pub(crate) tier_deserializer: TierDeserializer,
|
pub(crate) tier_deserializer: TierDeserializer,
|
||||||
}
|
}
|
||||||
@@ -226,7 +231,7 @@ mod tests {
|
|||||||
fn test_rln_ser_der() {
|
fn test_rln_ser_der() {
|
||||||
let rln_user_identity = RlnUserIdentity {
|
let rln_user_identity = RlnUserIdentity {
|
||||||
commitment: Fr::from(42),
|
commitment: Fr::from(42),
|
||||||
secret_hash: Fr::from(u16::MAX),
|
secret_hash: IdSecret::from(&mut Fr::from(u16::MAX)),
|
||||||
user_limit: Fr::from(1_000_000),
|
user_limit: Fr::from(1_000_000),
|
||||||
};
|
};
|
||||||
let serializer = RlnUserIdentitySerializer {};
|
let serializer = RlnUserIdentitySerializer {};
|
||||||
|
|||||||
@@ -24,3 +24,4 @@ opentelemetry-otlp = { version = "0.30.0", features = [
|
|||||||
"tls-roots",
|
"tls-roots",
|
||||||
] }
|
] }
|
||||||
tracing-opentelemetry = "0.31.0"
|
tracing-opentelemetry = "0.31.0"
|
||||||
|
anyhow = "1.0.99"
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use tracing::{
|
|||||||
};
|
};
|
||||||
use tracing_subscriber::{EnvFilter, layer::SubscriberExt, util::SubscriberInitExt};
|
use tracing_subscriber::{EnvFilter, layer::SubscriberExt, util::SubscriberInitExt};
|
||||||
|
|
||||||
|
use anyhow::{Context, Result, anyhow};
|
||||||
use opentelemetry::trace::TracerProvider;
|
use opentelemetry::trace::TracerProvider;
|
||||||
use opentelemetry_otlp::WithTonicConfig;
|
use opentelemetry_otlp::WithTonicConfig;
|
||||||
use opentelemetry_sdk::Resource;
|
use opentelemetry_sdk::Resource;
|
||||||
@@ -20,7 +21,7 @@ use prover::{AppArgs, AppArgsConfig, metrics::init_metrics, run_prover};
|
|||||||
const APP_NAME: &str = "prover-cli";
|
const APP_NAME: &str = "prover-cli";
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> {
|
async fn main() -> Result<()> {
|
||||||
// install crypto provider for rustls - required for WebSocket TLS connections
|
// install crypto provider for rustls - required for WebSocket TLS connections
|
||||||
rustls::crypto::CryptoProvider::install_default(aws_lc_rs::default_provider())
|
rustls::crypto::CryptoProvider::install_default(aws_lc_rs::default_provider())
|
||||||
.expect("Failed to install default CryptoProvider");
|
.expect("Failed to install default CryptoProvider");
|
||||||
@@ -58,7 +59,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>
|
|||||||
// Unwrap safe - default value provided
|
// Unwrap safe - default value provided
|
||||||
let config_path = app_args.get_one::<PathBuf>("config_path").unwrap();
|
let config_path = app_args.get_one::<PathBuf>("config_path").unwrap();
|
||||||
debug!("Reading config path: {:?}...", config_path);
|
debug!("Reading config path: {:?}...", config_path);
|
||||||
let config_str = std::fs::read_to_string(config_path)?;
|
let config_str = std::fs::read_to_string(config_path)
|
||||||
|
.context(format!("Failed to read config file: {:?}", config_path))?;
|
||||||
let config: AppArgsConfig = toml::from_str(config_str.as_str())?;
|
let config: AppArgsConfig = toml::from_str(config_str.as_str())?;
|
||||||
debug!("Config: {:?}", config);
|
debug!("Config: {:?}", config);
|
||||||
config
|
config
|
||||||
@@ -76,15 +78,17 @@ async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>
|
|||||||
|| app_args.ksc_address.is_none()
|
|| app_args.ksc_address.is_none()
|
||||||
|| app_args.tsc_address.is_none()
|
|| app_args.tsc_address.is_none()
|
||||||
{
|
{
|
||||||
return Err("Please provide smart contract addresses".into());
|
return Err(anyhow!("Please provide smart contract addresses"));
|
||||||
}
|
}
|
||||||
} else if app_args.mock_sc.is_none() {
|
} else if app_args.mock_sc.is_none() {
|
||||||
return Err("Please provide rpc url (--ws-rpc-url) or mock (--mock-sc)".into());
|
return Err(anyhow!(
|
||||||
|
"Please provide rpc url (--ws-rpc-url) or mock (--mock-sc)"
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
init_metrics(app_args.metrics_ip, &app_args.metrics_port);
|
init_metrics(app_args.metrics_ip, &app_args.metrics_port);
|
||||||
|
|
||||||
run_prover(app_args).await
|
run_prover(app_args).await.map_err(anyhow::Error::new)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_otlp_tracer_provider() -> Option<opentelemetry_sdk::trace::SdkTracerProvider> {
|
fn create_otlp_tracer_provider() -> Option<opentelemetry_sdk::trace::SdkTracerProvider> {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use std::hint::black_box;
|
||||||
// std
|
// std
|
||||||
use std::io::{Cursor, Write};
|
use std::io::{Cursor, Write};
|
||||||
// criterion
|
// criterion
|
||||||
@@ -5,7 +6,7 @@ use criterion::{Criterion, criterion_group, criterion_main};
|
|||||||
// third-party
|
// third-party
|
||||||
use ark_bn254::Fr;
|
use ark_bn254::Fr;
|
||||||
use ark_serialize::CanonicalSerialize;
|
use ark_serialize::CanonicalSerialize;
|
||||||
use rln::hashers::{hash_to_field, poseidon_hash};
|
use rln::hashers::{hash_to_field_le, poseidon_hash};
|
||||||
use rln::poseidon_tree::PoseidonTree;
|
use rln::poseidon_tree::PoseidonTree;
|
||||||
use rln::protocol::{keygen, serialize_proof_values};
|
use rln::protocol::{keygen, serialize_proof_values};
|
||||||
// internal
|
// internal
|
||||||
@@ -24,7 +25,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
|
|||||||
let rln_identifier = RlnIdentifier::new(b"test-test");
|
let rln_identifier = RlnIdentifier::new(b"test-test");
|
||||||
let rln_data = RlnData {
|
let rln_data = RlnData {
|
||||||
message_id: Fr::from(user_limit - 2),
|
message_id: Fr::from(user_limit - 2),
|
||||||
data: hash_to_field(b"data-from-message"),
|
data: hash_to_field_le(b"data-from-message"),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Merkle tree
|
// Merkle tree
|
||||||
@@ -35,7 +36,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
|
|||||||
let merkle_proof = tree.proof(0).unwrap();
|
let merkle_proof = tree.proof(0).unwrap();
|
||||||
|
|
||||||
// Epoch
|
// Epoch
|
||||||
let epoch = hash_to_field(b"Today at noon, this year");
|
let epoch = hash_to_field_le(b"Today at noon, this year");
|
||||||
|
|
||||||
{
|
{
|
||||||
// Not a benchmark but print the proof size (serialized)
|
// Not a benchmark but print the proof size (serialized)
|
||||||
@@ -61,17 +62,6 @@ pub fn criterion_benchmark(c: &mut Criterion) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.bench_function("compute proof and values", |b| {
|
c.bench_function("compute proof and values", |b| {
|
||||||
/*
|
|
||||||
b.iter(|| {
|
|
||||||
compute_rln_proof_and_values(
|
|
||||||
&rln_identity,
|
|
||||||
&rln_identifier,
|
|
||||||
rln_data.clone(),
|
|
||||||
epoch,
|
|
||||||
&merkle_proof,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
*/
|
|
||||||
b.iter_batched(
|
b.iter_batched(
|
||||||
|| {
|
|| {
|
||||||
// generate setup data
|
// generate setup data
|
||||||
@@ -80,11 +70,11 @@ pub fn criterion_benchmark(c: &mut Criterion) {
|
|||||||
|data| {
|
|data| {
|
||||||
// function to benchmark
|
// function to benchmark
|
||||||
compute_rln_proof_and_values(
|
compute_rln_proof_and_values(
|
||||||
&rln_identity,
|
black_box(&rln_identity),
|
||||||
&rln_identifier,
|
black_box(&rln_identifier),
|
||||||
data,
|
black_box(data),
|
||||||
epoch,
|
black_box(epoch),
|
||||||
&merkle_proof,
|
black_box(&merkle_proof),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
criterion::BatchSize::SmallInput,
|
criterion::BatchSize::SmallInput,
|
||||||
@@ -96,19 +86,21 @@ pub fn criterion_benchmark(c: &mut Criterion) {
|
|||||||
|| {
|
|| {
|
||||||
// generate setup data
|
// generate setup data
|
||||||
compute_rln_proof_and_values(
|
compute_rln_proof_and_values(
|
||||||
&rln_identity,
|
black_box(&rln_identity),
|
||||||
&rln_identifier,
|
black_box(&rln_identifier),
|
||||||
rln_data.clone(),
|
black_box(rln_data.clone()),
|
||||||
epoch,
|
black_box(epoch),
|
||||||
&merkle_proof,
|
black_box(&merkle_proof),
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
},
|
},
|
||||||
|(proof, proof_values)| {
|
|(proof, proof_values)| {
|
||||||
let mut output_buffer = Cursor::new(Vec::with_capacity(320));
|
let mut output_buffer = Cursor::new(Vec::with_capacity(320));
|
||||||
proof.serialize_compressed(&mut output_buffer).unwrap();
|
proof
|
||||||
|
.serialize_compressed(black_box(&mut output_buffer))
|
||||||
|
.unwrap();
|
||||||
output_buffer
|
output_buffer
|
||||||
.write_all(&serialize_proof_values(&proof_values))
|
.write_all(black_box(&serialize_proof_values(black_box(&proof_values))))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
},
|
},
|
||||||
criterion::BatchSize::SmallInput,
|
criterion::BatchSize::SmallInput,
|
||||||
|
|||||||
@@ -1,29 +1,31 @@
|
|||||||
// std
|
// std
|
||||||
use std::io::Cursor;
|
// use std::io::Cursor;
|
||||||
// third-party
|
// third-party
|
||||||
use ark_bn254::{Bn254, Fr};
|
use ark_bn254::{Bn254, Fr};
|
||||||
use ark_groth16::{Proof, ProvingKey};
|
use ark_groth16::{Proof, ProvingKey};
|
||||||
use ark_relations::r1cs::ConstraintMatrices;
|
use ark_relations::r1cs::ConstraintMatrices;
|
||||||
|
use rln::utils::IdSecret;
|
||||||
use rln::{
|
use rln::{
|
||||||
circuit::{ZKEY_BYTES, zkey::read_zkey},
|
circuit::{ARKZKEY_BYTES, read_arkzkey_from_bytes_uncompressed as read_zkey},
|
||||||
error::ProofError,
|
error::ProofError,
|
||||||
hashers::{hash_to_field, poseidon_hash},
|
hashers::{hash_to_field_le, poseidon_hash},
|
||||||
poseidon_tree::MerkleProof,
|
poseidon_tree::MerkleProof,
|
||||||
protocol::{
|
protocol::{
|
||||||
RLNProofValues, generate_proof, proof_values_from_witness, rln_witness_from_values,
|
RLNProofValues, generate_proof, proof_values_from_witness, rln_witness_from_values,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
use zerokit_utils::ZerokitMerkleProof;
|
||||||
|
|
||||||
/// A RLN user identity & limit
|
/// A RLN user identity & limit
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct RlnUserIdentity {
|
pub struct RlnUserIdentity {
|
||||||
pub commitment: Fr,
|
pub commitment: Fr,
|
||||||
pub secret_hash: Fr,
|
pub secret_hash: IdSecret,
|
||||||
pub user_limit: Fr,
|
pub user_limit: Fr,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<(Fr, Fr, Fr)> for RlnUserIdentity {
|
impl From<(Fr, IdSecret, Fr)> for RlnUserIdentity {
|
||||||
fn from((commitment, secret_hash, user_limit): (Fr, Fr, Fr)) -> Self {
|
fn from((commitment, secret_hash, user_limit): (Fr, IdSecret, Fr)) -> Self {
|
||||||
Self {
|
Self {
|
||||||
commitment,
|
commitment,
|
||||||
secret_hash,
|
secret_hash,
|
||||||
@@ -43,13 +45,13 @@ pub struct RlnIdentifier {
|
|||||||
impl RlnIdentifier {
|
impl RlnIdentifier {
|
||||||
pub fn new(identifier: &[u8]) -> Self {
|
pub fn new(identifier: &[u8]) -> Self {
|
||||||
let pk_and_matrices = {
|
let pk_and_matrices = {
|
||||||
let mut reader = Cursor::new(ZKEY_BYTES);
|
// let mut reader = Cursor::new(ARKZKEY_BYTES);
|
||||||
read_zkey(&mut reader).unwrap()
|
read_zkey(ARKZKEY_BYTES).unwrap()
|
||||||
};
|
};
|
||||||
let graph_bytes = include_bytes!("../resources/graph.bin");
|
let graph_bytes = include_bytes!("../resources/graph.bin");
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
identifier: hash_to_field(identifier),
|
identifier: hash_to_field_le(identifier),
|
||||||
pkey_and_constraints: pk_and_matrices,
|
pkey_and_constraints: pk_and_matrices,
|
||||||
graph: graph_bytes.to_vec(),
|
graph: graph_bytes.to_vec(),
|
||||||
}
|
}
|
||||||
@@ -74,9 +76,15 @@ pub fn compute_rln_proof_and_values(
|
|||||||
) -> Result<(Proof<Bn254>, RLNProofValues), ProofError> {
|
) -> Result<(Proof<Bn254>, RLNProofValues), ProofError> {
|
||||||
let external_nullifier = poseidon_hash(&[rln_identifier.identifier, epoch]);
|
let external_nullifier = poseidon_hash(&[rln_identifier.identifier, epoch]);
|
||||||
|
|
||||||
|
let path_elements = merkle_proof.get_path_elements();
|
||||||
|
let identity_path_index = merkle_proof.get_path_index();
|
||||||
|
|
||||||
|
// let mut id_s = user_identity.secret_hash;
|
||||||
|
|
||||||
let witness = rln_witness_from_values(
|
let witness = rln_witness_from_values(
|
||||||
user_identity.secret_hash,
|
user_identity.secret_hash.clone(),
|
||||||
merkle_proof,
|
path_elements,
|
||||||
|
identity_path_index,
|
||||||
rln_data.data,
|
rln_data.data,
|
||||||
external_nullifier,
|
external_nullifier,
|
||||||
user_identity.user_limit,
|
user_identity.user_limit,
|
||||||
@@ -101,8 +109,9 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_recover_secret_hash() {
|
fn test_recover_secret_hash() {
|
||||||
let (user_co, user_sh) = keygen();
|
let (user_co, mut user_sh_) = keygen();
|
||||||
let epoch = hash_to_field(b"foo");
|
let user_sh = IdSecret::from(&mut user_sh_);
|
||||||
|
let epoch = hash_to_field_le(b"foo");
|
||||||
let spam_limit = Fr::from(10);
|
let spam_limit = Fr::from(10);
|
||||||
|
|
||||||
// let mut tree = OptimalMerkleTree::new(20, Default::default(), Default::default()).unwrap();
|
// let mut tree = OptimalMerkleTree::new(20, Default::default(), Default::default()).unwrap();
|
||||||
@@ -116,14 +125,14 @@ mod tests {
|
|||||||
|
|
||||||
let (_proof_0, proof_values_0) = compute_rln_proof_and_values(
|
let (_proof_0, proof_values_0) = compute_rln_proof_and_values(
|
||||||
&RlnUserIdentity {
|
&RlnUserIdentity {
|
||||||
commitment: user_co,
|
commitment: *user_co,
|
||||||
secret_hash: user_sh,
|
secret_hash: user_sh.clone(),
|
||||||
user_limit: spam_limit,
|
user_limit: spam_limit,
|
||||||
},
|
},
|
||||||
&rln_identifier,
|
&rln_identifier,
|
||||||
RlnData {
|
RlnData {
|
||||||
message_id,
|
message_id,
|
||||||
data: hash_to_field(b"sig"),
|
data: hash_to_field_le(b"sig"),
|
||||||
},
|
},
|
||||||
epoch,
|
epoch,
|
||||||
&m_proof,
|
&m_proof,
|
||||||
@@ -132,14 +141,14 @@ mod tests {
|
|||||||
|
|
||||||
let (_proof_1, proof_values_1) = compute_rln_proof_and_values(
|
let (_proof_1, proof_values_1) = compute_rln_proof_and_values(
|
||||||
&RlnUserIdentity {
|
&RlnUserIdentity {
|
||||||
commitment: user_co,
|
commitment: *user_co,
|
||||||
secret_hash: user_sh,
|
secret_hash: user_sh.clone(),
|
||||||
user_limit: spam_limit,
|
user_limit: spam_limit,
|
||||||
},
|
},
|
||||||
&rln_identifier,
|
&rln_identifier,
|
||||||
RlnData {
|
RlnData {
|
||||||
message_id,
|
message_id,
|
||||||
data: hash_to_field(b"sig 2"),
|
data: hash_to_field_le(b"sig 2"),
|
||||||
},
|
},
|
||||||
epoch,
|
epoch,
|
||||||
&m_proof,
|
&m_proof,
|
||||||
|
|||||||
Reference in New Issue
Block a user