transaction.rs
Overview
This file defines the data structures and serialization logic for representing blockchain transactions at varying levels of detail. It provides both a rich archival model (ArchTransaction) with nested phases of a transaction and a flattened, simplified structure (FlatTransaction) suitable for database storage or external consumption.
The file consolidates transaction phases such as credit, storage, compute, action, and bounce into serializable structs. It also implements conversion logic to transform a detailed transaction serialization set into the archival form and further into a flat representation.
The primary goal of this module is to facilitate the structured extraction, transformation, and storage of transaction data from low-level protocol representations (TransactionSerializationSet and TransactionDescr) into application-level models.
Data Structures
TransactionCredit
Represents the credit phase of a transaction.
Fields:
credit: Option<String>— The amount credited, as a string representing the number of grams.due_fees_collected: Option<String>— Fees collected that were due, as a string.
TransactionStorage
Represents the storage phase of a transaction.
Fields:
storage_fees_collected: Option<String>— Storage fees collected during the transaction.storage_fees_due: Option<String>— Storage fees that are due.status_change: Option<u8>— Status change indicator (0=Unchanged, 1=Frozen, 2=Deleted).
TransactionCompute
Represents the compute phase of a transaction.
Fields:
success: Option<bool>— Whether the compute phase succeeded.msg_state_used: Option<bool>— Whether message state was used.account_activated: Option<bool>— Whether the account was activated during computation.gas_credit: Option<u32>— Gas credit used.gas_fees: Option<String>— Gas fees paid.gas_used: Option<f64>— Gas units used.gas_limit: Option<f64>— Gas limit set.mode: Option<i8>— Compute mode.exit_arg: Option<i32>— Exit argument code.exit_code: Option<i32>— Exit status code.vm_steps: Option<u32>— Number of VM steps executed.vm_init_state_hash: Option<String>— Initial VM state hash.vm_final_state_hash: Option<String>— Final VM state hash.compute_type: u8— Type of compute phase (0 = skipped, 1 = VM).skipped_reason: Option<u8>— Reason code when compute phase skipped.
TransactionAction
Represents the action phase of a transaction.
Fields:
success: Option<bool>— Whether the action succeeded.valid: Option<bool>— Whether the action was valid.no_funds: Option<bool>— Whether the action failed due to lack of funds.status_change: Option<u8>— Status change indicator.result_arg: Option<i32>— Result argument code.result_code: Option<i32>— Result status code.tot_actions: Option<i16>— Total actions executed.spec_actions: Option<i16>— Special actions count.skipped_actions: Option<i16>— Number of skipped actions.msgs_created: Option<i16>— Number of messages created by the action.action_list_hash: Option<String>— Hash of the action list.tot_msg_size_cells: Option<f64>— Total message size in cells.tot_msg_size_bits: Option<f64>— Total message size in bits.total_action_fees: Option<String>— Total fees charged for the action.total_fwd_fees: Option<String>— Total forwarding fees.
TransactionBounce
Represents the bounce phase of a transaction.
Fields:
bounce_type: Option<i32>— Bounce type indicator (0=Negfunds, 1=Nofunds, 2=Ok).fwd_fees: Option<String>— Forwarding fees.msg_fees: Option<String>— Message fees.msg_size_bits: Option<f64>— Message size in bits.msg_size_cells: Option<f64>— Message size in cells.req_fwd_fees: Option<String>— Required forwarding fees.
ArchTransaction (Public)
The archival representation of a transaction, containing detailed nested phases.
Fields (most fields are private but exposed via conversion):
id: String— Unique transaction identifier as hex string.block_id: String— Identifier of the block containing this transaction.boc: Vec<u8>— Binary Object Code representing the transaction.bounce: Option<TransactionBounce>— Bounce phase data.status: u8— Transaction status code.credit: Option<TransactionCredit>— Credit phase data.storage: Option<TransactionStorage>— Storage phase data.compute: Option<TransactionCompute>— Compute phase data.action: Option<TransactionAction>— Action phase data.credit_first: bool— Indicates if credit phase was first.ext_in_msg_fee: Option<String>— External inbound message fee.aborted: bool— Whether the transaction was aborted.destroyed: bool— Whether the account was destroyed.tr_type: u8— Transaction type flags.lt: String— Logical time as string.prev_trans_hash: String— Previous transaction hash.prev_trans_lt: String— Previous transaction logical time.proof: Option<Vec<u8>>— Optional proof bytes.now: u32— Current timestamp.outmsg_cnt: u16— Count of outbound messages.orig_status: u8— Original status code.end_status: u8— Ending status code.in_msg: String— Incoming message hash.out_msgs: Vec<String>— Outgoing message hashes.account_addr: String— Account address owning the transaction.workchain_id: i32— Workchain identifier.total_fees: String— Total fees paid.balance_delta: String— Balance change as a string.old_hash: String— State hash before transaction.new_hash: String— State hash after transaction.chain_order: String— Chain order string.
FlatTransaction (Public)
A flattened version of ArchTransaction, used for easier serialization and database storage.
Fields:
All fields are public and represent a denormalized view by flattening nested phases into single-level fields, e.g.,
compute_success,action_valid,storage_fees_collected.Outgoing messages are serialized as JSON string.
Includes all core transaction metadata similar to
ArchTransaction.
Implementations and Functions
Conversion: From<ArchTransaction> for FlatTransaction
Transforms a nested ArchTransaction into a flattened FlatTransaction.
Behavior:
Extracts nested phase details from
TransactionCredit,TransactionStorage,TransactionCompute, andTransactionAction.Flattens optional nested fields into top-level optional fields.
Serializes outgoing message vector into JSON string.
Example Usage:
let arch_trx: ArchTransaction = ...; let flat_trx: FlatTransaction = arch_trx.into();
Conversion: From<TransactionSerializationSet> for ArchTransaction
Transforms a low-level serialized transaction (TransactionSerializationSet) into the archival model (ArchTransaction).
Process:
Extracts metadata such as transaction ID, block ID, logical time, statuses, proofs, and hashes.
Parses transaction description phases (
TransactionDescr::Ordinary) into nested structs via helper functions.Calculates fees and balances using domain-specific logic and currency collections (
SignedCurrencyCollection).Extracts inbound and outbound message hashes and fees.
Constructs account address from workchain ID and account ID.
Error Handling:
Logs errors if transaction description cannot be read.
Panics on unexpected failures during message iteration or address construction.
Example Usage:
let trx_set: TransactionSerializationSet = ...; let arch_trx: ArchTransaction = trx_set.into();
Helper Functions for Phase Serialization
Each helper function converts optional protocol-specific phase data into corresponding transaction phase structs.
serialize_storage_phase(ph: Option<&TrStoragePhase>) -> (Option<TransactionStorage>, Option<&Grams>)serialize_compute_phase(ph: Option<&TrComputePhase>) -> (Option<TransactionCompute>, Option<&Grams>)serialize_credit_phase(ph: Option<&TrCreditPhase>) -> Option<TransactionCredit>serialize_action_phase(ph: Option<&TrActionPhase>) -> (Option<TransactionAction>, Option<&Grams>)serialize_bounce_phase(ph: Option<&TrBouncePhase>) -> Option<TransactionBounce>
These functions extract relevant fields, convert numeric types to strings where appropriate, and map enum variants to numeric codes for serialization.
Important Implementation Details and Algorithms
Fee Calculation and Balancing: The balance delta is computed by aggregating currency changes from inbound and outbound messages as well as transaction fees. It uses the
SignedCurrencyCollectionto handle positive and negative values in grams currency units.Phase Status Mapping: Status changes and reasons within phases are encoded as numeric codes (e.g.,
AccStatusChangeenum mapped to 0, 1, 2). This simplifies storage and later interpretation.Message Iteration: Outbound messages are iterated through slices of references to cells, extracting message hashes and fee information. This requires parsing the message structure from the cell and extracting value and fee data.
Transaction Description Parsing: The transaction description is pattern-matched to handle only ordinary transaction types. Other types are marked as unimplemented, ensuring focus on the standard transaction flow.
Use of Serde: All data structures derive
SerializeandDeserializefor JSON (or other formats) serialization, enabling their use with external storage or APIs.
Interaction with Other Parts of the System
Dependencies:
Uses types from the
tvm_blockcrate such asAccStatusChange,TrActionPhase,TrComputePhase,TransactionDescr, etc., to deserialize and interpret raw transaction data.Utilizes functions from sibling modules (
account::construct_address,account::serialize_account_status,message::get_msg_fees) for address creation, status serialization, and message fee extraction.Interacts with
SignedCurrencyCollectionfrom thecurrency_collectionmodule to represent and manipulate currency values and fees.Uses serialization helpers from
serialization::TransactionSerializationSetrepresenting raw transaction data sets.
Downstream Usage:
The
FlatTransactionstruct is suitable for database insertion, API responses, or indexing due to its flattened structure.The archival structure supports detailed transaction analysis, auditing, and storage.
Visual Diagram: Class Diagram of Transaction Data Structures and Conversions
classDiagram
class TransactionCredit {
+credit: Option<String>
+due_fees_collected: Option<String>
}
class TransactionStorage {
+storage_fees_collected: Option<String>
+storage_fees_due: Option<String>
+status_change: Option<u8>
}
class TransactionCompute {
+success: Option<bool>
+msg_state_used: Option<bool>
+account_activated: Option<bool>
+gas_credit: Option<u32>
+gas_fees: Option<String>
+gas_used: Option<f64>
+gas_limit: Option<f64>
+mode: Option<i8>
+exit_arg: Option<i32>
+exit_code: Option<i32>
+vm_steps: Option<u32>
+vm_init_state_hash: Option<String>
+vm_final_state_hash: Option<String>
+compute_type: u8
+skipped_reason: Option<u8>
}
class TransactionAction {
+success: Option<bool>
+valid: Option<bool>
+no_funds: Option<bool>
+status_change: Option<u8>
+result_arg: Option<i32>
+result_code: Option<i32>
+tot_actions: Option<i16>
+spec_actions: Option<i16>
+skipped_actions: Option<i16>
+msgs_created: Option<i16>
+action_list_hash: Option<String>
+tot_msg_size_cells: Option<f64>
+tot_msg_size_bits: Option<f64>
+total_action_fees: Option<String>
+total_fwd_fees: Option<String>
}
class TransactionBounce {
+bounce_type: Option<i32>
+fwd_fees: Option<String>
+msg_fees: Option<String>
+msg_size_bits: Option<f64>
+msg_size_cells: Option<f64>
+req_fwd_fees: Option<String>
}
class ArchTransaction {
-id: String
-block_id: String
-boc: Vec<u8>
-bounce: Option<TransactionBounce>
-status: u8
-credit: Option<TransactionCredit>
-storage: Option<TransactionStorage>
-compute: Option<TransactionCompute>
-action: Option<TransactionAction>
-credit_first: bool
-ext_in_msg_fee: Option<String>
-aborted: bool
-destroyed: bool
-tr_type: u8
-lt: String
-prev_trans_hash: String
-prev_trans_lt: String
-proof: Option<Vec<u8>>
-now: u32
-outmsg_cnt: u16
-orig_status: u8
-end_status: u8
-in_msg: String
-out_msgs: Vec<String>
-account_addr: String
-workchain_id: i32
-total_fees: String
-balance_delta: String
-old_hash: String
-new_hash: String
-chain_order: String
}
class FlatTransaction {
+id: String
+block_id: String
+boc: Vec<u8>
+status: u8
+credit: Option<String>
+storage_fees_collected: Option<String>
+storage_status_change: Option<u8>
+compute_success: Option<bool>
+compute_msg_state_used: Option<bool>
+compute_account_activated: Option<bool>
+compute_gas_fees: Option<String>
+compute_gas_used: Option<f64>
+compute_gas_limit: Option<f64>
+compute_mode: Option<i8>
+compute_exit_code: Option<i32>
+compute_skipped_reason: Option<u8>
+compute_vm_steps: Option<u32>
+compute_vm_init_state_hash: Option<String>
+compute_vm_final_state_hash: Option<String>
+compute_type: u8
+action_success: Option<bool>
+action_valid: Option<bool>
+action_no_funds: Option<bool>
+action_status_change: Option<u8>
+action_result_code: Option<i32>
+action_tot_actions: Option<i16>
+action_spec_actions: Option<i16>
+action_skipped_actions: Option<i16>
+action_msgs_created: Option<i16>
+action_list_hash: Option<String>
+action_tot_msg_size_cells: Option<f64>
+action_tot_msg_size_bits: Option<f64>
+credit_first: bool
+aborted: bool
+destroyed: bool
+tr_type: u8
+lt: String
+prev_trans_hash: String
+prev_trans_lt: String
+now: u32
+outmsg_cnt: u16
+orig_status: u8
+end_status: u8
+in_msg: String
+out_msgs: String
+account_addr: String
+workchain_id: i32
+total_fees: String
+balance_delta: String
+old_hash: String
+new_hash: String
+chain_order: String
}
ArchTransaction --> TransactionCredit
ArchTransaction --> TransactionStorage
ArchTransaction --> TransactionCompute
ArchTransaction --> TransactionAction
ArchTransaction --> TransactionBounce
FlatTransaction ..|> ArchTransaction : "from ArchTransaction"
Usage Examples
Creating ArchTransaction from Raw Serialization Set
use crate::transaction::ArchTransaction;
use crate::serialization::TransactionSerializationSet;
// Assume trx_set is a deserialized TransactionSerializationSet from blockchain data
let trx_set: TransactionSerializationSet = get_trx_serialization_set();
let arch_trx: ArchTransaction = trx_set.into();
Flattening ArchTransaction for Storage or API
use crate::transaction::{ArchTransaction, FlatTransaction};
let arch_trx: ArchTransaction = ...; // obtained from conversion above
let flat_trx: FlatTransaction = arch_trx.into();
// flat_trx can now be serialized to JSON or stored in DB
Notes on Field Semantics
Fees and Balances: All monetary values are represented as decimal strings of the underlying "grams" currency, using 128-bit unsigned integer values converted to hex or decimal strings.
Status Codes: Various phases report status changes, success flags, and reason codes that map directly to underlying blockchain protocol enums.
Hashes and IDs: All hashes and IDs are represented as hex strings for compactness and readability.
Message Hashes: Incoming and outgoing message hashes are tracked to relate the transaction to its associated messages.
Workchain and Account Address: Transactions are tied to a specific workchain and account address, constructed using utility functions.
This file plays a crucial role in bridging the gap between low-level blockchain transaction data and application-level transaction models tailored for persistence, querying, and analysis. It encapsulates domain-specific logic for interpreting transaction phases, computing fees, and managing message data.