set_curve rewrites an entire curve slot and validates every segment of it in the same transaction. For smooth curves this can cost tens of thousands of compute units, all in your update transaction.
Queued curve updates split that work in two:
- Your transaction only writes the edits into a small buffer.
submit_curve_updatescosts 58 CU regardless of batch size. - The validation work runs when the batch is applied, which by default is the next swap on the pool.
The recommended flow
- Build the
submit_curve_updatesinstruction. - Simulate a transaction containing
submit_curve_updatesfollowed byvalidate_curve_updates.- Error
73(ValidationSimulationSuccess) on the validate instruction means the batch is valid. - Any other error is the exact error the real apply would return.
- Error
- Remove
validate_curve_updatesand sendsubmit_curve_updates, typically in the same transaction as yourupdate_midprice. The next swap applies the batch.
validate_curve_updates never commits state, so a transaction that contains it always fails. Include it only when simulating.
submit_curve_updates
Requires the SDK’srpc feature (for Hadron::load) plus solana-sdk, solana-rpc-client, solana-rpc-client-api and solana-compute-budget-interface.
Each submit replaces the buffer; it does not append. If you submit twice before the buffer is applied, only the second batch remains.
validate_curve_updates
Simulatesubmit_curve_updates and validate_curve_updates together, so the dry-run checks the batch you are about to send:
L-06 apply[2] ct=0 kind=Edit idx=4 fail=point-op-validation.
Send the update
Deferred validation can halt swaps on your pool.
submit_curve_updates does not check your ops. They are only checked when the batch is applied, which is usually inside the next swap. If the batch is invalid, every swap on the pool fails until you submit a valid batch to replace it.This is the tradeoff for keeping validation out of your update transaction. Never send a batch without first simulating it with validate_curve_updates. If you cannot simulate first, use set_curve, which rejects a bad curve in your own transaction.validate_curve_updates and send submit_curve_updates with your oracle update under a tight compute-unit limit:
update_midprice about 37, submit_curve_updates 58). Each compute-budget instruction adds about 150 CU, so a limit of 1,000 leaves plenty of headroom.
Until the next swap applies the batch, the curve account still holds the old points, and off-chain quoters (including aggregators) quote from it. The swap that applies the batch executes against the new points. Send
apply_curve_updates yourself if you need the new points live and quoted before the next trade.apply_curve_updates
Batch rules
- Ops apply in order. Each op is checked against the curve as the earlier ops in the same batch left it, not against the final curve. A set of edits that is valid in the end can still fail midway. For example, to move two neighbouring points to the right, edit the right-hand point first. If you edit the left-hand point first, it lands past its old neighbour and the op fails with
CurvePointsNotSorted(error9). Validate catches this, so reorder the ops and simulate again. - Indexes follow earlier ops.
point_indexandexpected_x_inrefer to the curve after the earlier ops in the batch. After anAddorRemove, the points to its right shift by one. - One failure fails the batch. No partial apply.
- Max 28 ops per submit.
Where the compute units go
Validation cost depends on the curve’s interpolation and on how many segments are checked.set_curve checks every segment. A queued op checks only the segments next to the point it touches (at most two). Measured on the deployed program:
With the queue, your transaction pays only the 58 CU for
submit_curve_updates. The right-hand column is paid by whoever applies the batch: the next swap, or you if you send apply_curve_updates. validate_curve_updates costs the same as an apply, but only in simulation.
- Updating the curve with every oracle tick: use the queue. Your update transaction stays under 100 CU of Hadron work however long or smooth the curve is.
- Short or cheap curves:
set_curveon a 2-point flat curve already costs under 700 CU, so the queue saves little. - Keep batches small. The swap that applies the batch pays about 1,000–5,700 CU per op on top of its own cost. A large batch can push an aggregator’s swap over the compute budget it simulated. For large reshapes, use
set_curveor sendapply_curve_updatesyourself.
Errors
See Error Reference for the full list.