Skip to content

Commit 8479c60

Browse files
committed
bump zk and improve the logs
1 parent 6014b9e commit 8479c60

5 files changed

Lines changed: 106 additions & 63 deletions

File tree

Cargo.lock

Lines changed: 22 additions & 22 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,18 +77,13 @@ subxt-metadata = "0.44"
7777
# ZK proof generation (aligned with chain)
7878
anyhow = "1.0"
7979

80-
qp-wormhole-circuit = { version = "1.3.0", default-features = false, features = ["std"] }
81-
qp-wormhole-prover = { version = "1.3.0", default-features = false, features = ["std"] }
82-
qp-wormhole-verifier = { version = "1.3.0", default-features = false, features = ["std"] }
83-
qp-wormhole-aggregator = { version = "1.3.0", default-features = false, features = ["rayon", "std"] }
84-
qp-wormhole-inputs = { version = "1.3.0", default-features = false, features = ["std"] }
85-
qp-zk-circuits-common = { version = "1.3.0", default-features = false, features = ["std"] }
86-
qp-plonky2 = { version = "1.1.6", default-features = false, features = ["rand", "std"] }
8780
qp-wormhole-circuit-builder = { version = "1.3.0" }
81+
qp-wormhole-circuit-builder = { version = "1.4.0" }
8882

8983

9084
[build-dependencies]
9185
qp-wormhole-circuit-builder = { version = "1.3.0" }
86+
qp-wormhole-circuit-builder = { version = "1.4.0" }
9287

9388
[dev-dependencies]
9489
tempfile = "3.8.1"

