@@ -70,7 +70,7 @@ pub(crate) struct Config {
7070 dry_run : bool ,
7171 no_update : bool ,
7272 compute_unit_price : Option < u64 > ,
73- compute_unit_limit : Option < u32 > ,
73+ compute_unit_limit : ComputeUnitLimit ,
7474}
7575
7676type CommandResult = Result < ( ) , Error > ;
@@ -105,11 +105,43 @@ const FEES_REFERENCE: &str = "Consider setting a minimal fee. \
105105 aware of the possible risks of a stake pool with no fees, \
106106 you may force pool creation with the --unsafe-fees flag.";
107107
108- pub const COMPUTE_UNIT_LIMIT_ARG : ArgConstant < ' static > = ArgConstant {
108+ enum ComputeUnitLimit {
109+ Default ,
110+ Static ( u32 ) ,
111+ Simulated ,
112+ }
113+ const COMPUTE_UNIT_LIMIT_ARG : ArgConstant < ' static > = ArgConstant {
109114 name : "compute_unit_limit" ,
110115 long : "--with-compute-unit-limit" ,
111- help : "Set compute unit limit for transaction, in compute units." ,
116+ help : "Set compute unit limit for transaction, in compute units; also accepts \
117+ keyword SIMULATED to use compute units from transaction simulation prior \
118+ to sending. Note that SIMULATED may fail if accounts are modified by another \
119+ transaction between simulation and execution.",
112120} ;
121+ fn is_compute_unit_limit_or_simulated < T > ( string : T ) -> Result < ( ) , String >
122+ where
123+ T : AsRef < str > + std:: fmt:: Display ,
124+ {
125+ if string. as_ref ( ) . parse :: < u32 > ( ) . is_ok ( ) || string. as_ref ( ) == "SIMULATED" {
126+ Ok ( ( ) )
127+ } else {
128+ Err ( format ! (
129+ "Unable to parse input compute unit limit as integer or SIMULATED, provided: {string}"
130+ ) )
131+ }
132+ }
133+ fn parse_compute_unit_limit < T > ( string : T ) -> Result < ComputeUnitLimit , String >
134+ where
135+ T : AsRef < str > + std:: fmt:: Display ,
136+ {
137+ match string. as_ref ( ) . parse :: < u32 > ( ) {
138+ Ok ( compute_unit_limit) => Ok ( ComputeUnitLimit :: Static ( compute_unit_limit) ) ,
139+ Err ( _) if string. as_ref ( ) == "SIMULATED" => Ok ( ComputeUnitLimit :: Simulated ) ,
140+ _ => Err ( format ! (
141+ "Unable to parse compute unit limit, provided: {string}"
142+ ) ) ,
143+ }
144+ }
113145
114146fn check_stake_pool_fees (
115147 epoch_fee : & Fee ,
@@ -200,17 +232,21 @@ fn checked_transaction_with_signers_and_additional_fee<T: Signers>(
200232 compute_unit_price,
201233 ) ) ;
202234 }
203- if let Some ( compute_unit_limit) = config. compute_unit_limit {
204- instructions. push ( ComputeBudgetInstruction :: set_compute_unit_limit (
205- compute_unit_limit,
206- ) ) ;
207- } else {
208- add_compute_unit_limit_from_simulation (
209- & config. rpc_client ,
210- & mut instructions,
211- & config. fee_payer . pubkey ( ) ,
212- & recent_blockhash,
213- ) ?;
235+ match config. compute_unit_limit {
236+ ComputeUnitLimit :: Default => { }
237+ ComputeUnitLimit :: Static ( compute_unit_limit) => {
238+ instructions. push ( ComputeBudgetInstruction :: set_compute_unit_limit (
239+ compute_unit_limit,
240+ ) ) ;
241+ }
242+ ComputeUnitLimit :: Simulated => {
243+ add_compute_unit_limit_from_simulation (
244+ & config. rpc_client ,
245+ & mut instructions,
246+ & config. fee_payer . pubkey ( ) ,
247+ & recent_blockhash,
248+ ) ?;
249+ }
214250 }
215251 let message = Message :: new_with_blockhash (
216252 & instructions,
@@ -2004,14 +2040,14 @@ fn main() {
20042040 . global ( true )
20052041 . help ( "Transaction fee payer account [default: cli config keypair]" ) ,
20062042 )
2007- . arg ( compute_unit_price_arg ( ) . validator ( is_parsable :: < u64 > ) . global ( true ) )
2043+ . arg ( compute_unit_price_arg ( ) . validator ( is_parsable :: < u64 > ) . requires ( COMPUTE_UNIT_LIMIT_ARG . name ) . global ( true ) )
20082044 . arg (
20092045 Arg :: with_name ( COMPUTE_UNIT_LIMIT_ARG . name )
20102046 . long ( COMPUTE_UNIT_LIMIT_ARG . long )
20112047 . takes_value ( true )
20122048 . value_name ( "COMPUTE-UNIT-LIMIT" )
20132049 . help ( COMPUTE_UNIT_LIMIT_ARG . help )
2014- . validator ( is_parsable :: < u32 > )
2050+ . validator ( is_compute_unit_limit_or_simulated )
20152051 . global ( true )
20162052 )
20172053 . subcommand ( SubCommand :: with_name ( "create-pool" )
@@ -2795,7 +2831,10 @@ fn main() {
27952831 let dry_run = matches. is_present ( "dry_run" ) ;
27962832 let no_update = matches. is_present ( "no_update" ) ;
27972833 let compute_unit_price = value_t ! ( matches, COMPUTE_UNIT_PRICE_ARG . name, u64 ) . ok ( ) ;
2798- let compute_unit_limit = value_t ! ( matches, COMPUTE_UNIT_LIMIT_ARG . name, u32 ) . ok ( ) ;
2834+ let compute_unit_limit = matches
2835+ . value_of ( COMPUTE_UNIT_LIMIT_ARG . name )
2836+ . map ( |x| parse_compute_unit_limit ( x) . unwrap ( ) )
2837+ . unwrap_or ( ComputeUnitLimit :: Default ) ;
27992838
28002839 Config {
28012840 rpc_client : RpcClient :: new_with_commitment ( json_rpc_url, CommitmentConfig :: confirmed ( ) ) ,
0 commit comments