Skip to content

Conversation

@ekrembal
Copy link
Member

@ekrembal ekrembal commented Oct 6, 2025

No description provided.

Copilot AI review requested due to automatic review settings October 6, 2025 17:21
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Improve streaming error propagation and MuSig2 signing pipeline robustness; add optional partial-signature verification and enhanced monitoring. Key updates:

  • Change streaming channels to carry Result types and wire monitor_standalone_task to forward task errors to clients.
  • Carry public nonces alongside aggregated nonces and partial signatures; update aggregation to accept (PartialSignature, PublicNonce) and optionally verify partial signatures.
  • Strengthen aggregator pipeline with tighter counting, error handling, and task join reporting; various error message improvements.
  • Note: a safety check in header_chain_prover for genesis state hash is commented out.

Reviewed Changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
core/src/verifier.rs Stream partial sigs as Result, forward task errors via monitor, improved premature end message
core/src/utils.rs monitor_standalone_task now forwards task errors to a provided channel
core/src/test/musig2.rs Adjust tests to pass (PartialSignature, PublicNonce) tuples
core/src/rpc/verifier.rs Propagate monitor errors, clarify error contexts, handle Result-wrapped partial sigs
core/src/rpc/parser/verifier.rs Clearer parse error messages
core/src/rpc/parser/mod.rs Optional-message macro returns Option directly
core/src/rpc/operator.rs Monitor error forwarding; operator deposit_sign sends Result-wrapped sigs
core/src/rpc/aggregator.rs Carry/route public nonces; stricter counts; improved error handling and logging; API adjustments
core/src/musig2.rs aggregate_partial_signatures now accepts (PartialSignature, PublicNonce); optional per-partial verification
core/src/header_chain_prover.rs Commented out genesis chain state hash validation (risk)
core/src/errors.rs New ErrorExt methods; changed BridgeError -> Status mapping to always internal

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +302 to 305
while let Some((queue_item, pub_nonces)) = queue_rx.recv().await {
let pub_nonces_ref = pub_nonces.as_slice();
let partial_sigs = try_join_all(partial_sig_rx.iter_mut().enumerate().map(
|(idx, stream)| async move {
Copy link

Copilot AI Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pub_nonces_ref[idx] has type &PublicNonce, but the tuple expects a PublicNonce, causing a type mismatch. Use a value (copy/clone or deref) instead of a reference.

Copilot uses AI. Check for mistakes.
)
.wrap_err("Failed to parse partial signature")?;

Ok::<_, BridgeError>((partial_sig, pub_nonces_ref[idx]))
Copy link

Copilot AI Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pub_nonces_ref[idx] has type &PublicNonce, but the tuple expects a PublicNonce, causing a type mismatch. Use a value (copy/clone or deref) instead of a reference.

Suggested change
Ok::<_, BridgeError>((partial_sig, pub_nonces_ref[idx]))
Ok::<_, BridgeError>((partial_sig, pub_nonces_ref[idx].clone()))

Copilot uses AI. Check for mistakes.
Comment on lines +158 to 165
if total_sigs != needed_nofn_sigs {
let err_msg = format!(
"Expected {} nofn signatures, got {} from sighash stream",
needed_nofn_sigs, total_sigs
);
tracing::error!(err_msg);
return Err(eyre::eyre!(err_msg).into());
}
Copy link

Copilot AI Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tracing::error!(err_msg) does not format the message as intended. Use tracing::error!(%err_msg) or tracing::error!("{}", err_msg) to emit the string. The same pattern appears at lines 290–291 and 366–367 below; please update those too.

Copilot uses AI. Check for mistakes.
"MuSig2 Error: partial signature verification failed for verifiers: {}",
partial_sig_verification_errors.join(", ")
);
tracing::error!(error_msg);
Copy link

Copilot AI Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tracing::error!(error_msg) won’t render the message; use tracing::error!(%error_msg) or tracing::error!("{}", error_msg) to log the string.

Suggested change
tracing::error!(error_msg);
tracing::error!("{}", error_msg);

Copilot uses AI. Check for mistakes.
Comment on lines +203 to +211
// let genesis_chain_state_hash = genesis_chain_state.to_hash();
// if genesis_chain_state_hash != config.protocol_paramset().genesis_chain_state_hash {
// return Err(eyre::eyre!(
// "Genesis chain state hash mismatch: {} != {}",
// hex::encode(genesis_chain_state_hash),
// hex::encode(config.protocol_paramset().genesis_chain_state_hash)
// )
// .into());
// }
Copy link

Copilot AI Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Genesis chain state hash validation is commented out, removing an important correctness/safety check. Please restore the validation to ensure the prover is anchored to the expected genesis parameters.

Suggested change
// let genesis_chain_state_hash = genesis_chain_state.to_hash();
// if genesis_chain_state_hash != config.protocol_paramset().genesis_chain_state_hash {
// return Err(eyre::eyre!(
// "Genesis chain state hash mismatch: {} != {}",
// hex::encode(genesis_chain_state_hash),
// hex::encode(config.protocol_paramset().genesis_chain_state_hash)
// )
// .into());
// }
let genesis_chain_state_hash = genesis_chain_state.to_hash();
if genesis_chain_state_hash != config.protocol_paramset().genesis_chain_state_hash {
return Err(eyre::eyre!(
"Genesis chain state hash mismatch: {} != {}",
hex::encode(genesis_chain_state_hash),
hex::encode(config.protocol_paramset().genesis_chain_state_hash)
)
.into());
}

Copilot uses AI. Check for mistakes.
)
.await
.wrap_err_with(|| {
format!("While waiting for {nonce_idx} + 1th sig out of {num_required_nofn_sigs} ")
Copy link

Copilot AI Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The message has a stray space and reads '+ 1th'. Consider: format!("While waiting for signature {} of {}", nonce_idx + 1, num_required_nofn_sigs) for a clearer error.

Suggested change
format!("While waiting for {nonce_idx} + 1th sig out of {num_required_nofn_sigs} ")
format!(
"While waiting for signature {} of {}",
nonce_idx + 1,
num_required_nofn_sigs
)

Copilot uses AI. Check for mistakes.
}

/// For each expected sighash, we collect a batch of public nonces from all verifiers. We aggregate and send to the agg_nonce_sender. Then repeat for the next sighash.
/// For each expected sighash, we collect a batch of public nonces from all verifiers. We aggregate and send aggregatod nonce and all public nonces (needed for partial signature verification) to the agg_nonce_sender. Then repeat for the next sighash.
Copy link

Copilot AI Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected spelling of 'aggregatod' to 'aggregated'.

Suggested change
/// For each expected sighash, we collect a batch of public nonces from all verifiers. We aggregate and send aggregatod nonce and all public nonces (needed for partial signature verification) to the agg_nonce_sender. Then repeat for the next sighash.
/// For each expected sighash, we collect a batch of public nonces from all verifiers. We aggregate and send aggregated nonce and all public nonces (needed for partial signature verification) to the agg_nonce_sender. Then repeat for the next sighash.

Copilot uses AI. Check for mistakes.
}

/// Reroutes aggregated nonces to the signature aggregator.
/// Reroutes aggregated nonces and public nonces for each aggregatedd nonce to the signature aggregator.
Copy link

Copilot AI Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected spelling of 'aggregatedd' to 'aggregated'.

Suggested change
/// Reroutes aggregated nonces and public nonces for each aggregatedd nonce to the signature aggregator.
/// Reroutes aggregated nonces and public nonces for each aggregated nonce to the signature aggregator.

Copilot uses AI. Check for mistakes.
Comment on lines +288 to 292
if nonce_count != needed_nofn_sigs {
let err_msg = format!("Expected {needed_nofn_sigs} aggregated nonces in nonce_distributor, got {nonce_count}",);
tracing::error!(err_msg);
return Err(eyre::eyre!(err_msg).into());
}
Copy link

Copilot AI Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As with earlier occurrences, use tracing::error!(%err_msg) or tracing::error!("{}", err_msg) so the error message is rendered.

Copilot uses AI. Check for mistakes.
let err_msg = format!(
"Expected {needed_nofn_sigs} partial signatures in nonce_distributor, got {sig_count}",
);
tracing::error!(err_msg);
Copy link

Copilot AI Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use tracing::error!(%err_msg) or tracing::error!("{}", err_msg) to log the formatted string; otherwise it won’t be printed as intended.

Suggested change
tracing::error!(err_msg);
tracing::error!("{}", err_msg);

Copilot uses AI. Check for mistakes.
@github-actions github-actions bot added the F-deposit-replace-needed Flag: Deposit replacements are needed. This will change Txids. label Oct 6, 2025
Copilot AI review requested due to automatic review settings October 6, 2025 19:00
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 17 out of 26 changed files in this pull request and generated 4 comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +181 to +185
let partial_sigs_and_nonces: Vec<&(PartialSignature, PublicNonce)> =
partial_sigs.iter().collect();
let partial_sigs: Vec<&PartialSignature> =
partial_sigs_and_nonces.iter().map(|(sig, _)| sig).collect();
// enable partial signature verification with an environment variable to see which verifier is giving bad partial signatures
Copy link

Copilot AI Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This double-iter pattern yields &&(PartialSignature, PublicNonce) and destructuring with |(sig, _)| won’t match; it will fail to compile or infer types incorrectly. Build the references directly from the function parameter: let partial_sigs: Vec<&PartialSignature> = partial_sigs.iter().map(|(sig, _)| sig).collect();

Copilot uses AI. Check for mistakes.
)
.wrap_err("Failed to parse partial signature")?;

