Skip to content

Commit 68d9540

Browse files
committed
chore: prevent recompilation by hashing files + features
1 parent b39a038 commit 68d9540

3 files changed

Lines changed: 105 additions & 39 deletions

File tree

Makefile

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -172,23 +172,35 @@ reset_last_aggregated_block:
172172
@echo "Resetting last aggregated block..."
173173
@echo '{"last_aggregated_block":0}' > config-files/proof-aggregator.last_aggregated_block.json
174174

175-
start_proof_aggregator_dev: is_aggregator_set reset_last_aggregated_block ## Starts proof aggregator with mock proofs (DEV mode)
176-
AGGREGATOR=$(AGGREGATOR) RISC0_DEV_MODE=1 cargo run --manifest-path ./aggregation_mode/Cargo.toml --release --bin proof_aggregator -- config-files/config-proof-aggregator-mock.yaml
175+
build_proof_aggregator_dev:
176+
@cd aggregation_mode && \
177+
cargo build --release --bin proof_aggregator
178+
179+
build_proof_aggregator_cpu:
180+
@cd aggregation_mode && \
181+
cargo build --release --bin proof_aggregator --features prove
182+
183+
build_proof_aggregator_gpu:
184+
@cd aggregation_mode && \
185+
cargo build --release --bin proof_aggregator --features prove,gpu
186+
187+
start_proof_aggregator_dev: is_aggregator_set reset_last_aggregated_block build_proof_aggregator_dev ## Starts proof aggregator with mock proofs (DEV mode)
188+
AGGREGATOR=$(AGGREGATOR) RISC0_DEV_MODE=1 ./aggregation_mode/target/release/proof_aggregator -- config-files/config-proof-aggregator-mock.yaml
177189

178-
start_proof_aggregator: is_aggregator_set reset_last_aggregated_block ## Starts proof aggregator with proving activated
179-
AGGREGATOR=$(AGGREGATOR) cargo run --manifest-path ./aggregation_mode/Cargo.toml --release --features prove --bin proof_aggregator -- config-files/config-proof-aggregator.yaml
190+
start_proof_aggregator_cpu: is_aggregator_set reset_last_aggregated_block build_proof_aggregator_cpu ## Starts proof aggregator with proving activated
191+
AGGREGATOR=$(AGGREGATOR) ./aggregation_mode/target/release/proof_aggregator -- config-files/config-proof-aggregator-mock.yaml
180192

181-
start_proof_aggregator_dev_ethereum_package: is_aggregator_set reset_last_aggregated_block ## Starts proof aggregator with mock proofs (DEV mode) in ethereum package
182-
AGGREGATOR=$(AGGREGATOR) RISC0_DEV_MODE=1 cargo run --manifest-path ./aggregation_mode/Cargo.toml --release --bin proof_aggregator -- config-files/config-proof-aggregator-mock-ethereum-package.yaml
193+
start_proof_aggregator_gpu: is_aggregator_set reset_last_aggregated_block build_proof_aggregator_gpu ## Starts proof aggregator with proving + GPU acceleration (CUDA)
194+
AGGREGATOR=$(AGGREGATOR) SP1_PROVER=cuda ./aggregation_mode/target/release/proof_aggregator -- config-files/config-proof-aggregator.yaml
183195

184-
start_proof_aggregator_ethereum_package: is_aggregator_set reset_last_aggregated_block ## Starts proof aggregator with proving activated in ethereum package
185-
AGGREGATOR=$(AGGREGATOR) cargo run --manifest-path ./aggregation_mode/Cargo.toml --release --features prove --bin proof_aggregator -- config-files/config-proof-aggregator-ethereum-package.yaml
196+
start_proof_aggregator_dev_ethereum_package: is_aggregator_set reset_last_aggregated_block build_proof_aggregator_dev ## Starts proof aggregator with mock proofs (DEV mode) in ethereum package
197+
AGGREGATOR=$(AGGREGATOR) RISC0_DEV_MODE=1 ./aggregation_mode/target/release/proof_aggregator -- config-files/config-proof-aggregator-mock-ethereum-package.yaml
186198

187-
start_proof_aggregator_gpu: is_aggregator_set reset_last_aggregated_block ## Starts proof aggregator with proving + GPU acceleration (CUDA)
188-
AGGREGATOR=$(AGGREGATOR) SP1_PROVER=cuda cargo run --manifest-path ./aggregation_mode/Cargo.toml --release --features prove,gpu --bin proof_aggregator -- config-files/config-proof-aggregator.yaml
199+
start_proof_aggregator_cpu_ethereum_package: is_aggregator_set reset_last_aggregated_block build_proof_aggregator_cpu ## Starts proof aggregator with proving activated in ethereum package
200+
AGGREGATOR=$(AGGREGATOR) ./aggregation_mode/target/release/proof_aggregator -- config-files/config-proof-aggregator-ethereum-package.yaml
189201

190-
start_proof_aggregator_gpu_ethereum_package: is_aggregator_set reset_last_aggregated_block ## Starts proof aggregator with proving activated in ethereum package
191-
AGGREGATOR=$(AGGREGATOR) SP1_PROVER=cuda cargo run --manifest-path ./aggregation_mode/Cargo.toml --release --features prove,gpu --bin proof_aggregator -- config-files/config-proof-aggregator-ethereum-package.yaml
202+
start_proof_aggregator_gpu_ethereum_package: is_aggregator_set reset_last_aggregated_block build_proof_aggregator_gpu ## Starts proof aggregator with proving activated in ethereum package
203+
AGGREGATOR=$(AGGREGATOR) SP1_PROVER=cuda ./aggregation_mode/target/release/proof_aggregator -- config-files/config-proof-aggregator-ethereum-package.yaml
192204

