Compare commits
13 Commits
collinjack
...
main
Author | SHA1 | Date | |
---|---|---|---|
|
e084396969 | ||
|
d9507aa2ac | ||
|
f7fe621554 | ||
|
c41425c55c | ||
|
b0698ec2d2 | ||
|
b0b1c6fd1e | ||
|
f6d168cd7c | ||
|
26f1652952 | ||
|
0bff6e31df | ||
|
7b3383123c | ||
|
9006b955d2 | ||
|
a48c121a3c | ||
|
1435971226 |
64
.github/workflows/ci.yml
vendored
Normal file
64
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
name: ci
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- "**"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Lint CLI
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
sparse-checkout: |
|
||||||
|
clients/cli
|
||||||
|
proto
|
||||||
|
|
||||||
|
- name: Set up Rust
|
||||||
|
uses: dtolnay/rust-toolchain@stable
|
||||||
|
|
||||||
|
- name: Install protoc
|
||||||
|
uses: arduino/setup-protoc@v3
|
||||||
|
|
||||||
|
- name: Set up Rust cache
|
||||||
|
uses: Swatinem/rust-cache@v2
|
||||||
|
with:
|
||||||
|
workspaces: ./clients/cli
|
||||||
|
|
||||||
|
- name: Format
|
||||||
|
working-directory: clients/cli
|
||||||
|
run: |
|
||||||
|
rustfmt src/**/*.rs --check --edition 2021
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
working-directory: clients/cli
|
||||||
|
run: |
|
||||||
|
cargo build --profile=ci-build
|
||||||
|
|
||||||
|
- name: Run cargo clippy
|
||||||
|
working-directory: clients/cli
|
||||||
|
run: |
|
||||||
|
cargo clippy --profile=ci-build --no-deps --all-targets --workspace -- -D warnings
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
working-directory: clients/cli
|
||||||
|
run: |
|
||||||
|
cargo test --profile=ci-build --tests
|
||||||
|
|
||||||
|
- name: Ensure checked in generated files are up to date
|
||||||
|
run: |
|
||||||
|
if [ -n "$(git status --porcelain)" ]; then \
|
||||||
|
echo "There are uncommitted changes in working tree after building."; \
|
||||||
|
git status; \
|
||||||
|
git --no-pager diff; \
|
||||||
|
exit 1; \
|
||||||
|
else \
|
||||||
|
echo "Git working tree is clean"; \
|
||||||
|
fi;
|
@ -39,9 +39,8 @@ If you believe that you have uncovered a bug, please describe it to the best of
|
|||||||
|
|
||||||
As a starting point, in a bug report we will pretty much always want:
|
As a starting point, in a bug report we will pretty much always want:
|
||||||
|
|
||||||
- the Nexus network version/revision you are using;
|
|
||||||
- the platform you are on, ideally both the operating system (Windows, macOS, or Linux) and the machine architecture (_e.g.,_ if you're using an M-series Mac) if you know them;
|
- the platform you are on, ideally both the operating system (Windows, macOS, or Linux) and the machine architecture (_e.g.,_ if you're using an M-series Mac) if you know them;
|
||||||
- console logs from the CLI or web application showing errors ands status messages;
|
- console logs from the CLI or web application showing errors and status messages;
|
||||||
- concrete and comprehensive steps to reproduce the bug.
|
- concrete and comprehensive steps to reproduce the bug.
|
||||||
|
|
||||||
Code snippets should be as minimal as possible. It is always better if you can reproduce the bug with a small snippet that focuses on your Nexus zkVM usage rather than on the surrounding code in your project. This will help collaborators verify, reproduce, and zero in on a fix.
|
Code snippets should be as minimal as possible. It is always better if you can reproduce the bug with a small snippet that focuses on your Nexus zkVM usage rather than on the surrounding code in your project. This will help collaborators verify, reproduce, and zero in on a fix.
|
||||||
|
2
clients/cli/Cargo.lock
generated
2
clients/cli/Cargo.lock
generated
@ -1567,7 +1567,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nexus-network"
|
name = "nexus-network"
|
||||||
version = "0.1.0"
|
version = "0.3.4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ark-bn254",
|
"ark-bn254",
|
||||||
"ark-crypto-primitives",
|
"ark-crypto-primitives",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nexus-network"
|
name = "nexus-network"
|
||||||
version = "0.1.0"
|
version = "0.3.4"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
@ -10,6 +10,23 @@ path = "src/prover.rs"
|
|||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
prost-build = "0.13"
|
prost-build = "0.13"
|
||||||
|
|
||||||
|
[profile.dev]
|
||||||
|
opt-level = 1
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
lto = "fat"
|
||||||
|
strip = true
|
||||||
|
codegen-units = 1
|
||||||
|
|
||||||
|
[profile.ci-build]
|
||||||
|
inherits = "dev"
|
||||||
|
opt-level = 0
|
||||||
|
debug = 0
|
||||||
|
strip = "none"
|
||||||
|
lto = false
|
||||||
|
codegen-units = 256
|
||||||
|
incremental = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-stream = "0.3"
|
async-stream = "0.3"
|
||||||
clap = { version = "4.5", features = ["derive"] }
|
clap = { version = "4.5", features = ["derive"] }
|
||||||
@ -83,8 +100,3 @@ ark-vesta = { git = "https://github.com/arkworks-rs/curves/", rev = "8c0256a" }
|
|||||||
ark-bls12-381 = { git = "https://github.com/arkworks-rs/curves/", rev = "3fded1f" }
|
ark-bls12-381 = { git = "https://github.com/arkworks-rs/curves/", rev = "3fded1f" }
|
||||||
|
|
||||||
zstd-sys = { git = "https://github.com/gyscos/zstd-rs" }
|
zstd-sys = { git = "https://github.com/gyscos/zstd-rs" }
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
strip = true
|
|
||||||
lto = true
|
|
||||||
codegen-units = 1
|
|
||||||
|
@ -1,23 +1,59 @@
|
|||||||
# network-cli
|
# Network CLI
|
||||||
|
|
||||||
Command line interface (CLI) for accessing the Nexus Network. Highest-performance option for proving.
|
The command line interface (CLI) lets you run a prover node and contribute proofs to the Nexus network.
|
||||||
|
It is the highest-performance option for proving.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
If you don't have these dependencies already, install them first.
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
|
||||||
|
```
|
||||||
|
sudo apt update
|
||||||
|
sudo apt upgrade
|
||||||
|
sudo apt install build-essential pkg-config libssl-dev git-all
|
||||||
|
```
|
||||||
|
|
||||||
|
### macOS
|
||||||
|
|
||||||
|
If you have [installed Homebrew](https://brew.sh/) to manage packages on OS X,
|
||||||
|
run this command to install Git.
|
||||||
|
|
||||||
|
```
|
||||||
|
brew install git
|
||||||
|
```
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
[Install WSL](https://learn.microsoft.com/en-us/windows/wsl/install),
|
||||||
|
then see Linux instructions above.
|
||||||
|
|
||||||
## Quick start
|
## Quick start
|
||||||
|
|
||||||
```
|
```
|
||||||
curl https://cli.nexus.xyz/install.sh | sh
|
curl https://cli.nexus.xyz/ | sh
|
||||||
```
|
```
|
||||||
|
|
||||||
If you do not already have Rust, you will be prompted to install it.
|
If you do not already have Rust, you will be prompted to install it.
|
||||||
|
|
||||||
## Terms of Use
|
## Terms of Use
|
||||||
|
|
||||||
Use of the CLI is subject to the [Terms of Use](https://nexus.xyz/terms_of_use).
|
Use of the CLI is subject to the [Terms of Use](https://nexus.xyz/terms-of-use).
|
||||||
The first time you run it, it prompts you to accept the terms. To accept the terms
|
The first time you run it, it prompts you to accept the terms. To accept the terms
|
||||||
noninteractively (for example, in a continuous integration environment),
|
noninteractively (for example, in a continuous integration environment),
|
||||||
add `NONINTERACTIVE=1` before `sh`.
|
add `NONINTERACTIVE=1` before `sh`.
|
||||||
|
|
||||||
## Known issues
|
## Known issues
|
||||||
|
|
||||||
Currently only proving is supported. Submitting programs to the network is in private beta.
|
* Only the latest version of the CLI is currently supported.
|
||||||
To request an API key, [contact us](https://forms.gle/183D9bcDHUdbxCV5A).
|
* Prebuilt binaries are not yet available.
|
||||||
|
* Linking email to prover id is currently available on the web version only.
|
||||||
|
* Counting cycles proved is not yet available in the CLI.
|
||||||
|
* Only proving is supported. Submitting programs to the network is in private beta.
|
||||||
|
To request an API key, contact us at growth@nexus.xyz.
|
||||||
|
|
||||||
|
## Resources
|
||||||
|
|
||||||
|
* [Network FAQ](https://nexus.xyz/network#network-faqs)
|
||||||
|
* [Discord server](https://discord.gg/nexus-xyz)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::config::analytics_token;
|
use crate::config::{analytics_id, analytics_api_key};
|
||||||
use chrono::Datelike;
|
use chrono::Datelike;
|
||||||
use chrono::Timelike;
|
use chrono::Timelike;
|
||||||
use reqwest::header::{ACCEPT, CONTENT_TYPE};
|
use reqwest::header::{ACCEPT, CONTENT_TYPE};
|
||||||
@ -16,14 +16,27 @@ pub fn track(
|
|||||||
) {
|
) {
|
||||||
println!("{}", description);
|
println!("{}", description);
|
||||||
|
|
||||||
let token = analytics_token(ws_addr_string);
|
let firebase_app_id = analytics_id(ws_addr_string);
|
||||||
if token.is_empty() {
|
let firebase_api_key = analytics_api_key(ws_addr_string);
|
||||||
|
if firebase_app_id.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let local_now = chrono::offset::Local::now();
|
let local_now = chrono::offset::Local::now();
|
||||||
|
|
||||||
|
// For tracking events, we use the Firebase Measurement Protocol
|
||||||
|
// Firebase is mostly designed for mobile and web apps, but for our use case of a CLI,
|
||||||
|
// we can use the Measurement Protocol to track events by POST to a URL.
|
||||||
|
// The only thing that may be unexpected is that the URL we use includes a firebase key
|
||||||
|
|
||||||
|
// Firebase format for properties for Measurement protocol:
|
||||||
|
// https://developers.google.com/analytics/devguides/collection/protocol/ga4/reference?client_type=firebase#payload
|
||||||
|
// https://developers.google.com/analytics/devguides/collection/protocol/ga4/reference?client_type=firebase#payload_query_parameters
|
||||||
let mut properties = json!({
|
let mut properties = json!({
|
||||||
"token": token,
|
|
||||||
"time": SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis(),
|
"time": SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis(),
|
||||||
|
// app_instance_id is the standard key Firebase uses this key to track the same user across sessions
|
||||||
|
// It is a bit redundant, but I wanted to keep the recommended format Firebase uses to minimize surprises
|
||||||
|
// I still left the distinct_id key as well for backwards compatibility
|
||||||
|
"app_instance_id": event_properties["prover_id"],
|
||||||
"distinct_id": event_properties["prover_id"],
|
"distinct_id": event_properties["prover_id"],
|
||||||
"prover_type": "volunteer",
|
"prover_type": "volunteer",
|
||||||
"client_type": "cli",
|
"client_type": "cli",
|
||||||
@ -36,15 +49,27 @@ pub fn track(
|
|||||||
for (k, v) in event_properties.as_object().unwrap() {
|
for (k, v) in event_properties.as_object().unwrap() {
|
||||||
properties[k] = v.clone();
|
properties[k] = v.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Firebase format for events
|
||||||
let body = json!({
|
let body = json!({
|
||||||
"event": event_name,
|
"app_instance_id": event_properties["prover_id"],
|
||||||
"properties": properties
|
"events": [{
|
||||||
|
"name": event_name,
|
||||||
|
"params": properties
|
||||||
|
}],
|
||||||
});
|
});
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let client = reqwest::Client::new();
|
let client = reqwest::Client::new();
|
||||||
|
|
||||||
let _ = client
|
let _ = client
|
||||||
.post("https://api.mixpanel.com/track?ip=1")
|
// URL is the Google Analytics endpoint for Firebase: https://stackoverflow.com/questions/50355752/firebase-analytics-from-remote-rest-api
|
||||||
.body(format!("[{}]", body.to_string()))
|
.post(format!(
|
||||||
|
"https://www.google-analytics.com/mp/collect?firebase_app_id={}&api_secret={}",
|
||||||
|
firebase_app_id,
|
||||||
|
firebase_api_key
|
||||||
|
))
|
||||||
|
.body(format!("[{}]", body))
|
||||||
.header(ACCEPT, "text/plain")
|
.header(ACCEPT, "text/plain")
|
||||||
.header(CONTENT_TYPE, "application/json")
|
.header(CONTENT_TYPE, "application/json")
|
||||||
.send()
|
.send()
|
||||||
|
@ -1,11 +1,78 @@
|
|||||||
pub fn analytics_token(ws_addr_string: &str) -> String {
|
// Debug version of analytics_id
|
||||||
if ws_addr_string.starts_with("wss://dev.orchestrator.nexus.xyz:443/") {
|
#[cfg(debug_assertions)]
|
||||||
return "504d4d443854f2cd10e2e385aca81aa4".into();
|
pub fn analytics_id(_ws_addr_string: &str) -> String {
|
||||||
} else if ws_addr_string.starts_with("wss://staging.orchestrator.nexus.xyz:443/") {
|
// Use one of the tokens in the release version if debugging analytics
|
||||||
return "30bcb58893992aabc5aec014e7b903d2".into();
|
"".into()
|
||||||
} else if ws_addr_string.starts_with("wss://beta.orchestrator.nexus.xyz:443/") {
|
|
||||||
return "3c16d3853f4258414c9c9109bbbdef0e".into();
|
|
||||||
} else {
|
|
||||||
return "".into();
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Debug version of analytics_api_key
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
pub fn analytics_api_key(_ws_addr_string: &str) -> String {
|
||||||
|
// Use one of the tokens in the release version if debugging analytics
|
||||||
|
"".into()
|
||||||
|
}
|
||||||
|
|
||||||
|
// The following enum is used to determine the environment from the web socket string
|
||||||
|
#[derive(Debug)]
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
enum Environment {
|
||||||
|
Dev,
|
||||||
|
Staging,
|
||||||
|
Beta,
|
||||||
|
Unknown,
|
||||||
|
}
|
||||||
|
|
||||||
|
// The web socket addresses for the different environments
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
mod web_socket_urls {
|
||||||
|
pub const DEV: &str = "wss://dev.orchestrator.nexus.xyz:443/";
|
||||||
|
pub const STAGING: &str = "wss://staging.orchestrator.nexus.xyz:443/";
|
||||||
|
pub const BETA: &str = "wss://beta.orchestrator.nexus.xyz:443/";
|
||||||
|
}
|
||||||
|
|
||||||
|
// the firebase APP IDS by environment
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
mod firebase {
|
||||||
|
pub const DEV_APP_ID: &str = "1:954530464230:web:f0a14de14ef7bcdaa99627";
|
||||||
|
pub const STAGING_APP_ID: &str = "1:222794630996:web:1758d64a85eba687eaaac1";
|
||||||
|
pub const BETA_APP_ID: &str = "1:279395003658:web:04ee2c524474d683d75ef3";
|
||||||
|
|
||||||
|
// Analytics keys for the different environments
|
||||||
|
// These are keys that allow the measurement protocol to write to the analytics database
|
||||||
|
// They are not sensitive. Worst case, if a malicious actor obtains the secret, they could potentially send false or misleading data to your GA4 property
|
||||||
|
pub const DEV_API_SECRET: &str = "8ySxiKrtT8a76zClqqO8IQ";
|
||||||
|
pub const STAGING_API_SECRET: &str = "OI7H53soRMSDWfJf1ittHQ";
|
||||||
|
pub const BETA_API_SECRET: &str = "gxxzKAQLSl-uYI0eKbIi_Q";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Release versions (existing code)
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
pub fn analytics_id(ws_addr_string: &str) -> String {
|
||||||
|
|
||||||
|
// Determine the environment from the web socket string (ws_addr_string)
|
||||||
|
let env = match ws_addr_string {
|
||||||
|
web_socket_urls::DEV => Environment::Dev,
|
||||||
|
web_socket_urls::STAGING => Environment::Staging,
|
||||||
|
web_socket_urls::BETA => Environment::Beta,
|
||||||
|
_ => Environment::Unknown,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Return the appropriate Firebase App ID based on the environment
|
||||||
|
match env {
|
||||||
|
Environment::Dev => firebase::DEV_APP_ID.to_string(),
|
||||||
|
Environment::Staging => firebase::STAGING_APP_ID.to_string(),
|
||||||
|
Environment::Beta => firebase::BETA_APP_ID.to_string(),
|
||||||
|
Environment::Unknown => String::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
pub fn analytics_api_key(ws_addr_string: &str) -> String {
|
||||||
|
match ws_addr_string {
|
||||||
|
web_socket_urls::DEV => firebase::DEV_API_SECRET.to_string(),
|
||||||
|
web_socket_urls::STAGING => firebase::STAGING_API_SECRET.to_string(),
|
||||||
|
web_socket_urls::BETA => firebase::BETA_API_SECRET.to_string(),
|
||||||
|
_ => String::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -32,9 +32,8 @@ use nexus_core::{
|
|||||||
init_circuit_trace, key::CanonicalSerialize, pp::gen_vm_pp, prove_seq_step, types::*,
|
init_circuit_trace, key::CanonicalSerialize, pp::gen_vm_pp, prove_seq_step, types::*,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use std::env;
|
use rand::RngCore;
|
||||||
use zstd::stream::Encoder;
|
use zstd::stream::Encoder;
|
||||||
use rand::{ RngCore };
|
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
struct Args {
|
struct Args {
|
||||||
@ -119,16 +118,35 @@ async fn main() {
|
|||||||
contents: Some(prover_request::Contents::Registration(
|
contents: Some(prover_request::Contents::Registration(
|
||||||
ProverRequestRegistration {
|
ProverRequestRegistration {
|
||||||
prover_type: ProverType::Volunteer.into(),
|
prover_type: ProverType::Volunteer.into(),
|
||||||
prover_id: prover_id.clone().into(),
|
prover_id: prover_id.clone(),
|
||||||
estimated_proof_cycles_hertz: None,
|
estimated_proof_cycles_hertz: None,
|
||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
};
|
};
|
||||||
|
|
||||||
client
|
let mut retries = 0;
|
||||||
|
let max_retries = 5;
|
||||||
|
|
||||||
|
while let Err(e) = client
|
||||||
.send(Message::Binary(registration.encode_to_vec()))
|
.send(Message::Binary(registration.encode_to_vec()))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
{
|
||||||
|
eprintln!(
|
||||||
|
"Failed to send message: {:?}, attempt {}/{}",
|
||||||
|
e,
|
||||||
|
retries + 1,
|
||||||
|
max_retries
|
||||||
|
);
|
||||||
|
|
||||||
|
retries += 1;
|
||||||
|
if retries >= max_retries {
|
||||||
|
eprintln!("Max retries reached, exiting...");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a delay before retrying
|
||||||
|
tokio::time::sleep(tokio::time::Duration::from_secs(u64::pow(2, retries))).await;
|
||||||
|
}
|
||||||
|
|
||||||
track(
|
track(
|
||||||
"register".into(),
|
"register".into(),
|
||||||
@ -136,9 +154,6 @@ async fn main() {
|
|||||||
&ws_addr_string,
|
&ws_addr_string,
|
||||||
json!({"ws_addr_string": ws_addr_string, "prover_id": prover_id}),
|
json!({"ws_addr_string": ws_addr_string, "prover_id": prover_id}),
|
||||||
);
|
);
|
||||||
println!(
|
|
||||||
"Network stats are available at https://beta.nexus.xyz/."
|
|
||||||
);
|
|
||||||
loop {
|
loop {
|
||||||
let program_message = match client.next().await.unwrap().unwrap() {
|
let program_message = match client.next().await.unwrap().unwrap() {
|
||||||
Message::Binary(b) => b,
|
Message::Binary(b) => b,
|
||||||
@ -169,7 +184,7 @@ async fn main() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let mut vm: NexusVM<MerkleTrie> =
|
let mut vm: NexusVM<MerkleTrie> =
|
||||||
parse_elf(&elf_bytes.as_ref()).expect("error loading and parsing RISC-V instruction");
|
parse_elf(elf_bytes.as_ref()).expect("error loading and parsing RISC-V instruction");
|
||||||
vm.syscalls.set_input(&input);
|
vm.syscalls.set_input(&input);
|
||||||
|
|
||||||
// TODO(collinjackson): Get outputs
|
// TODO(collinjackson): Get outputs
|
||||||
@ -211,8 +226,8 @@ async fn main() {
|
|||||||
track(
|
track(
|
||||||
"progress".into(),
|
"progress".into(),
|
||||||
format!(
|
format!(
|
||||||
"Program trace is {} steps. Proving from {} to {}...",
|
"Program trace is {} steps. Proving {} steps starting at {}...",
|
||||||
total_steps, start, end
|
total_steps, steps_to_prove, start
|
||||||
),
|
),
|
||||||
&ws_addr_string,
|
&ws_addr_string,
|
||||||
json!({
|
json!({
|
||||||
@ -233,19 +248,21 @@ async fn main() {
|
|||||||
completed_fraction = steps_proven as f32 / steps_to_prove as f32;
|
completed_fraction = steps_proven as f32 / steps_to_prove as f32;
|
||||||
let progress = ProverRequest {
|
let progress = ProverRequest {
|
||||||
contents: Some(prover_request::Contents::Progress(Progress {
|
contents: Some(prover_request::Contents::Progress(Progress {
|
||||||
completed_fraction: completed_fraction,
|
completed_fraction,
|
||||||
steps_in_trace: total_steps as i32,
|
steps_in_trace: total_steps as i32,
|
||||||
steps_to_prove: steps_to_prove as i32,
|
steps_to_prove: steps_to_prove as i32,
|
||||||
steps_proven: steps_proven as i32,
|
steps_proven,
|
||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
let progress_duration = SystemTime::now().duration_since(progress_time).unwrap();
|
let progress_duration = SystemTime::now().duration_since(progress_time).unwrap();
|
||||||
let cycles_proven = steps_proven * 4;
|
let cycles_proven = steps_proven * 4;
|
||||||
let proof_cycles_hertz = k * 1000 / progress_duration.as_millis();
|
let proof_cycles_hertz = k as f64 * 1000.0 / progress_duration.as_millis() as f64;
|
||||||
let proof_cycles_per_minute = k * 60 * 1000 / progress_duration.as_millis();
|
|
||||||
track(
|
track(
|
||||||
"progress".into(),
|
"progress".into(),
|
||||||
format!("Proved step {} at {} Hz.", step, proof_cycles_hertz),
|
format!(
|
||||||
|
"Proved step {} at {:.2} proof cycles/sec.",
|
||||||
|
step, proof_cycles_hertz
|
||||||
|
),
|
||||||
&ws_addr_string,
|
&ws_addr_string,
|
||||||
json!({
|
json!({
|
||||||
"completed_fraction": completed_fraction,
|
"completed_fraction": completed_fraction,
|
||||||
@ -256,15 +273,31 @@ async fn main() {
|
|||||||
"k": k,
|
"k": k,
|
||||||
"progress_duration_millis": progress_duration.as_millis(),
|
"progress_duration_millis": progress_duration.as_millis(),
|
||||||
"proof_cycles_hertz": proof_cycles_hertz,
|
"proof_cycles_hertz": proof_cycles_hertz,
|
||||||
"proof_cycles_per_minute": proof_cycles_per_minute,
|
|
||||||
"prover_id": prover_id,
|
"prover_id": prover_id,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
progress_time = SystemTime::now();
|
progress_time = SystemTime::now();
|
||||||
client
|
|
||||||
.send(Message::Binary(progress.encode_to_vec()))
|
let mut retries = 0;
|
||||||
.await
|
let max_retries = 5;
|
||||||
.unwrap();
|
while let Err(e) = client.send(Message::Binary(progress.encode_to_vec())).await {
|
||||||
|
eprintln!(
|
||||||
|
"Failed to send message: {:?}, attempt {}/{}",
|
||||||
|
e,
|
||||||
|
retries + 1,
|
||||||
|
max_retries
|
||||||
|
);
|
||||||
|
|
||||||
|
retries += 1;
|
||||||
|
if retries >= max_retries {
|
||||||
|
eprintln!("Max retries reached, exiting...");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add a delay before retrying
|
||||||
|
tokio::time::sleep(tokio::time::Duration::from_secs(u64::pow(2, retries))).await;
|
||||||
|
}
|
||||||
|
|
||||||
if step == end - 1 {
|
if step == end - 1 {
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
let mut writer = Box::new(&mut buf);
|
let mut writer = Box::new(&mut buf);
|
||||||
@ -279,22 +312,24 @@ async fn main() {
|
|||||||
proof: Some(proof::Proof::NovaBytes(buf)),
|
proof: Some(proof::Proof::NovaBytes(buf)),
|
||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
|
let duration = SystemTime::now().duration_since(start_time).unwrap();
|
||||||
|
let proof_cycles_hertz =
|
||||||
|
cycles_proven as f64 * 1000.0 / duration.as_millis() as f64;
|
||||||
client
|
client
|
||||||
.send(Message::Binary(response.encode_to_vec()))
|
.send(Message::Binary(response.encode_to_vec()))
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let duration = SystemTime::now().duration_since(start_time).unwrap();
|
|
||||||
let proof_cycles_hertz = cycles_proven * 1000 / duration.as_millis();
|
|
||||||
let proof_cycles_per_minute = cycles_proven * 60 * 1000 / duration.as_millis();
|
|
||||||
track(
|
track(
|
||||||
"proof".into(),
|
"proof".into(),
|
||||||
format!("Proof sent! You proved at {} Hz.", proof_cycles_hertz),
|
format!(
|
||||||
|
"Proof sent! Overall speed was {:.2} proof cycles/sec.",
|
||||||
|
proof_cycles_hertz
|
||||||
|
),
|
||||||
&ws_addr_string,
|
&ws_addr_string,
|
||||||
json!({
|
json!({
|
||||||
"proof_duration_sec": duration.as_secs(),
|
"proof_duration_sec": duration.as_secs(),
|
||||||
"proof_duration_millis": duration.as_millis(),
|
"proof_duration_millis": duration.as_millis(),
|
||||||
"proof_cycles_hertz": proof_cycles_hertz,
|
"proof_cycles_hertz": proof_cycles_hertz,
|
||||||
"proof_cycles_per_minute": proof_cycles_per_minute,
|
|
||||||
"prover_id": prover_id,
|
"prover_id": prover_id,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
mkdir -p clients/flutter/lib/src/generated
|
|
||||||
protoc --experimental_allow_proto3_optional --dart_out=grpc:clients/flutter/lib/src/generated -Iproto proto/orchestrator.proto
|
|
||||||
dart format clients/flutter/lib/src/generated
|
|
||||||
(cd clients/dummy_client && cargo build || echo clients/dummy_client not found, possibly due to a sparse checkout.)
|
|
||||||
(cd clients/cli && cargo build || echo clients/cli not found, possibly due to a sparse checkout.)
|
|
||||||
(cd orchestrator && cargo build || echo orchestrator/ not found, possibly due a sparse checkout.)
|
|
@ -1,7 +1,7 @@
|
|||||||
// Copyright (c) 2024 Nexus. All rights reserved.
|
// Copyright (c) 2024 Nexus. All rights reserved.
|
||||||
//
|
//
|
||||||
// If you use this protocol to communicate with Nexus's servers,
|
// If you use this protocol to communicate with Nexus's servers,
|
||||||
// you must agree to the Terms of Service: https://nexus.xyz/tos
|
// you must agree to the Terms of Service: https://nexus.xyz/terms-of-use
|
||||||
|
|
||||||
syntax = "proto3";
|
syntax = "proto3";
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user