-
Notifications
You must be signed in to change notification settings - Fork 28
[DONT MERGE] CI for hotfix #1178
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this 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.
| 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 { |
Copilot
AI
Oct 6, 2025
There was a problem hiding this comment.
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.
| ) | ||
| .wrap_err("Failed to parse partial signature")?; | ||
|
|
||
| Ok::<_, BridgeError>((partial_sig, pub_nonces_ref[idx])) |
Copilot
AI
Oct 6, 2025
There was a problem hiding this comment.
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.
| Ok::<_, BridgeError>((partial_sig, pub_nonces_ref[idx])) | |
| Ok::<_, BridgeError>((partial_sig, pub_nonces_ref[idx].clone())) |
| 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()); | ||
| } |
Copilot
AI
Oct 6, 2025
There was a problem hiding this comment.
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.
| "MuSig2 Error: partial signature verification failed for verifiers: {}", | ||
| partial_sig_verification_errors.join(", ") | ||
| ); | ||
| tracing::error!(error_msg); |
Copilot
AI
Oct 6, 2025
There was a problem hiding this comment.
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.
| tracing::error!(error_msg); | |
| tracing::error!("{}", error_msg); |
| // 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
AI
Oct 6, 2025
There was a problem hiding this comment.
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.
| // 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()); | |
| } |
| ) | ||
| .await | ||
| .wrap_err_with(|| { | ||
| format!("While waiting for {nonce_idx} + 1th sig out of {num_required_nofn_sigs} ") |
Copilot
AI
Oct 6, 2025
There was a problem hiding this comment.
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.
| 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 | |
| ) |
| } | ||
|
|
||
| /// 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. |
Copilot
AI
Oct 6, 2025
There was a problem hiding this comment.
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'.
| /// 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. |
| } | ||
|
|
||
| /// Reroutes aggregated nonces to the signature aggregator. | ||
| /// Reroutes aggregated nonces and public nonces for each aggregatedd nonce to the signature aggregator. |
Copilot
AI
Oct 6, 2025
There was a problem hiding this comment.
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'.
| /// 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. |
| 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()); | ||
| } |
Copilot
AI
Oct 6, 2025
There was a problem hiding this comment.
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.
| let err_msg = format!( | ||
| "Expected {needed_nofn_sigs} partial signatures in nonce_distributor, got {sig_count}", | ||
| ); | ||
| tracing::error!(err_msg); |
Copilot
AI
Oct 6, 2025
There was a problem hiding this comment.
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.
| tracing::error!(err_msg); | |
| tracing::error!("{}", err_msg); |
This reverts commit 431b3de.
There was a problem hiding this 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.
| 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 |
Copilot
AI
Oct 6, 2025
There was a problem hiding this comment.
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();
| ) | ||
| .wrap_err("Failed to parse partial signature")?; | ||
|
|
||
| Ok::<_, BridgeError>((partial_sig, pub_nonces_ref[idx])) |
Copilot
AI
Oct 6, 2025
There was a problem hiding this comment.
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())).
| Ok::<_, BridgeError>((partial_sig, pub_nonces_ref[idx])) | |
| Ok::<_, BridgeError>((partial_sig, pub_nonces_ref[idx].clone())) |
| } | ||
| } | ||
|
|
||
| /// Monitors a [`tokio::task::JoinHandle`] in the background and logs it's end |
Copilot
AI
Oct 6, 2025
There was a problem hiding this comment.
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'.
| /// 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 |
| 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"); |
Copilot
AI
Oct 6, 2025
There was a problem hiding this comment.
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.
No description provided.