node.rs
Overview
This file implements the main entry point and core runtime logic for the Acki-Nacki node, which is a critical component responsible for participating in the blockchain network. It manages node initialization, configuration loading, network setup, block processing, validation, threading, and graceful shutdown. The node coordinates multiple services and threads to maintain the blockchain state, process blocks, handle attestation, and communicate with other nodes through gossip and network protocols.
The file contains the Args struct for command-line argument parsing, initialization routines, an asynchronous main runtime using Tokio, and various helper functions. It orchestrates the interaction between networking, storage, cryptographic keys, block producers, validators, and HTTP APIs.
Main Entities and Functions
Args Struct
Purpose: Defines command-line arguments for the node executable.
Fields:
config_path: PathBuf— Path to the node configuration file.clear_missing_block_locks: bool— Whether to clear missing block locks on startup (default true).check_zerostate_validity: bool— Whether to verify the zerostate validity (default true).
Usage example:
let args = Args::parse();
println!("Config file: {:?}", args.config_path);
main() -> Result<(), std::io::Error>
Purpose: The synchronous entry point of the application.
Initializes runtime environment, optionally sets up Rayon thread affinity.
Creates a Tokio multi-threaded runtime and calls the asynchronous
tokio_main()function.Exits the process with code 0 after completion.
tokio_main()
Purpose: The asynchronous main runtime function.
Parses command line arguments.
Initializes tracing and metrics.
Invokes the core
execute()function, handling errors and shutdown.Calls
shutdown_tracing()to finalize tracing resources.
execute(args: Args, metrics: Option<Metrics>) -> anyhow::Result<()>
Purpose: Core asynchronous execution function that performs the node startup and runs its services.
Parameters:
args— Parsed command-line arguments.metrics— Optional metrics collector.
Returns: Result indicating success or failure.
Main responsibilities:
Loads the node configuration and network/gossip settings.
Initializes durable storage (Aerospike, LRU cache) for messages, cross references, and action locks.
Loads and optionally verifies the blockchain zerostate.
Sets up block keeper set (
bk_set) and channels for configuration reloads and shutdown signals.Starts the gossip protocol and network layer with the configured transport.
Spawns the block manager server that listens for incoming raw blocks.
Handles signals (SIGHUP for hot reload, SIGINT/SIGTERM for shutdown).
Initializes routing and node threads for each blockchain thread in the zerostate.
Starts HTTP server exposing APIs for external interaction.
Optionally starts message router if configured via environment.
Runs heartbeat thread, deadlock detection (if enabled), state saving services.
Gracefully handles shutdown triggered by signals or service failures.
This function orchestrates almost all major components and threads of the node.
verify_zerostate(zs: &ZeroState, message_db: &MessageDurableStorage) -> anyhow::Result<()>
Purpose: Validates the consistency and correctness of the blockchain zerostate.
Parameters:
zs— Loaded zerostate.message_db— Durable message storage instance.
Returns: Result indicating success or detailed error on failure.
Checks performed:
Ensures no duplicated messages exist in the zerostate across all thread states.
Verifies the presence and correctness of DApp configuration accounts (specifically DAppIdentifier::ZERO).
Checks that the
is_unlimitflag in the config data is set to true.Skips secondary DAppIdentifier::ONE check because it may be absent in test networks.
dispatch_hot_reload(...)
Purpose: Monitors configuration and block keeper set channels for hot reload events.
Updates network and gossip configurations dynamically on changes.
Listens for shutdown signals to terminate the loop.
Runs asynchronously in its own Tokio task.
clear_missing_block_locks(...) -> anyhow::Result<HashMap<ThreadIdentifier, ActionLockCollection>>
Purpose: Cleans up stale or missing block locks that no longer correspond to unfinalized blocks.
Parameters:
repository_impl— Repository interface for block metadata.block_state_repository— Access to stored block states.unfinalized_blocks— Map of thread IDs to their unfinalized candidate blocks.action_lock_db— Storage interface for action locks.action_lock_data_dir— Filesystem path for action lock data.
Returns: A map from thread identifiers to their cleaned action lock collections.
Algorithm:
Iterates over all threads and their metadata.
For each thread, finds the last prefinalized block.
Traverses the children blocks within a certain check distance.
Removes locks for blocks that are not present in unfinalized sets.
Ensures data consistency between in-memory and persistent action lock storage.
into_external_message(message: tvm_block::Message, thread_id: ThreadIdentifier) -> anyhow::Result<NetworkMessage>
Purpose: Converts a TVM message into a network external message suitable for broadcasting.
Parameters:
message— The TVM message to be wrapped.thread_id— The thread identifier this message belongs to.
Returns: A
NetworkMessage::ExternalMessagewith the wrapped message or an error if the message is internal.
resolve_bp(...) -> ResolvingResult
Purpose: Resolves the block producer node(s) responsible for a given thread.
Parameters:
thread_id— Thread to resolve block producer for.repo— Reference to the repository.nodes_rx— Receiver holding current known peer nodes.node_id— The current node's identifier.
Returns:
ResolvingResultindicating if the current node is the block producer and list of addresses.
debug_used_features()
Prints enabled compile-time features and environment variables related to tracing, metrics, and node verbosity.
Important Implementation Details
Uses Tokio runtime for asynchronous concurrency and multi-threading.
Integrates Aerospike as durable storage backend with LRU cache layering.
Employs multiple Tokio channels and
tokio::sync::watchfor configuration changes, shutdown signaling, and inter-thread communication.Implements a sophisticated block state repository and optimistic state saving mechanisms.
Runs an HTTP server exposing APIs for account queries, message retrieval, and block producer resolution.
Supports hot reload of TLS certificates and node configuration on SIGHUP signal.
Manages concurrency using
Arc,Mutex, and atomic primitives for shared state.Uses specialized services for routing, gossiping, block processing, validation, attestation sending, and authority switching.
Contains deadlock detection support (conditional compilation).
The node operates across multiple blockchain threads, each running an instance of the
Nodestruct representing the operational logic per thread.Uses cryptographic BLS keys for signing and verification.
Applies action lock collections to prevent conflicting operations on blocks.
Handles external messages and integrates with external state sharing via blob sync.
Interactions with Other Parts of the System
node::node::Node — Core node instance per blockchain thread; this file creates and manages these.
node::repository::RepositoryImpl — Persistent blockchain data repository used extensively.
node::block::producer::process::TVMBlockProducerProcess — Block production engine used in node threads.
node::node::services::block_processor::service::BlockProcessorService — Service handling block processing logic.
node::node::services::validation::service::ValidationService — Validation logic service for blocks and messages.
network::network::BasicNetwork — Network layer abstraction created and started here.
gossip — Gossip protocol is started and configured here.
http_server::WebServer — HTTP API server exposing node data and control endpoints.
message_router::MessageRouter — Optional message routing service started based on environment variable.
node::helper::init_tracing / shutdown_tracing — Initializes and cleans up telemetry/tracing.
node::storage:: and node::types:: modules** — Used for managing blockchain data structures and storage.
transport_layer::msquic::MsQuicTransport — Network transport used by the node.
ext_messages_auth::auth::AccountRequest — Channel for external account query requests.
node::protocol::authority_switch — Authority switching mechanism for block production rights.
node::utilities::guarded::Guarded / GuardedMut — For safe concurrent access to mutable data.
Visual Diagram: Class and Major Structs Interaction
classDiagram
class Node {
+new()
+execute()
}
class Args {
+config_path: PathBuf
+clear_missing_block_locks: bool
+check_zerostate_validity: bool
}
class RepositoryImpl {
+load_saved_blocks()
+select_thread_last_finalized_block()
+get_all_metadata()
}
class BlockStateRepository {
+get()
}
class Authority {
+builder()
+get_thread_authority()
}
class ValidationService {
+new()
+interface()
}
class BlockProcessorService {
+new()
}
class TVMBlockProducerProcess {
+builder()
+build()
}
class RoutingService {
+new()
+start()
}
class GossipHandle {
+with_chitchat()
}
class BasicNetwork {
+new()
+start()
}
class MessageDurableStorage {}
class ActionLockCollection {
+new()
+get()
+remove()
}
Node --> RepositoryImpl : uses
Node --> ValidationService : uses
Node --> BlockProcessorService : uses
Node --> TVMBlockProducerProcess : uses
Node --> Authority : holds
Node --> RoutingService : interacts
RoutingService --> BasicNetwork : uses
BasicNetwork --> GossipHandle : uses
RepositoryImpl --> BlockStateRepository : uses
RepositoryImpl --> ActionLockCollection : manages
execute o-- Args : reads
execute --> RepositoryImpl : creates
execute --> BlockStateRepository : creates
execute --> Authority : creates
execute --> ValidationService : creates
execute --> GossipHandle : creates
execute --> BasicNetwork : creates
Usage Flow (Simplified)
Startup:
main()initializes runtime and callstokio_main().Argument Parsing:
Args::parse()reads command-line options.Tracing & Metrics: Initialize observability.
Configuration Loading: Load node, network, gossip, and Aerospike configs.
Storage Initialization: Setup durable stores, caches, block state repositories.
Zerostate Loading & Verification: Load blockchain zerostate, verify integrity.
Network & Gossip Start: Start gossip and network layers.
Signal Handling: Spawn thread to handle SIGHUP (reload), SIGINT/SIGTERM (shutdown).
Routing & Node Threads: Start routing and spawn a
Nodeinstance per blockchain thread.Services Startup: Start block processor, validation, attestation, HTTP server, message router.
Runtime Operation: Node runs asynchronously, processing blocks, syncing state, handling messages.
Shutdown: On signal, cleanly shutdown services, save state, and exit.
References
For command-line argument parsing details see clap::Parser.
For blockchain data structures and repository management see
node::repository::RepositoryImpl.For block processing and production logic see
node::block::producer::process::TVMBlockProducerProcess.Networking and gossip protocol details are in
network::network::BasicNetworkandgossip.For attestation and validation services see
node::node::services::validation::service::ValidationService.For concurrency primitives and guarded data see
node::utilities::guarded::Guarded.For cryptographic key handling see
node::bls::GoshBLS.For zero state structure and validation see node::zerostate::ZeroState.
For HTTP server and APIs see
http_server::WebServer.
This file is the orchestrator and runtime core that integrates multiple components and services into a working blockchain node instance capable of syncing, producing, validating, and serving blockchain data in a distributed network environment.