Transaction Simulation
Footprint
As mentioned in the persisting data section, a contract can only load or store CONTRACT_DATA
entries that are declared in a footprint associated with its invocation.
A footprint is a set of ledger keys, each marked as either read-only or read-write. Read-only keys are available to the transaction for reading; read-write keys are available for reading, writing, or both.
Any Soroban transaction submitted by a user has to be accompanied by this footprint. A single footprint encompasses all the data read and written by all contracts transitively invoked by the transaction: not just the initial contract that the transaction calls, but also all contracts it calls, and so on.
Since it can be difficult for a user to know which ledger entries a given contract call will attempt to read or write (especially entries that are caused by other contracts deep within a transaction), the host provides an auxiliary simulateTransaction
mechanism that executes a transaction against a temporary, possibly out-of-date snapshot of the ledger. The simulateTransaction
mechanism is not constrained to only read or write the contents of a footprint; rather it records a footprint describing the transaction's execution, discards the execution's effects, and then returns the recorded footprint to its caller.
This simulation-provided footprint can then be used to accompany a "real" submission of the same transaction to the network for real execution. If the state of the ledger has changed too much between the time of the simulated and the real submission, the footprint may be too stale and no longer accurately identify the keys the transaction needs to read and/or write, at which point the simulation must be retried to refresh the footprint.
In any event (whether successful or failing), the real transaction will execute atomically, deterministically, and with serializable consistency semantics. An inaccurate footprint simply causes deterministic transaction failure, not a stale-read anomaly. All effects of such a failed transaction are discarded, as they would be in the presence of any other error.
Authorization
See the authorization overview docs and authorization in transactions section for general information on Soroban authorization.
Soroban's simulateTransaction
mechanism can also be used to compute the SorobanAuthorizedInvocation
trees that must be authorized by the Address
es for all the require_auth
checks to pass.
Soroban host provides a special 'recording' mode for auth. Whenever require_auth
is called, the host records its context (address, contract id, function, arguments), attributes it to a SorobanAuthorizedInvocation
tree, and marks it as successful. Then, after the invocation has finished, simulateTransaction
can return all the recorded trees, as well as the generated random nonce values.
Given this information from the simulation, the client only needs to provide these trees and nonces to the respective Address
es for signing and then build the final transaction using the simulation output and the corresponding signatures.
The recording auth mode is optional for simulateTransaction
. For example, when dealing with the custom account contracts, it may be necessary to simulate the custom account's __check_auth
code (that is simply omitted in the recording auth mode), for example, to get its ledger footprint. The non-recording mode is referred to as 'enforcing'. Enforcing mode is basically equivalent to running the transaction on-chain (with possibly a slightly stale ledger state); hence, it requires all the signatures to be valid.
Note that the recording auth mode never emulates authorization failures. The reason for that is that failing authorization is always an exceptional situation (i.e., the Address
es for which you don't anticipate successful authorization shouldn't be used in the first place). It is similar to how, for example, the simulateTransaction
mechanism doesn't emulate failures caused by the incorrect footprint. simulateTransaction
with enforcing auth mode may still be used to verify the signatures before executing the transaction on-chain.