193205
verify_aggregated_proof_sp1_holesky_stage:
194206
@echo "Verifying SP1 in aggregated proofs on holesky..."

aggregation_mode/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ risc0-ethereum-contracts = { git = "https://github.com/risc0/risc0-ethereum/", t
2929
[build-dependencies]
3030
sp1-build = { version = "4.1.3" }
3131
risc0-build = { version = "2.0.0" }
32+
sha3 = "0.10.8"
3233

3334
[package.metadata.risc0]
3435
# Tell risc0 build to find method in ./aggregation_programs/risc0 package

aggregation_mode/build.rs

Lines changed: 80 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,86 @@
11
use risc0_build::{DockerOptionsBuilder, GuestOptionsBuilder};
2+
use sha3::{Digest, Keccak256};
3+
24
use std::collections::HashMap;
5+
use std::io::Read;
6+
use std::path::Path;
7+
use std::{env, fs};
8+
9+
// Hash all inputs
10+
fn hash_files_and_features<P: AsRef<Path>>(paths: &[P], features: Vec<String>) -> String {
11+
let mut hasher = Keccak256::new();
12+
for path in paths {
13+
let mut f = fs::File::open(path).unwrap();
14+
let mut buffer = Vec::new();
15+
f.read_to_end(&mut buffer).unwrap();
16+
hasher.update(&buffer);
17+
}
18+
19+
for feature in features {
20+
hasher.update(&feature);
21+
}
22+
23+
format!("{:x}", hasher.finalize())
24+
}
325

426
// Reference: https://docs.succinct.xyz/docs/sp1/writing-programs/compiling#advanced-build-options-1
527
fn main() {
6-
sp1_build::build_program_with_args("./aggregation_programs/sp1", {
7-
sp1_build::BuildArgs {
8-
output_directory: Some("./aggregation_programs/sp1/elf".to_string()),
9-
binaries: vec![
10-
"sp1_user_proofs_aggregator_program".into(),
11-
"sp1_chunk_aggregator_program".into(),
12-
],
13-
// We use Docker to generate a reproducible ELF that will be identical across all platforms
14-
// (https://docs.succinct.xyz/docs/sp1/writing-programs/compiling#production-builds)
15-
docker: true,
16-
..Default::default()
17-
}
18-
});
19-
20-
// With this containerized build process, we ensure that all builds of the guest code,
21-
// regardless of the machine or local environment, will produce the same ImageID
22-
let docker_options = DockerOptionsBuilder::default().build().unwrap();
23-
// Reference: https://github.com/risc0/risc0/blob/main/risc0/build/src/config.rs#L73-L90
24-
let guest_options = GuestOptionsBuilder::default()
25-
.use_docker(docker_options)
26-
.build()
27-
.unwrap();
28-
29-
risc0_build::embed_methods_with_options(HashMap::from([(
30-
"risc0_aggregation_program",
31-
guest_options,
32-
)]));
28+
let programs = [
29+
"build.rs",
30+
"aggregation_programs/sp1/src/user_proofs_aggregator_main.rs",
31+
"aggregation_programs/sp1/src/chunk_aggregator_main.rs",
32+
"aggregation_programs/sp1/src/lib.rs",
33+
"aggregation_programs/risc0/src/user_proofs_aggregator_main.rs",
34+
"aggregation_programs/risc0/src/chunk_aggregator_main.rs",
35+
"aggregation_programs/risc0/src/lib.rs",
36+
];
37+
38+
for file in &programs {
39+
println!("cargo:rerun-if-changed={}", file);
40+
}
41+
42+
// Collect and sort features for stable hashing
43+
let mut features: Vec<String> = env::vars()
44+
.filter(|(k, _)| k.starts_with("CARGO_FEATURE_"))
45+
.map(|(k, v)| format!("{k}={v}"))
46+
.collect();
47+
features.sort(); // Ensure deterministic hash regardless of env var order
48+
49+
let hash = hash_files_and_features(&programs, features);
50+
let hash_file = Path::new("target/programs_hash.txt");
51+
52+
let needs_build = if let Ok(prev) = fs::read_to_string(hash_file) {
53+
prev != hash
54+
} else {
55+
true
56+
};
57+
58+
if needs_build {
59+
sp1_build::build_program_with_args("./aggregation_programs/sp1", {
60+
sp1_build::BuildArgs {
61+
output_directory: Some("./aggregation_programs/sp1/elf".to_string()),
62+
// We use Docker to generate a reproducible ELF that will be identical across all platforms
63+
// (https://docs.succinct.xyz/docs/sp1/writing-programs/compiling#production-builds)
64+
// docker: true,
65+
..Default::default()
66+
}
67+
});
68+
69+
// With this containerized build process, we ensure that all builds of the guest code,
70+
// regardless of the machine or local environment, will produce the same ImageID
71+
let docker_options = DockerOptionsBuilder::default().build().unwrap();
72+
// Reference: https://github.com/risc0/risc0/blob/main/risc0/build/src/config.rs#L73-L90
73+
let guest_options = GuestOptionsBuilder::default()
74+
// .use_docker(docker_options)
75+
.build()
76+
.unwrap();
77+
risc0_build::embed_methods_with_options(HashMap::from([(
78+
"risc0_aggregation_program",
79+
guest_options,
80+
)]));
81+
82+
fs::write(hash_file, hash).unwrap();
83+
} else {
84+
println!("Programs code unchanged — skipping programs build");
85+
}
3386
}

0 commit comments

Comments
 (0)