This page documents the transaction validation and assembly mechanisms in fuel-core, which enable transactions to be validated, tested, and properly constructed before submission to the transaction pool. This includes dry-run execution for testing, predicate gas estimation, and automated transaction assembly with coin selection and fee calculation.
For information about transaction lifecycle states after submission, see Transaction Lifecycle. For details about the transaction pool's validation logic, see Transaction Pool Architecture.
Transaction validation and assembly in fuel-core provides three primary capabilities:
These operations are exposed through both the GraphQL API and the client SDK, allowing applications to validate and build transactions before submission.
Dry run execution allows transactions to be executed against the current (or historical) blockchain state without committing any changes. This is essential for:
Sources: crates/fuel-core/src/schema/tx.rs124-195 crates/client/src/client.rs699-731
The dry run operation accepts several optional parameters to control execution behavior:
| Parameter | Type | Purpose |
|---|---|---|
utxo_validation | Option<bool> | If false, disables UTXO existence and signature checks, allowing read-only calls with non-existent inputs |
gas_price | Option<U64> | Override gas price for fee calculation |
block_height | Option<U32> | Execute at a specific historical block height (requires --historical-execution flag) |
record_storage_reads | bool | Record all storage reads for execution replay/debugging |
Sources: crates/fuel-core/src/schema/tx.rs124-195 crates/client/assets/schema.sdl1062
The dry run process follows this sequence:
Sources: crates/fuel-core/src/schema/tx.rs124-195 crates/fuel-core/src/schema/tx.rs550-589
Dry run execution returns a status for each transaction indicating success or failure:
Sources: crates/client/src/client/schema/tx.rs350-411 crates/client/assets/schema.sdl336-353
When record_storage_reads is enabled, the dry run also returns a log of all storage accesses, allowing the execution to be replayed locally for debugging:
Sources: crates/fuel-core/src/schema/tx.rs574-589 crates/client/assets/schema.sdl1067-1071
Predicates are executable scripts that control the spending of UTXOs. Before a transaction can be executed, the gas cost of evaluating all predicates must be estimated and included in the transaction. Predicate estimation calculates these costs and updates the transaction accordingly.
Sources: crates/fuel-core/src/schema/tx.rs518-535 crates/client/src/client.rs851-860
The estimate_predicates operation:
HexString)ReadView to access current consensus parametersEstimatePredicates trait method from fuel-vmpredicate_gas_used fields populatedSources: crates/fuel-core/src/schema/tx.rs518-535
Predicate estimation is a critical step in transaction assembly. The assemble_tx operation includes an estimate_predicates parameter that, when enabled, automatically estimates predicates before calculating final fees:
Sources: crates/fuel-core/src/schema/tx.rs372-515 crates/client/assets/schema.sdl1043-1046
Transaction assembly is the process of taking an application-level transaction (containing only business logic) and transforming it into a complete, executable transaction by:
Change or Destroy outputs for remaining assetsVariable outputs if needed during executionContract inputs/outputs if contracts are usedSources: crates/fuel-core/src/schema/tx.rs372-515 crates/client/assets/schema.sdl997-1050
The assemble_tx operation requires the following parameters:
| Parameter | Type | Description |
|---|---|---|
tx | HexString | The base transaction containing application logic only |
block_horizon | U32 | Number of blocks into the future to estimate gas price for |
required_balances | Vec<RequiredBalance> | List of assets and amounts needed by the application, with change policies |
fee_address_index | U16 | Index into required_balances indicating which address pays the fee |
exclude_input | Option<ExcludeInput> | UTXOs and messages to exclude from coin selection |
estimate_predicates | Option<bool> | Whether to estimate predicate gas before fee calculation |
reserve_gas | Option<U64> | Additional gas to reserve when calculating fees |
Sources: crates/fuel-core/src/schema/tx.rs372-409 crates/client/assets/schema.sdl1021-1050
Each required balance specifies an asset, amount, and how change should be handled:
Sources: crates/client/assets/schema.sdl1233-1238 crates/client/assets/schema.sdl142-152
The transaction assembly implementation is delegated to the AssembleTx struct, which handles different transaction types:
Sources: crates/fuel-core/src/schema/tx.rs467-515 crates/fuel-core/src/schema/tx/assemble_tx.rs
The assembly process includes multiple validation checks:
max_inputs from consensus parametersSources: crates/fuel-core/src/schema/tx.rs414-437
After assembly completes, a final dry run is performed to validate the transaction and obtain execution status:
Sources: crates/fuel-core/src/schema/tx.rs488-514
The assembly operation returns an AssembleTransactionResult containing:
transaction: The fully assembled transaction ready for submissionstatus: The dry run execution status (success or failure with details)gasPrice: The gas price used for fee calculationSources: crates/client/assets/schema.sdl8-12 crates/client/src/client/types/assemble_tx.rs
The Rust client SDK exposes these validation and assembly methods:
Sources: crates/client/src/client.rs699-860
A typical client usage pattern for transaction assembly:
assemble_tx to build complete transactionsubmit or submit_and_await_commitSources: tests/tests/tx.rs86-359
The GraphQL schema defines the validation and assembly operations:
| Operation | Type | Description |
|---|---|---|
dryRun | Query | Execute transactions without committing (also available as deprecated Mutation) |
dryRunRecordStorageReads | Query | Dry run with storage read recording |
storageReadReplay | Query | Retrieve storage reads for a historical block |
estimatePredicates | Query | Estimate predicate gas costs |
assembleTx | Query | Assemble complete transaction with coin selection |
Sources: crates/client/assets/schema.sdl945-1172
When the --historical-execution flag is enabled, dry run and storage read replay operations can execute transactions at specific historical block heights. This requires the HistoricalRocksDB storage backend to maintain past state snapshots.
Sources: crates/fuel-core/src/schema/tx.rs146-151 crates/fuel-core/src/schema/tx.rs599-604
Transaction validation and assembly integrates with several other fuel-core systems:
Refresh this wiki