Ok::<_, BridgeError>((partial_sig, pub_nonces_ref[idx]))
Copy link

Copilot AI Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You return (PartialSignature, PublicNonce) but pass pub_nonces_ref[idx], which is &PublicNonce. This mismatches the expected owned type. Use clone() (or deref if Copy) to produce a PublicNonce: Ok::<_, BridgeError>((partial_sig, pub_nonces_ref[idx].clone())).

Suggested change
Ok::<_, BridgeError>((partial_sig, pub_nonces_ref[idx]))
Ok::<_, BridgeError>((partial_sig, pub_nonces_ref[idx].clone()))

Copilot uses AI. Check for mistakes.
}
}

/// Monitors a [`tokio::task::JoinHandle`] in the background and logs it's end
Copy link

Copilot AI Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the possessive 'its' instead of 'it's'.

Suggested change
/// Monitors a [`tokio::task::JoinHandle`] in the background and logs it's end
/// Monitors a [`tokio::task::JoinHandle`] in the background and logs its end

Copilot uses AI. Check for mistakes.
Comment on lines +27 to +31
env::verify(LC_IMAGE_ID, &light_client_proof.lc_journal).unwrap();

let light_client_circuit_output = deserialize_circuit_output(&light_client_proof.lc_journal);
let light_client_circuit_output: LightClientCircuitOutput =
borsh::from_slice(light_client_proof.lc_journal.as_slice())
.expect("Failed to deserialize light client circuit output");
Copy link

Copilot AI Oct 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid unwrap() here; use expect with a clear message (as you already do for deserialization) so failures include context, or consider returning a Result from this function instead of panicking.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

F-deposit-replace-needed Flag: Deposit replacements are needed. This will change Txids.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants