Virtual execution
Suggest an editSometimes you can't predict or know the exact execution details of an action. To solve this problem, protocols apply what we call Virtual Execution: the execution is made virtually, with the real execution performed later on, when the details of that execution become known.
Examples
Monaco Protocol's order book: When a match happens between a maker and a taker, the protocol doesn't yet know how to send the tokens to the maker, because in order to do that, it would have to know the accounts of the maker, for which it would require to store additional data and have the taker compute the account addresses. So it marks them as eligible for sending, and later on, when someone is ready to perform the execution, they bring the virtually executed send into a real one.
The result is written down first and carried out later. The match records what the maker is owed, and a separate settle pays it once the maker's account is in the transaction.
// the match has the book but not the maker's token account, so it only records
maker_order.filled = true;
maker_order.owed = fill_amount;
// a later settle, with the maker's token account now in the transaction
require!(maker_order.filled, OrderError::NotFilled);
transfer(&ctx, maker_order.owed)?;
maker_order.owed = 0;Until the settle runs, the recorded amount is not real money yet, so the program must not let it be spent.
ZK Compression represents many accounts with one on-chain Merkle root, while their data stays in Solana's transaction history. A zero knowledge proof lets the program verify account data. Updating the tree on every spend is expensive, so the protocol queues the spend and immediately blocks the account from being spent again. A worker called "forester" updates the tree later, processing queued spends in batches. The old account state can no longer be reused and users can use the new state without waiting for the tree update.