special_messages.rs
Overview
This file extends the BlockBuilder struct with functionality to execute a specific category of internal messages called Dapp Config messages. These messages are related to updating the configuration of decentralized applications (Dapps) within the blockchain context. The primary method execute_dapp_config_messages orchestrates the creation, distribution, execution, and management of these Dapp Config messages during block production.
The method handles:
Filtering relevant Dapp Config messages.
Creating and serializing the messages for execution.
Dispatching messages either to the current thread or to other threads based on routing.
Managing parallel execution of these messages while respecting thread and destination constraints.
Integrating the results of executed messages into the block-building process.
This file interacts closely with blockchain configuration, message routing, optimistic state management, and internal execution threading, all critical parts of the block production pipeline.
Detailed Explanation
BlockBuilder::execute_dapp_config_messages
pub(super) fn execute_dapp_config_messages(
&mut self,
blockchain_config: &BlockchainConfig,
block_unixtime: u32,
block_lt: u64,
check_messages_map: &mut Option<HashMap<AccountAddress, BTreeMap<u64, UInt256>>>,
) -> anyhow::Result<()>
Purpose
Executes all queued Dapp Config messages during block construction, ensuring that configuration updates for Dapps are processed in the current block.
Parameters
&mut self: Mutable reference to the currentBlockBuilderinstance.blockchain_config: Reference to the blockchain's configuration parameters (BlockchainConfig), used to influence execution behavior.block_unixtime: Unix timestamp representing the current block's creation time.block_lt: Logical time of the block, used for ordering and validation.check_messages_map: Optional mutable reference to a map tracking message checksums keyed by account addresses and logical times. Used for message verification or deduplication.
Returns
anyhow::Result<()>: ReturnsOk(())on success or an error if execution or message creation fails.
Functionality & Workflow
Initialization of Config Messages:
Clones
self.dapp_minted_mapto iterate over minted Dapp tokens.Filters out entries with zero minted tokens.
For each entry, retrieves corresponding credit configuration from
self.dapp_credit_map.Skips configs marked as unlimited.
Calculates the config address using
calculate_dapp_config_address.Creates a "config touch" message with current block Unix time and minted amount.
Message Routing and Caching:
Determines the destination address (
dst_addr) and forms a routing tuple (AccountRouting).Wraps the message into a
WrappedMessage.Checks if the destination belongs to the current optimistic state (thread):
If yes, caches the message in
produced_internal_messages_to_the_current_thread.Otherwise, caches it in
produced_internal_messages_to_other_threads.
Serialization and Envelope Creation:
Serializes the message.
Creates a
MsgEnvelopewith forwarding fees.Creates an
EnqueuedMsgfor scheduling.Generates an
OutMsgwith a default transaction (since these messages lack a parent transaction).Stores the
OutMsginself.out_msg_descrfor output message tracking.
Parallel Execution:
Maintains a set of active destination accounts and a queue of active external threads.
Executes messages in parallel up to the allowed
parallelization_level.Ensures no two messages targeting the same destination run simultaneously.
Uses
self.executeto run the message, passing execution time limits set to none (ExecutionTimeLimits::NO_LIMITS).Collects execution results asynchronously:
Upon completion, applies post-transaction processing with
self.after_transaction.Frees destination slots for new messages.
Loop Termination:
Continues until all config messages are executed and all threads are completed.
Logs progress at various stages for debugging and traceability.
Usage Example
let mut block_builder = BlockBuilder::new(...);
let blockchain_config = get_blockchain_config();
let block_unixtime = current_unix_time();
let block_lt = current_block_logical_time();
let mut check_messages_map = None;
block_builder.execute_dapp_config_messages(
&blockchain_config,
block_unixtime,
block_lt,
&mut check_messages_map,
)?;
Important Implementation Details
Parallel Execution Control:
The method enforces a concurrency limit (parallelization_level) to prevent oversubscription of resources and ensures that only one message per destination account is processed simultaneously. This avoids race conditions in state updates.Message Routing:
Messages are routed based on their destination; those belonging to the current thread are cached separately from those destined for other threads, enabling thread-specific execution and inter-thread coordination.Serialization and Envelope Handling:
Outgoing messages are serialized and wrapped in envelopes with forwarding fees, ensuring they conform to blockchain message standards before inclusion in the output message descriptor.Thread-safe State Updates:
The method uses synchronization primitives (e.g.,Arc) to safely share wrapped messages across threads.Error Handling:
Usesanyhow::Resultextensively to propagate errors from underlying blockchain, serialization, and execution operations with descriptive error messages.Logging and Tracing:
Employs detailed logging attraceanddebuglevels to track message processing, routing decisions, and parallel execution states.
Interactions with Other Components
BlockBuilder:
This file extends theBlockBuilderstruct, which is responsible for constructing blocks by executing transactions and internal messages.BlockchainConfig:
Provides blockchain-specific parameters needed during message execution.OptimisticState:
Used to check if a routing belongs to the current thread’s state, facilitating correct message routing.AccountAddressandAccountRouting:
Used for identifying message destinations and routing messages to appropriate threads.ExecutionTimeLimits:
Controls execution constraints for message processing.Message-related Types (
Message,WrappedMessage,OutMsg,EnqueuedMsg,MsgEnvelope):
Used for creating, wrapping, serializing, and scheduling messages for execution.calculate_dapp_config_addressandcreate_config_touch_message:
Helper functions from the Dapp config module (creditconfig::dappconfig) that create necessary addresses and messages for config updates.self.executeandself.after_transaction:
InternalBlockBuildermethods used to run and finalize message execution asynchronously.
Mermaid Diagram: Structure of execute_dapp_config_messages
flowchart TD
A[Start: execute_dapp_config_messages] --> B[Iterate dapp_minted_map]
B --> C{value != 0 and !is_unlimit?}
C -->|No| B
C -->|Yes| D[Calculate config address]
D --> E[Create config touch message]
E --> F{Destination belongs to current thread?}
F -->|Yes| G[Cache in current thread map]
F -->|No| H[Cache in other threads map]
G --> I[Serialize message & create envelope]
H --> I
I --> J[Add OutMsg to output descriptor]
J --> K[Add message to config_messages queue]
K --> L[Initialize active_destinations & active_ext_threads]
L --> M{Parallel execution loop}
M --> N[Start message execution if parallel slots available]
N --> O[Add destination to active_destinations]
O --> M
M --> P{Check completed threads}
P --> Q[Process finished thread]
Q --> R[Remove destination from active_destinations]
R --> M
M --> S{All messages executed and threads empty?}
S -->|No| M
S -->|Yes| T[End: return Ok]
This documentation provides a comprehensive breakdown of the special_messages.rs file, focusing on the execution of Dapp Config messages within the block-building process. For further details on related types such as Message, AccountAddress, and execution threading, see their respective topics: Message Structure, Account Management, and Threaded Execution Model.