build.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ fn main() {
2222
.parse()
2323
.expect("QP_NUM_LEAF_PROOFS must be a valid usize");
2424

25-
println!("cargo:rerun-if-changed=build.rs");
25+
// Don't emit any rerun-if-changed directives - this forces the build script
26+
// to run on every build. Circuit generation is fast enough in release mode.
2627

2728
println!(
2829
"cargo:warning=[quantus-cli] Generating ZK circuit binaries (num_leaf_proofs={})...",

src/cli/address_format.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,15 @@ impl QuantusSS58 for subxt::ext::subxt_core::utils::AccountId32 {
2929
sp_account_id.to_ss58check_with_version(quantus_ss58_format())
3030
}
3131
}
32+
33+
/// Convert raw 32-byte account to Quantus SS58 format
34+
pub fn bytes_to_quantus_ss58(bytes: &[u8; 32]) -> String {
35+
let sp_account_id = sp_core::crypto::AccountId32::from(*bytes);
36+
sp_account_id.to_ss58check_with_version(quantus_ss58_format())
37+
}
38+
39+
/// Convert a byte slice to Quantus SS58 format (panics if not 32 bytes)
40+
pub fn slice_to_quantus_ss58(bytes: &[u8]) -> String {
41+
let arr: [u8; 32] = bytes.try_into().expect("account must be 32 bytes");
42+
bytes_to_quantus_ss58(&arr)
43+
}

src/cli/wormhole.rs

Lines changed: 68 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::{
44
quantus_subxt::{self as quantus_node, api::wormhole},
55
},
66
cli::{
7+
address_format::{bytes_to_quantus_ss58, slice_to_quantus_ss58},
78
common::{submit_transaction, ExecutionMode},
89
send::get_balance,
910
},
@@ -880,10 +881,11 @@ async fn aggregate_proofs(
880881
// De-quantize to show actual amount that will be minted
881882
let dequantized_amount =
882883
(account_data.summed_output_amount as u128) * SCALE_DOWN_FACTOR;
884+
let ss58_address = slice_to_quantus_ss58(exit_bytes);
883885
log_print!(
884886
" [{}] {} -> {} quantized ({} planck = {})",
885887
idx,
886-
hex::encode(exit_bytes),
888+
ss58_address,
887889
account_data.summed_output_amount,
888890
dequantized_amount,
889891
format_balance(dequantized_amount)
@@ -1304,8 +1306,13 @@ fn print_multiround_config(
13041306

13051307
/// Execute initial transfers from wallet to wormhole addresses (round 1 only).
13061308
///
1307-
/// Sends all transfers in a single batched extrinsic using `utility.batch()`,
1308-
/// then parses the `NativeTransferred` events to extract transfer info for proof generation.
1309+
/// Sends all transfers in a single batched extrinsic using `utility.batch()`.
1310+
/// Transfer counts are queried from chain storage (not events) to determine the
1311+
/// `transfer_count` for each recipient, which is needed for proof generation.
1312+
///
1313+
/// Note: We query `TransferCount` storage BEFORE submitting the batch because
1314+
/// the transfer_count in the proof must be the value at the time of transfer
1315+
/// (i.e., before the increment that happens during `record_transfer`).
13091316
async fn execute_initial_transfers(
13101317
quantus_client: &QuantusClient,
13111318
wallet: &MultiroundWalletContext,
@@ -1349,6 +1356,33 @@ async fn execute_initial_transfers(
13491356

13501357
log_print!(" Submitting batch of {} transfers...", num_proofs);
13511358

1359+
// Query transfer counts BEFORE submitting the batch.
1360+
// The transfer_count used in the proof is the count at the time of transfer,
1361+
// which equals the count before the transfer (since it increments after).
1362+
let client = quantus_client.client();
1363+
let mut transfer_counts_before: Vec<u64> = Vec::with_capacity(num_proofs);
1364+
for secret in secrets.iter() {
1365+
let wormhole_address = SubxtAccountId(secret.address);
1366+
let count = client
1367+
.storage()
1368+
.at_latest()
1369+
.await
1370+
.map_err(|e| {
1371+
crate::error::QuantusError::Generic(format!("Failed to get storage: {}", e))
1372+
})?
1373+
.fetch(&quantus_node::api::storage().wormhole().transfer_count(wormhole_address))
1374+
.await
1375+
.map_err(|e| {
1376+
crate::error::QuantusError::Generic(format!(
1377+
"Failed to fetch transfer count for {}: {}",
1378+
hex::encode(secret.address),
1379+
e
1380+
))
1381+
})?
1382+
.unwrap_or(0);
1383+
transfer_counts_before.push(count);
1384+
}
1385+
13521386
submit_transaction(
13531387
quantus_client,
13541388
&quantum_keypair,
@@ -1359,40 +1393,20 @@ async fn execute_initial_transfers(
13591393
.await
13601394
.map_err(|e| crate::error::QuantusError::Generic(format!("Batch transfer failed: {}", e)))?;
13611395

1362-
// Get the block and find all NativeTransferred events
1363-
let client = quantus_client.client();
1396+
// Get the block hash for the transfer info (any recent block works since we use storage)
13641397
let block = at_best_block(quantus_client)
13651398
.await
13661399
.map_err(|e| crate::error::QuantusError::Generic(format!("Failed to get block: {}", e)))?;
13671400
let block_hash = block.hash();
13681401

1369-
let events_api =
1370-
client.events().at(block_hash).await.map_err(|e| {
1371-
crate::error::QuantusError::Generic(format!("Failed to get events: {}", e))
1372-
})?;
1373-
1374-
// Match each secret's wormhole address to its NativeTransferred event
1402+
// Build transfer info using the transfer counts we captured before the batch
13751403
let funding_account: SubxtAccountId = SubxtAccountId(wallet.keypair.to_account_id_32().into());
13761404
let mut transfers = Vec::with_capacity(num_proofs);
13771405

13781406
for (i, secret) in secrets.iter().enumerate() {
1379-
let event = events_api
1380-
.find::<wormhole::events::NativeTransferred>()
1381-
.find(|e| if let Ok(evt) = e { evt.to.0 == secret.address } else { false })
1382-
.ok_or_else(|| {
1383-
crate::error::QuantusError::Generic(format!(
1384-
"No NativeTransferred event found for wormhole address {} (proof {})",
1385-
hex::encode(secret.address),
1386-
i + 1
1387-
))
1388-
})?
1389-
.map_err(|e| {
1390-
crate::error::QuantusError::Generic(format!("Event decode error: {}", e))
1391-
})?;
1392-
13931407
transfers.push(TransferInfo {
13941408
block_hash,
1395-
transfer_count: event.transfer_count,
1409+
transfer_count: transfer_counts_before[i],
13961410
amount: partition_amounts[i],
13971411
wormhole_address: SubxtAccountId(secret.address),
13981412
funding_account: funding_account.clone(),
@@ -1440,25 +1454,27 @@ async fn generate_round_proofs(
14401454
log_print!(" Random output partition:");
14411455
for (i, assignment) in output_assignments.iter().enumerate() {
14421456
let amt1_planck = (assignment.output_amount_1 as u128) * SCALE_DOWN_FACTOR;
1457+
let ss58_1 = bytes_to_quantus_ss58(&assignment.exit_account_1);
14431458
if assignment.output_amount_2 > 0 {
14441459
let amt2_planck = (assignment.output_amount_2 as u128) * SCALE_DOWN_FACTOR;
1460+
let ss58_2 = bytes_to_quantus_ss58(&assignment.exit_account_2);
14451461
log_print!(
1446-
" Proof {}: {} ({}) -> 0x{}..., {} ({}) -> 0x{}...",
1462+
" Proof {}: {} ({}) -> {}, {} ({}) -> {}",
14471463
i + 1,
14481464
assignment.output_amount_1,
14491465
format_balance(amt1_planck),
1450-
hex::encode(&assignment.exit_account_1[..4]),
1466+
ss58_1,
14511467
assignment.output_amount_2,
14521468
format_balance(amt2_planck),
1453-
hex::encode(&assignment.exit_account_2[..4])
1469+
ss58_2
14541470
);
14551471
} else {
14561472
log_print!(
1457-
" Proof {}: {} ({}) -> 0x{}...",
1473+
" Proof {}: {} ({}) -> {}",
14581474
i + 1,
14591475
assignment.output_amount_1,
14601476
format_balance(amt1_planck),
1461-
hex::encode(&assignment.exit_account_1[..4])
1477+
ss58_1
14621478
);
14631479
}
14641480
}
@@ -1978,6 +1994,25 @@ async fn verify_aggregated_and_get_events(
19781994
// Verify locally before submitting on-chain
19791995
log_verbose!("Verifying aggregated proof locally before on-chain submission...");
19801996
let bins_dir = Path::new("generated-bins");
1997+
1998+
// Log circuit binary hashes for debugging
1999+
let common_bytes = std::fs::read(bins_dir.join("aggregated_common.bin")).map_err(|e| {
2000+
crate::error::QuantusError::Generic(format!("Failed to read aggregated_common.bin: {}", e))
2001+
})?;
2002+
let verifier_bytes = std::fs::read(bins_dir.join("aggregated_verifier.bin")).map_err(|e| {
2003+
crate::error::QuantusError::Generic(format!(
2004+
"Failed to read aggregated_verifier.bin: {}",
2005+
e
2006+
))
2007+
})?;
2008+
println!(
2009+
"[quantus-cli] Circuit binaries: common_bytes.len={}, verifier_bytes.len={}, common_hash={}, verifier_hash={}",
2010+
common_bytes.len(),
2011+
verifier_bytes.len(),
2012+
hex::encode(blake3::hash(&common_bytes).as_bytes()),
2013+
hex::encode(blake3::hash(&verifier_bytes).as_bytes()),
2014+
);
2015+
19812016
let verifier = WormholeVerifier::new_from_files(
19822017
&bins_dir.join("aggregated_verifier.bin"),
19832018
&bins_dir.join("aggregated_common.bin"),
@@ -2030,11 +2065,11 @@ async fn verify_aggregated_and_get_events(
20302065
// Log minted amounts
20312066
log_print!(" Tokens minted (from NativeTransferred events):");
20322067
for (idx, transfer) in transfer_events.iter().enumerate() {
2033-
let to_hex = hex::encode(transfer.to.0);
2068+
let ss58_address = bytes_to_quantus_ss58(&transfer.to.0);
20342069
log_print!(
20352070
" [{}] {} -> {} planck ({})",
20362071
idx,
2037-
to_hex,
2072+
ss58_address,
20382073
transfer.amount,
20392074
format_balance(transfer.amount)
20402075
);

0 commit comments

Comments
 (0)