parse_block_accounts_and_messages.rs

Overview

This file provides functionality to extract and organize data related to account activities and internal messages from a blockchain block structure (AckiNackiBlock). It primarily focuses on gathering information needed for post-processing updates after a block has been processed optimistically. The main method implemented extends the AckiNackiBlock struct with the ability to compute:

This processing is essential for maintaining the optimistic state consistency and for routing messages correctly within the system.

Key Structures and Types

Detailed Explanation of get_data_for_postprocessing

Signature

pub fn get_data_for_postprocessing(
    &self,
    initial_optimistic_state: &mut OptimisticStateImpl,
    updated_shard_state: Arc<ShardStateUnsplit>,
) -> anyhow::Result<(
    HashMap<AccountAddress, HashSet<MessageIdentifier>>,
    HashMap<AccountAddress, Vec<(MessageIdentifier, Arc<WrappedMessage>)>>,
    HashMap<AccountRouting, Option<WrappedAccount>>,
    HashMap<AccountRouting, Vec<(MessageIdentifier, Arc<WrappedMessage>)>>,
)>

Parameters

Return Value

Returns a Result containing a tuple of four collections upon success:

  1. Consumed Internal Messages:
    HashMap<AccountAddress, HashSet<MessageIdentifier>>
    Maps each account address to a set of identifiers of internal messages it has consumed during block processing.

  2. Produced Internal Messages to Current Thread:
    HashMap<AccountAddress, Vec<(MessageIdentifier, Arc<WrappedMessage>)>>
    Maps each account address to a list of tuples, each containing an internal message identifier and the wrapped message, representing produced internal messages routed within the current optimistic state thread.

  3. Accounts That Changed dApp ID:
    HashMap<AccountRouting, Option<WrappedAccount>>
    Maps each account routing (dApp ID + account address) to an optional wrapped account if the account changed its dApp identifier during block processing. If the account is missing, the value is None.

  4. Produced Internal Messages to Other Threads:
    HashMap<AccountRouting, Vec<(MessageIdentifier, Arc<WrappedMessage>)>>
    Maps each account routing to a list of produced internal messages that belong to other optimistic state threads, i.e., messages that do not belong to the current optimistic state.

Processing Steps and Implementation Details

  1. Initialize Data Structures:
    Four HashMaps to store consumed messages, accounts with changed dApp IDs, produced messages to current thread, and produced messages to other threads are created.

  2. Read Block Extra Metadata:
    The method reads the extra data from the underlying block to access message descriptors:

    • Out Message Descriptor: Iterates over all outgoing messages in the block, extracting those with internal destination accounts. For each message:

      • Extract internal header and destination account ID.

      • Construct an AccountRouting from dApp ID (or fallback to default) and destination account.

      • Wrap the message and create a MessageIdentifier.

      • Append the message to the produced_internal_messages map keyed by AccountRouting.

    • In Message Descriptor: Iterates over all incoming messages, extracting internal headers and destination account addresses. Each message is identified and inserted into the consumed_internal_messages set for the destination account.

  3. Parse Account Blocks for dApp ID Changes:
    Iterates over account blocks within the main block extra data to detect accounts that changed their dApp IDs. For each account block:

    • If the dApp ID changed, the method retrieves the account from the updated shard state.

    • Constructs an AccountRouting based on the new dApp ID (or defaults).

    • Inserts the routing and either a wrapped account or None if missing in the accounts_that_changed_their_dapp_id map.

  4. Split Produced Internal Messages Based on Routing Ownership:
    Divides the collected produced internal messages into two groups based on whether the routing belongs to the current optimistic state thread:

    • Messages belonging to the current thread are keyed in the produced_internal_messages_to_the_current_thread map using only the account address.

    • Messages belonging to other threads are stored in produced_internal_messages_to_other_threads keyed by the full AccountRouting.

  5. Return Collected Data:
    Returns all four data structures wrapped in Ok.

Error Handling

Usage Example

let mut optimistic_state = ...; // Obtained from optimistic state management
let updated_shard_state = Arc::new(...); // Snapshot after block execution
let block: AckiNackiBlock = ...; // The block to post-process

let result = block.get_data_for_postprocessing(&mut optimistic_state, updated_shard_state)?;
let (
    consumed_messages,
    produced_messages_current_thread,
    accounts_with_dapp_changes,
    produced_messages_other_threads,
) = result;

// Further processing with these collections...

Interaction With Other System Components

This file serves as a crucial bridge between raw block data and the optimistic state management system, enabling accurate message routing and account state tracking after block execution.


Mermaid Diagram

flowchart TD
A[AckiNackiBlock] -->|get_data_for_postprocessing| B[Read Block Extra]
B --> C[Read Out Message Descriptor]
B --> D[Read In Message Descriptor]
B --> E[Read Account Blocks]
C --> F[Extract Produced Internal Messages]
D --> G[Extract Consumed Internal Messages]
E --> H[Detect Accounts with dApp ID Changes]
F --> I{Routing Ownership Check}
I -->|Belongs Current Thread| J[Produced Messages To Current Thread]
I -->|Belongs Other Threads| K[Produced Messages To Other Threads]
subgraph Outputs
G[Consumed Internal Messages]
J[Produced Internal Messages To Current Thread]
H[Accounts That Changed dApp ID]
K[Produced Internal Messages To Other Threads]
end
get_data_for_postprocessing-->|Returns|Outputs