service.rs
Overview
This file implements the BlockProcessorService, a core component responsible for processing candidate blocks within a thread of the blockchain. The service manages block validation, attestation processing, signature verification, and the application of blocks to the optimistic state repository. It interacts closely with other system components such as the block state repository, network services, validation services, and shared services to ensure blocks are correctly validated, finalized, and integrated into the chain.
The service operates in a dedicated thread and continuously processes unfinalized blocks, managing their lifecycle from reception through validation and finalization, including handling cross-thread references and synchronization.
Main Structures and Functions
BlockProcessorService
Description
The main service struct that encapsulates the block processing thread handle and a flag indicating whether missing blocks were requested.
Fields
service_handler: std::thread::JoinHandle<()>
Handle for the spawned thread running the block processing loop.missing_blocks_were_requested: Arc<AtomicBool>
Atomic flag shared across the service indicating if missing blocks have been requested.
Methods
new
pub fn new(
security_guarantee: SecurityGuarantee,
node_id: NodeIdentifier,
time_to_produce_block: Duration,
save_state_frequency: u32,
bls_keys_map: Arc<Mutex<HashMap<PubKey, (Secret, RndSeed)>>>,
thread_identifier: ThreadIdentifier,
block_state_repository: BlockStateRepository,
repository: RepositoryImpl,
shared_services: SharedServices,
nack_set_cache: Arc<Mutex<FixedSizeHashSet<UInt256>>>,
send_direct_tx: NetDirectSender<NodeIdentifier, NetworkMessage>,
broadcast_tx: NetBroadcastSender<NetworkMessage>,
skipped_attestation_ids: Arc<Mutex<HashSet<BlockIdentifier>>>,
block_gap: BlockGap,
validation_service: ValidationServiceInterface,
share_service: ExternalFileSharesBased,
send: AckiNackiSend,
chain_pulse_monitor: std::sync::mpsc::Sender<ChainPulseEvent>,
unprocessed_blocks_cache: UnfinalizedCandidateBlockCollection,
cross_thread_ref_data_availability_synchronization_service: CrossThreadRefDataAvailabilitySynchronizationServiceInterface,
save_optimistic_service_sender: InstrumentedSender<Arc<OptimisticStateImpl>>,
) -> Self
Creates and starts the block processing service thread.
Parameters:
security_guarantee: Defines the acceptable probability threshold against successful attacks.node_id: Identifier for the local node.time_to_produce_block: Expected duration to produce a block.save_state_frequency: Frequency to persist state snapshots.bls_keys_map: Map of public keys to secret keys and random seeds for signature operations.thread_identifier: Identifier for the blockchain thread to process.block_state_repository: Repository for block states.repository: Main data repository implementation.shared_services: Shared services like metrics and cross-thread reference data service.nack_set_cache: Cache of NACKed blocks' hashes.send_direct_tx: Channel to send direct network messages.broadcast_tx: Channel to broadcast network messages.skipped_attestation_ids: Set of attestation IDs to skip.block_gap: Gap parameter for block production.validation_service: Service interface for block validation.share_service: Service managing external file shares.send: Interface to send ACKs and NACKs.chain_pulse_monitor: Channel to send chain pulse events.unprocessed_blocks_cache: Cache of unfinalized candidate blocks.cross_thread_ref_data_availability_synchronization_service: Service for cross-thread reference synchronization.save_optimistic_service_sender: Channel to send optimistic state snapshots for saving.
Returns:
Returns a new instance ofBlockProcessorServicewith the processing thread running asynchronously.Usage Example:
let service = BlockProcessorService::new(
security_guarantee,
node_id,
time_to_produce_block,
save_state_frequency,
bls_keys_map,
thread_identifier,
block_state_repository,
repository,
shared_services,
nack_set_cache,
send_direct_tx,
broadcast_tx,
skipped_attestation_ids,
block_gap,
validation_service,
share_service,
send,
chain_pulse_monitor,
unprocessed_blocks_cache,
cross_thread_ref_data_availability_synchronization_service,
save_optimistic_service_sender,
);
SecurityGuarantee
Description
Represents a security guarantee as a floating-point number indicating the chance of a successful attack.
Fields
f64- Private field representing the probability.
Methods
from_chance_of_successful_attack(p: f64) -> Self
Creates aSecurityGuaranteefrom a given probabilitypof a successful attack.
Constraints:pmust be between 0.0 and 1.0 inclusive.chance_of_successful_attack(&self) -> f64
Returns the stored probability value.
calculate_v_parameter
fn calculate_v_parameter(
attestation_target_in_bkset_size: usize,
chance_of_successful_attack: f64,
bk_set_size: usize,
) -> f64
Calculates the expected number of acki-nacki (acknowledgment/nacknowledgment) messages v based on the attestation target, attack probability, and block keeper set size.
Parameters:
attestation_target_in_bkset_size: Number of attestations required.chance_of_successful_attack: Probability of a successful attack (fromSecurityGuarantee).bk_set_size: Size of the block keeper set.
Returns:
A floating-point number representing the expected number of acki-nacki messages.Implementation Details:
Uses a formula derived from the expected fraction of malicious block keepers and the probability of attack to computev.
process_candidate_block
fn process_candidate_block(
security_guarantee: SecurityGuarantee,
node_id: NodeIdentifier,
save_state_frequency: u32,
bls_keys_map: Arc<Mutex<HashMap<PubKey, (Secret, RndSeed)>>>,
block_state: &BlockState,
block_state_repository: &BlockStateRepository,
repository: &RepositoryImpl,
shared_services: &mut SharedServices,
nack_set_cache: Arc<Mutex<FixedSizeHashSet<UInt256>>>,
skipped_attestation_ids: &Arc<Mutex<HashSet<BlockIdentifier>>>,
candidate_block: &Envelope<GoshBLS, AckiNackiBlock>,
validation_service: &ValidationServiceInterface,
time_to_produce_block: &Duration,
share_service: ExternalFileSharesBased,
send: AckiNackiSend,
chain_pulse_monitor: &Sender<ChainPulseEvent>,
cross_thread_ref_data_availability_synchronization_service: &mut CrossThreadRefDataAvailabilitySynchronizationServiceInterface,
save_optimistic_service_sender: &InstrumentedSender<Arc<OptimisticStateImpl>>,
filter_prehistoric: &FilterPrehistoric,
) -> anyhow::Result<()>
Processes an individual candidate block, including validation, signature verification, attestation processing, optimistic state application, and finalization steps.
Parameters:
security_guarantee: Security parameters for consensus guarantees.node_id: Local node identifier.save_state_frequency: Frequency to save state snapshots.bls_keys_map: BLS keys for signing and verification.block_state: The mutable state of the candidate block.block_state_repository: Repository to fetch other block states.repository: Repository interface for blockchain data.shared_services: Access to shared metrics and services.nack_set_cache: Cache of bad block identifiers.skipped_attestation_ids: Set of attestation IDs to ignore.candidate_block: The candidate block enveloped with signatures.validation_service: Service to which block validation requests are sent.time_to_produce_block: Expected block production duration.share_service: Service to save and share external file states.send: Interface to send ACKs/NACKs.chain_pulse_monitor: Channel for chain pulse events.cross_thread_ref_data_availability_synchronization_service: Service handling cross-thread references.save_optimistic_service_sender: Channel to send optimistic state snapshots for persistent saving.filter_prehistoric: Filter to exclude prehistoric blocks.
Returns:
Ananyhow::Result<()>indicating success or failure of processing.Usage Example:
process_candidate_block(
security_guarantee,
node_id,
save_state_frequency,
bls_keys_map,
block_state,
&block_state_repository,
&repository,
&mut shared_services,
nack_set_cache,
&skipped_attestation_ids,
candidate_block,
&validation_service,
&time_to_produce_block,
share_service,
send,
&chain_pulse_monitor,
&mut cross_thread_ref_data_availability_synchronization_service,
&save_optimistic_service_sender,
&filter_prehistoric,
)?;
Implementation Details:
Validates block sequence numbers and heights against the parent block.
Performs common block parameter checks including producer correctness and thread table validation.
Verifies block and attestation signatures.
Sets block statistics and attestation targets based on finalized ancestor blocks.
Processes block attestations and updates finalization proofs.
Handles cross-thread reference data availability checks.
Applies the block to the optimistic state and manages state saving conditions.
Sends validation requests to the validation service if necessary.
Interacts with chain pulse monitoring for block lifecycle events.
verify_all_block_signatures
pub(crate) fn verify_all_block_signatures(
block_state_repository: &BlockStateRepository,
candidate_block: &Envelope<GoshBLS, AckiNackiBlock>,
block_state: &BlockState,
skipped_attestation_ids: &Arc<Mutex<HashSet<BlockIdentifier>>>,
) -> Option<bool>
Verifies the producer's signature on the block envelope and the signatures on all block attestations within the common section.
Parameters:
block_state_repository: Repository for accessing block states.candidate_block: The candidate block envelope to verify.block_state: The state of the candidate block.skipped_attestation_ids: Identifiers of attestations to skip verification.
Returns:
Some(true)if all signatures are valid.Some(false)if any signature is invalid.Noneif verification cannot be completed (e.g., missing data).
Implementation Details:
Checks if the producer's signature verification status is cached.
Performs signature verification using the block keeper's public keys.
Verifies that the producer stated in the common section has a valid signature.
Verifies all attestations' signatures that have not been previously verified.
Updates the block state with verification results and timing metrics.
check_common_block_params
fn check_common_block_params(
candidate_block: &Envelope<GoshBLS, AckiNackiBlock>,
parent_block_state: &BlockState,
_time_to_produce_block: &Duration,
block_state: &BlockState,
) -> anyhow::Result<bool>
Performs basic validation checks on the candidate block against its parent, including sequence number, block height, and producer selection.
Parameters:
candidate_block: Candidate block to check.parent_block_state: State of the parent block._time_to_produce_block: Duration expected for block production (not fully used).block_state: State of the candidate block.
Returns:
Ok(true)if checks pass,Ok(false)if any check fails, or an error if data is missing.Implementation Details:
Ensures the candidate block's sequence number is strictly greater than the parent's.
Validates the block height is the next expected height in the thread.
Validates the producer is correct according to the producer selector.
Checks for duplicate entries in the threads table.
Validates block hash integrity.
process_block_attestations
fn process_block_attestations(
block_state: &BlockState,
parent_block_state: &BlockState,
block_state_repository: &BlockStateRepository,
candidate_block: &Envelope<GoshBLS, AckiNackiBlock>,
validation_service: &ValidationServiceInterface,
chain_pulse_monitor: &Sender<ChainPulseEvent>,
filter_prehistoric: &FilterPrehistoric,
shared_services: &SharedServices,
) -> anyhow::Result<bool>
Processes block attestations, updating finalization checkpoints, setting prefinalization and finalization proofs, and managing fallback attestation states.
Parameters:
block_state: The candidate block state.parent_block_state: The parent block state.block_state_repository: Repository of block states.candidate_block: Candidate block envelope.validation_service: Service for validation requests.chain_pulse_monitor: Channel to send chain pulse events.filter_prehistoric: Filter to exclude prehistoric blocks.shared_services: Access to shared metrics and services.
Returns:
Ok(true)if attestations are processed successfully,Ok(false)if processing cannot proceed, or an error.Implementation Details:
Uses ancestor blocks finalization checkpoints to determine which attestations passed or failed.
Invalidates blocks if attestation targets are not met.
Updates finalization proofs for primary and fallback attestations.
Sends chain pulse events for prefinalized blocks.
Updates block state with finalized blocks and attestation interests.
Marks attestations as processed.
Important Implementation Details and Algorithms
Chain Pulse Management:
The service uses theChainPulsecomponent to monitor blockchain progress and trigger attestation resends, retry missing blocks, and detect finalization stalls.Optimistic State Application:
Blocks are applied to anOptimisticStateImplinstance, representing a speculative state that can be saved or discarded based on consensus progress.Signature Verification:
Block and attestation signatures are verified against the block keeper set's public keys to ensure authenticity and integrity.Finalization Checkpoints:
The file uses ancestor blocks' finalization checkpoints to determine the status of attestations and finalize blocks accordingly.Attestation Target Calculation:
The service calculates primary and fallback attestation targets based on the size of the block keeper set and the security guarantee, adjusting validation requirements dynamically.Cross-Thread Reference Data Synchronization:
Blocks requiring cross-thread references synchronize missing data before proceeding, ensuring consistency across parallel threads.Metrics and Monitoring:
The service reports various metrics such as processing delays, validation times, attestation counts, and message queue lengths to shared metrics services.
Interaction with Other System Components
BlockStateRepository:
Used extensively to fetch and update the state of blocks, including parent and ancestor blocks.RepositoryImpl:
Provides access to persistent blockchain data and optimistic states.SharedServices:
Offers access to shared utilities like metrics, cross-thread data services, and other system-wide services.ValidationServiceInterface:
The service sends blocks that require full validation to this interface for asynchronous processing.Network Channels (
NetDirectSender,NetBroadcastSender):
Used to send direct and broadcast network messages related to block propagation and synchronization.UnfinalizedCandidateBlockCollection:
Maintains a cache of candidate blocks waiting to be processed and finalized.CrossThreadRefDataAvailabilitySynchronizationServiceInterface:
Synchronizes availability of cross-thread referenced data required by candidate blocks.ExternalFileSharesBased:
Manages saving and sharing of external file state resources.ChainPulseEvent Channel:
Used to notify other system components about block lifecycle events such as prefinalization and application.
Visual Diagram of BlockProcessorService Structure and Workflow
flowchart TD
A[BlockProcessorService] --> B[New Service Thread]
B --> C[Main Loop: Process Unfinalized Blocks]
C --> D[Remove Finalized/Invalidated Blocks]
C --> E[Fetch Last Finalized Block]
C --> F[Pulse ChainPulse]
C --> G[Clone Unprocessed Blocks Queue]
G --> H[Iterate Candidate Blocks]
H --> I["process_candidate_block()"]
I --> J[Check Common Block Params]
I --> K[Verify Signatures]
I --> L[Process Block Attestations]
I --> M[Apply Block to Optimistic State]
I --> N[Send Validation Requests]
I --> O[Handle Cross-Thread Ref Data]
I --> P[Update Metrics]
This flowchart outlines the main workflow inside the spawned thread of the BlockProcessorService, showing the processing of unfinalized blocks including validation, attestation processing, application, and interaction with other services.
Additional Notes
The file uses concurrency primitives like
Arc,Mutex, andAtomicBoolto ensure thread-safe access to shared data structures.The service emphasizes robustness by handling partial failures gracefully (e.g., skipping blocks if parent states are unavailable).
It adheres to strict validation rules, including producer correctness, sequence ordering, and signature authenticity, crucial for blockchain consensus.
The service integrates with telemetry and tracing for detailed monitoring and debugging.
It includes constants like MAX_ATTESTATION_TARGET_BETA to configure attestation behavior and thresholds.
For related concepts, see topics such as Block State Management, Attestation Processing, Signature Verification, and Consensus Mechanisms.