feat(rpc): implement simulateTransaction#1333
Merged
Conversation
…, and minimal test script for debugging
- destroy conns on deinit - basic connection eviction - pass ptr to empty slice instead of null in lsquic_engine_connect - update peer address on packet ingestion
…, and minimal test script for debugging
- destroy conns on deinit - basic connection eviction - pass ptr to empty slice instead of null in lsquic_engine_connect - update peer address on packet ingestion
- Add SendTransaction hook context with decode, deserialize, and sanitize logic - Expose TransactionSender type alias and initWithWire constructor - Add getBlockhashLastValidBlockHeight to SlotTracker - Make getDurableNonce public for use in preflight checks - Move MAX_INSTRUCTION_TRACE_LENGTH to transaction_context module
- Add decodeAndDeserialize tests for base64/base58 encoding and error cases - Add sendTransactionImpl tests for channel dispatch and durable nonce - Add SlotTracker getBlockhashLastValidBlockHeight tests - Add TransactionInfo.initWithWire unit tests - Add SendTransaction serialization and resolveEncoding tests - Make transaction_legacy_example fields public for test access
…, and minimal test script for debugging
…connection pool and metrics - Replace the comptime-parameterized generic Client with a heap-allocated QuicClient that owns all resources (socket, SSL context, lsquic engine, connection pool, receiver channel). - Use fixed-size connection pool with slot reuse via idle timeout - Improve error handling in packetsOut and stream writes (partial write support) - Improve documentation - Add prometheus metric
- Move timing metrics into receiveTransactions and processTransactions via defer blocks - Make metrics logging interval configurable via log_metrics_interval config option - Add doc comments to receiveTransactions and processTransactions. - Fix test cleanup ordering with proper defer statements and increase test timeout.
…tAccountReader - Change loadAndExecuteTransaction to take SlotAccountReader instead of SlotAccountStore, enabling simulation use without side effects on the account store. - Introduce PreparedAccount type to thread fee payer (with loaded_size and rent_collected) from checkFeePayer through loadTransactionAccounts, avoiding store round-trip. - Move account persistence to callers: svm_gateway persists writes for intra-slot visibility, conformance and simulation callers can remain read-only. - Update checkFeePayer to take SlotAccountReader and return PreparedAccount instead of writing the fee-deducted payer back to the store.
- Add simulateTransaction to SendTransactionHookContext, using SvmGateway to execute transactions in a read-only simulation context for preflight checks - Return preflight failures as JSON-RPC error code -32002 with transaction error, logs, units consumed, and loaded accounts data size, matching agave's format - Change SendTransaction.Response from a plain Signature to a tagged union distinguishing signature success from preflight_fail - Replace account_reader with account_store and add epoch_tracker and status_cache fields to SendTransactionHookContext to support simulation setup - Add integration test verifying -32002 error response on preflight failure.
…bmit modes - Remove Mode union (RpcMode/SigMode) in favor of a single RpcClient for state queries - Add SubmitMode union with direct (channel) and rpc (client) variants for transaction submission - Inline RPC query methods (getAccountBalance, getLatestBlockhash, getSignatureStatus) on Service - Update call sites in cmd.zig and test_send_transactions.zig
- Implement rpc submit path that base64-encodes the wire transaction and calls sendTransaction on a dedicated RPC client, handling preflight failures - Add --mock-submit-url CLI arg to specify the RPC endpoint for transaction submission; when omitted, transactions are submitted directly to the channel - Validate that --mock-submit-url requires --mock-transfer-transactions
- Return error.SlotNotAvailable when preflight slot is pruned between commitment lookup and slot_tracker.get() - Replace preflight_failure unreachable with explicit @Panic for clearer diagnostics if server layer invariant is violated
- Set emit_null_optional_fields=false to avoid sending null values that Solana rejects (e.g. "skipPreflight": null → "invalid type: null, expected a boolean") - Add preflight config to MockTransferService with preflightCommitment matching the blockhash commitment level - Log RPC error code, message, and data on sendTransaction failure - Add standalone test_mock_transfers script for testing RPC submission mode independently from the validator - Remove --mock-submit-url from validator CLI; validator always uses direct submission mode
Previously wire_transaction.len was used (always PACKET_DATA_SIZE), instead of the actual decoded length. Thread wire_len from decodeAndDeserialize through to sendTransactionImpl so TransactionInfo receives the correct size.
Execute compute_budget program on the transaction message to populate compute_budget_instruction_details instead of leaving it as default empty, ensuring correct fee/priority calculations downstream.
…ack to the supermajority root instead of our tower's root
…llision and it really has no reason to be hardcoded when the OS will assign a free port.
…n removing the root slot if our root is older than the supermajority root
…plement-getSignatureStatuses-in-rpc
Guard against committing transactions with total_stake=0 on ticks with no newly frozen slots, which would wipe out valid commitment data from the previous cycle.
…adamw/implement-sendTransaction-in-rpc
…types - Move fromLedger converters into UiInnerInstructions, UiTransactionTokenBalances, and UiTransactionReturnData - Remove duplicate conversion functions from Ledger.zig and SendTransaction.zig - Reuse Committer.FallbackAccountReader instead of duplicating SimulationFallbackAccountReader
Cover unsupported encoding, min context slot, slot not found, and replaceRecentBlockhash + sigVerify conflict cases.
…on helpers - Add missing epoch_info.release() in simulateRuntimeTransaction - Add tests for resolveAndConvertTokenBalances edge cases - Add tests for getSimulatedAccount lookup behavior - Add test for simulateRuntimeTransaction blockhash-not-found path
yewman
approved these changes
Apr 6, 2026
prestonsn
approved these changes
Apr 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
simulateTransactionRPC methodsimulateTranasctionfunctionality insendTransaction'sskipPreflight=falsecodepathImplementation
simulateTransactioninSendTransactionHookContextRamifications
skipPreflight=falseis unimplemented and will panic, this PR adds the missing functionality for this codepathTests
sendTransactionrequest withskipPreflight=falsesuccessfullysimulateTransactionrequests touching different codepaths successfullysimulateTransactionRPC method