fold.rs
Overview
This file provides functionality to fold multiple BLS-signed attestations into a single aggregated attestation envelope. Folding is an operation that aggregates multiple individual signatures and their associated signer information into one combined signature. This reduces overhead and improves efficiency when handling attestations in consensus or validation protocols.
The main public function is try_fold, which attempts to fold a list of signatures with their signer occurrences optimistically first, and if that fails, falls back to a more granular one-by-one folding with signature verification. The result indicates the successfully folded envelope (if any) and the set of "poisoned" envelopes that failed verification or merging.
This file interacts primarily with:
BlockKeeperSet(from the block keeper system) for retrieving public keys for signature verification.EnvelopeandGoshBLStypes for signature aggregation, envelope creation, and verification.The attestation-related types like
AttestationDataandSignerIndex.
The folding process is critical in aggregating attestations securely and efficiently in the broader consensus or attestation processing system.
Structs
TryFoldResult
pub struct TryFoldResult {
pub folded: Option<Envelope<GoshBLS, AttestationData>>,
pub poisoned: Vec<Envelope<GoshBLS, AttestationData>>,
}
Purpose: Represents the outcome of trying to fold multiple attestations.
Fields:
folded: An optional aggregatedEnvelopeif folding succeeded.poisoned: A vector of individual envelopes that failed verification or merging.
Usage: Returned by
try_foldandtry_fold_one_by_one_checkedto indicate folding success and failures.
Functions
try_fold
pub fn try_fold(
attestation_data: AttestationData,
to_combine: Vec<(HashMap<SignerIndex, u16>, Signature)>,
bk_set: &BlockKeeperSet,
) -> TryFoldResult
Purpose: Attempts to fold multiple attestations into one aggregated envelope.
Parameters:
attestation_data: The common attestation data all signatures pertain to.to_combine: A vector of tuples, each containing aHashMapof signer indices with their occurrence counts and a corresponding BLSSignature.bk_set: Reference toBlockKeeperSetproviding public keys for verification.
Returns: A
TryFoldResultwith either a folded envelope or a list of poisoned envelopes.Behavior:
Tries optimistic folding by aggregating all signatures at once (
try_fold_all_optimistic).If optimistic folding fails, falls back to verifying and folding one-by-one (
try_fold_one_by_one_checked).
Example:
let result = try_fold(attestation_data, signatures_to_combine, &block_keeper_set); if let Some(folded_envelope) = result.folded { // Use folded envelope } else { // Handle poisoned envelopes in result.poisoned }
try_fold_all_optimistic
fn try_fold_all_optimistic(
attestation_data: AttestationData,
to_combine: &[(HashMap<SignerIndex, u16>, Signature)],
bk_set: &BlockKeeperSet,
) -> Option<Envelope<GoshBLS, AttestationData>>
Purpose: Attempts to fold all signatures optimistically by merging them all at once without intermediate verification.
Parameters:
attestation_data: The attestation data common to all signatures.to_combine: Slice of tuples with signer occurrences and signatures to combine.bk_set: Reference to the block keeper set for public keys.
Returns:
Some(Envelope)if successful and verified, otherwiseNone.Implementation Details:
Aggregates all signer occurrences by summing counts.
Calls
GoshBLS::merge_allto merge all signatures into one aggregated signature.Creates an
Envelopewith the aggregated signature and occurrences.Verifies signatures using the public keys.
Returns the folded envelope only if verification passes.
Usage: Used internally by
try_foldfor fast-path folding.
try_fold_one_by_one_checked
fn try_fold_one_by_one_checked(
attestation_data: AttestationData,
to_combine: Vec<(HashMap<SignerIndex, u16>, Signature)>,
bk_set: &BlockKeeperSet,
) -> TryFoldResult
Purpose: Performs folding by incrementally folding and verifying each signature one at a time.
Parameters:
attestation_data: The common attestation data.to_combine: Vector of signer occurrences and signatures.bk_set: Reference to block keeper set for public keys.
Returns: A
TryFoldResultwith the folded envelope if any and a list of poisoned envelopes.Implementation Details:
Iterates over all signatures.
Creates an envelope for each signature and verifies it.
If verification succeeds:
If there is already a folded envelope, tries to merge current signature into it.
Updates the aggregated signature occurrences accordingly.
If verification fails or merge fails, adds the envelope to poisoned vector.
Uses
GoshBLS::mergeto merge signatures incrementally.
Usage: Fallback method used by
try_foldwhen optimistic merge fails.Example:
let result = try_fold_one_by_one_checked(attestation_data, signatures, &block_keeper_set); if let Some(agg) = result.folded { // Handle aggregated signature } for bad_env in result.poisoned { // Log or discard poisoned envelopes }
Important Implementation Details
Signature Aggregation and Verification: The folding depends heavily on BLS signature aggregation properties provided by the
GoshBLSscheme. This allows multiple signatures over the same message to be merged into one signature.Signer Occurrence Tracking: Signer indices and their occurrence counts (as
u16) are aggregated to keep track of which signers contributed to the folded signature. This is crucial for verifying the correctness and provenance of the aggregated signature.Optimistic vs. Checked Folding: The two-step approach attempts a fast aggregation first, then falls back to a more robust and slower verification/merging process ensuring data integrity.
Error Handling: Verification errors or merging failures cause envelopes to be marked as poisoned, preventing invalid data from being folded into the aggregate.
Use of
Envelope: TheEnvelopeabstraction encapsulates the signature, signer occurrences, and attestation data, providing methods for creation and verification.
Interactions with Other System Components
BlockKeeperSet: Used to obtain public keys by signer indexes for signature verification (
bk_set.get_pubkeys_by_signers()).Envelope: Represents the data structure that holds aggregated signatures and signer information; folding creates or modifies
Envelopeinstances.GoshBLS: Signature scheme used to merge and verify BLS signatures.
AttestationData & SignerIndex: Types representing the attestation content and the identities of signers involved in the signature.
These dependencies indicate this file is part of a larger attestation and consensus subsystem responsible for signature aggregation and verification.
Visual Diagram
flowchart TD
A[try_fold] --> B[try_fold_all_optimistic]
B -->|Success| C[Return folded Envelope]
B -->|Fail| D[try_fold_one_by_one_checked]
D --> E[Iterate signatures]
E --> F{Verify signature}
F -->|Ok| G{Folded envelope exists?}
G -->|Yes| H[Merge signature into folded envelope]
G -->|No| I[Set folded envelope = current envelope]
F -->|Fail| J[Add envelope to poisoned list]
D --> K[Return TryFoldResult with folded & poisoned]
subgraph Inputs
attestation_data
to_combine
bk_set
end
subgraph Outputs
TryFoldResult
end
A --> Outputs