michelson_v1_gas.ml
(*****************************************************************************)
(* *)
(* Open Source License *)
(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
(* Copyright (c) 2019-2022 Nomadic Labs <contact@nomadic-labs.com> *)
(* Copyright (c) 2020 Metastate AG <hello@metastate.dev> *)
(* *)
(* Permission is hereby granted, free of charge, to any person obtaining a *)
(* copy of this software and associated documentation files (the "Software"),*)
(* to deal in the Software without restriction, including without limitation *)
(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *)
(* and/or sell copies of the Software, and to permit persons to whom the *)
(* Software is furnished to do so, subject to the following conditions: *)
(* *)
(* The above copyright notice and this permission notice shall be included *)
(* in all copies or substantial portions of the Software. *)
(* *)
(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)
(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *)
(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *)
(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)
(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *)
(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *)
(* DEALINGS IN THE SOFTWARE. *)
(* *)
(*****************************************************************************)
open Alpha_context
open Gas
module S = Saturation_repr
module Size = Gas_input_size
module Cost_of = struct
module S_syntax = struct
(* This is a good enough approximation. S.numbits 0 = 0 *)
let log2 x = S.safe_int (1 + S.numbits x)
let ( + ) = S.add
let ( * ) = S.mul
let ( lsr ) = S.shift_right
end
let z_bytes (z : Z.t) =
let bits = Z.numbits z in
(7 + bits) / 8
let int_bytes (z : 'a Script_int.num) = z_bytes (Script_int.to_zint z)
let manager_operation_int = 1_000
let manager_operation = step_cost @@ S.safe_int manager_operation_int
module Generated_costs = struct
(* Automatically generated costs functions. *)
(* model N_IAbs_int *)
(* Approximating 0.065045 x term *)
let cost_N_IAbs_int size = S.safe_int (20 + (size lsr 4))
(* model N_IAdd_bls12_381_fr *)
(* when benchmarking, compile bls12-381 without ADX *)
let cost_N_IAdd_bls12_381_fr = S.safe_int 30
(* model N_IAdd_bls12_381_g1 *)
(* when benchmarking, compile bls12-381 without ADX *)
let cost_N_IAdd_bls12_381_g1 = S.safe_int 900
(* model N_IAdd_bls12_381_g2 *)
(* when benchmarking, compile bls12-381 without ADX *)
let cost_N_IAdd_bls12_381_g2 = S.safe_int 2_470
let cost_linear_op_int size1 size2 =
let open S_syntax in
let v0 = S.safe_int (Compare.Int.max size1 size2) in
S.safe_int 35 + ((v0 lsr 4) + (v0 lsr 7))
(* model N_IAdd_int *)
(* Approximating 0.078154 x term *)
let cost_N_IAdd_int = cost_linear_op_int
(* model N_IAdd_nat *)
(* Approximating 0.077807 x term *)
let cost_N_IAdd_nat = cost_linear_op_int
(* model N_IAdd_seconds_to_timestamp *)
(* Approximating 0.078056 x term *)
let cost_N_IAdd_seconds_to_timestamp = cost_linear_op_int
(* model N_IAdd_tez *)
let cost_N_IAdd_tez = S.safe_int 20
(* model N_IAdd_timestamp_to_seconds *)
(* Approximating 0.077771 x term *)
let cost_N_IAdd_timestamp_to_seconds = cost_linear_op_int
(* model N_IAddress *)
let cost_N_IAddress = S.safe_int 10
(* model N_IAmount *)
let cost_N_IAmount = S.safe_int 10
(* model N_IAnd *)
let cost_N_IAnd = S.safe_int 10
(* model N_IAnd_int_nat *)
(* Approximating 0.076804 x 2 x term *)
let cost_N_IAnd_int_nat size1 size2 =
let open S_syntax in
let v0 = S.safe_int (Compare.Int.min size1 size2) in
S.safe_int 35 + ((v0 lsr 3) + (v0 lsr 6))
(* model N_IAnd_nat *)
(* Approximating 0.076804 x term *)
(* The difference with `cost_N_IAnd_int_nat` comes from Zarith, where the
complexity of `Z.logand` depends on the sign of the argument. *)
let cost_N_IAnd_nat size1 size2 =
let open S_syntax in
let v0 = S.safe_int (Compare.Int.min size1 size2) in
S.safe_int 35 + ((v0 lsr 4) + (v0 lsr 7))
(* model N_IApply *)
let cost_N_IApply rec_flag =
if rec_flag then S.safe_int 220 else S.safe_int 140
(* model N_IBlake2b *)
(* Approximating 1.120804 x term *)
let cost_N_IBlake2b size =
let open S_syntax in
let v0 = S.safe_int size in
S.safe_int 430 + v0 + (v0 lsr 3)
(* model N_IBytes_size *)
let cost_N_IBytes_size = S.safe_int 10
(* model N_ICar *)
let cost_N_ICar = S.safe_int 10
(* model N_ICdr *)
let cost_N_ICdr = S.safe_int 10
(* model N_IChainId *)
let cost_N_IChainId = S.safe_int 15
(* model N_ICheck_signature_ed25519 *)
(* Approximating 1.123507 x term *)
let cost_N_ICheck_signature_ed25519 size =
let open S_syntax in
let v0 = S.safe_int size in
S.safe_int 65_800 + (v0 + (v0 lsr 3))
(* model N_ICheck_signature_p256 *)
(* Approximating 1.111539 x term *)
let cost_N_ICheck_signature_p256 size =
let open S_syntax in
let v0 = S.safe_int size in
S.safe_int 990_000 + (v0 + (v0 lsr 3))
(* model N_ICheck_signature_secp256k1 *)
(* Approximating 1.125404 x term *)
let cost_N_ICheck_signature_secp256k1 size =
let open S_syntax in
let v0 = S.safe_int size in
S.safe_int 51_600 + (v0 + (v0 lsr 3))
(* model N_IComb *)
(* Approximating 3.531001 x term *)
(* Note: size >= 2, so the cost is never 0 *)
let cost_N_IComb size =
let open S_syntax in
let v0 = S.safe_int size in
(S.safe_int 3 * v0) + (v0 lsr 1) + (v0 lsr 5)
(* model N_IComb_get *)
(* Approximating 0.573180 x term *)
let cost_N_IComb_get size =
let open S_syntax in
let v0 = S.safe_int size in
S.safe_int 20 + (v0 lsr 1) + (v0 lsr 4)
(* model N_IComb_set *)
(* Approximating 1.287531 x term *)
let cost_N_IComb_set size =
let open S_syntax in
let v0 = S.safe_int size in
S.safe_int 20 + (v0 + (v0 lsr 2) + (v0 lsr 5))
(* Model N_ICompare *)
(* Approximating 0.024413 x term *)
let cost_N_ICompare size1 size2 =
let open S_syntax in
let v0 = S.safe_int (Compare.Int.min size1 size2) in
S.safe_int 35 + ((v0 lsr 6) + (v0 lsr 7))
(* model N_IConcat_bytes_pair *)
(* Approximating 0.065017 x term *)
let cost_N_IConcat_bytes_pair size1 size2 =
let open S_syntax in
let v0 = S.safe_int size1 + S.safe_int size2 in
S.safe_int 45 + (v0 lsr 4)
(* model N_IConcat_string_pair *)
(* Approximating 0.061402 x term *)
let cost_N_IConcat_string_pair size1 size2 =
let open S_syntax in
let v0 = S.safe_int size1 + S.safe_int size2 in
S.safe_int 45 + (v0 lsr 4)
(* model N_ICons_list *)
let cost_N_ICons_list = S.safe_int 10
(* model N_ICons_none *)
let cost_N_ICons_none = S.safe_int 10
(* model N_ICons_pair *)
let cost_N_ICons_pair = S.safe_int 10
(* model N_ICons_some *)
let cost_N_ICons_some = S.safe_int 10
(* model N_IConst *)
let cost_N_IConst = S.safe_int 10
(* model N_IContract *)
let cost_N_IContract = S.safe_int 30
(* model N_ICreate_contract *)
let cost_N_ICreate_contract = S.safe_int 30
(* model N_IDiff_timestamps *)
(* Approximating 0.077922 x term *)
let cost_N_IDiff_timestamps = cost_linear_op_int
(* model N_IDig *)
(* Approximating 6.750442 x term *)
let cost_N_IDig size =
let open S_syntax in
let v0 = S.safe_int size in
S.safe_int 30 + ((S.safe_int 6 * v0) + (v0 lsr 1) + (v0 lsr 2))
(* model N_IDip *)
let cost_N_IDip = S.safe_int 10
(* model N_IDipN *)
(* Approximating 2.740571 x term *)
let cost_N_IDipN size =
let open S_syntax in
let v0 = S.safe_int size in
S.safe_int 30 + ((S.safe_int 2 * v0) + (v0 lsr 1) + (v0 lsr 3))
(* model N_IView *)
let cost_N_IView = S.safe_int 1460
(* model N_IDrop *)
let cost_N_IDrop = S.safe_int 10
(* model N_IDropN *)
(* Approximating 2.713108 x term *)
let cost_N_IDropN size =
let open S_syntax in
let v0 = S.safe_int size in
S.safe_int 30 + (S.safe_int 2 * v0) + (v0 lsr 1) + (v0 lsr 3)
(* model N_IDug *)
(* Approximating 6.718396 x term *)
let cost_N_IDug size =
let open S_syntax in
let v0 = S.safe_int size in
S.safe_int 35 + ((S.safe_int 6 * v0) + (v0 lsr 1) + (v0 lsr 2))
(* model N_IDup *)
let cost_N_IDup = S.safe_int 10
(* model N_IDupN *)
(* Approximating 1.222263 x term *)
let cost_N_IDupN size =
let open S_syntax in
let v0 = S.safe_int size in
S.safe_int 20 + v0 + (v0 lsr 2)
let cost_div_int size1 size2 =
let q = size1 - size2 in
if Compare.Int.(q < 0) then S.safe_int 105
else
let open S_syntax in
let v0 = S.safe_int q * S.safe_int size2 in
S.safe_int 105 + (v0 lsr 10) + (v0 lsr 11) + (v0 lsr 13)
(* model N_IEdiv_int *)
(* Approximating 0.001591 x term *)
let cost_N_IEdiv_int = cost_div_int
(* model N_IEdiv_nat *)
(* Approximating 0.001605 x term *)
let cost_N_IEdiv_nat = cost_div_int
(* model N_IEdiv_tez *)
let cost_N_IEdiv_tez = S.safe_int 80
(* model N_IEdiv_teznat *)
let cost_N_IEdiv_teznat = S.safe_int 70
(* model N_IEmpty_big_map *)
let cost_N_IEmpty_big_map = S.safe_int 10
(* model N_IEmpty_map *)
let cost_N_IEmpty_map = S.safe_int 220
(* model N_IEmpty_set *)
let cost_N_IEmpty_set = S.safe_int 220
(* model N_IEq *)
let cost_N_IEq = S.safe_int 10
(* model N_IExec *)
let cost_N_IExec = S.safe_int 10
(* model N_IFailwith *)
(* let cost_N_IFailwith = S.safe_int 105 *)
(* model N_IGe *)
let cost_N_IGe = S.safe_int 10
(* model N_IGt *)
let cost_N_IGt = S.safe_int 10
(* model N_IHalt *)
let cost_N_IHalt = S.safe_int 10
(* model N_IHash_key *)
let cost_N_IHash_key = S.safe_int 605
(* model N_IIf *)
let cost_N_IIf = S.safe_int 10
(* model N_IIf_cons *)
let cost_N_IIf_cons = S.safe_int 10
(* model N_IIf_left *)
let cost_N_IIf_left = S.safe_int 10
(* model N_IIf_none *)
let cost_N_IIf_none = S.safe_int 10
(* model N_IOpt_map *)
let cost_opt_map = S.safe_int 10
(* model N_IImplicit_account *)
let cost_N_IImplicit_account = S.safe_int 10
(* model N_IInt_bls12_381_z_fr *)
(* when benchmarking, compile bls12-381 without ADX *)
let cost_N_IInt_bls12_381_z_fr = S.safe_int 115
(* model N_IInt_nat *)
let cost_N_IInt_nat = S.safe_int 10
(* model N_IIs_nat *)
let cost_N_IIs_nat = S.safe_int 10
(* model N_IKeccak *)
(* Approximating 8.276352 x term *)
let cost_N_IKeccak size =
let open S_syntax in
let v0 = S.safe_int size in
S.safe_int 1350 + ((S.safe_int 8 * v0) + (v0 lsr 2))
(* model N_ILambda *)
let cost_N_ILambda = S.safe_int 10
(* model N_ILe *)
let cost_N_ILe = S.safe_int 10
(* model N_ILeft *)
let cost_N_ILeft = S.safe_int 10
(* model N_ILevel *)
let cost_N_ILevel = S.safe_int 10
(* model N_IList_iter *)
let cost_N_IList_iter _ = S.safe_int 20
(* model N_IList_map *)
let cost_N_IList_map _ = S.safe_int 20
(* model N_IList_size *)
let cost_N_IList_size = S.safe_int 10
(* model N_ILoop *)
let cost_N_ILoop = S.safe_int 10
(* model N_ILoop_left *)
let cost_N_ILoop_left = S.safe_int 10
(* model N_ILsl_nat *)
(* Approximating 0.115642 x term *)
let cost_N_ILsl_nat size =
let open S_syntax in
let v0 = S.safe_int size in
S.safe_int 40 + ((v0 lsr 4) + (v0 lsr 5) + (v0 lsr 6))
(* model N_ILsr_nat *)
(* Approximating 0.115565 x term *)
let cost_N_ILsr_nat size =
let open S_syntax in
let v0 = S.safe_int size in
S.safe_int 45 + ((v0 lsr 4) + (v0 lsr 5) + (v0 lsr 6))
(* model N_ILt *)
let cost_N_ILt = S.safe_int 10
(* model N_IMap_get *)
(* Approximating 0.048359 x term *)
let cost_N_IMap_get size1 size2 =
let open S_syntax in
let v0 = size1 * log2 size2 in
S.safe_int 45 + (v0 lsr 5) + (v0 lsr 6)
(* model N_IMap_get_and_update *)
(* Approximating 0.145661 x term *)
let cost_N_IMap_get_and_update size1 size2 =
let open S_syntax in
let v0 = size1 * log2 size2 in
S.safe_int 75 + (v0 lsr 3) + (v0 lsr 6)
(* model N_IMap_iter *)
(* Approximating 7.621331 x term *)
let cost_N_IMap_iter size =
let open S_syntax in
let v0 = S.safe_int size in
S.safe_int 50 + (S.safe_int 7 * v0) + (v0 lsr 1) + (v0 lsr 3)
(* model N_IMap_map *)
(* Approximating 7.46280485884 x term *)
let cost_N_IMap_map size =
let open S_syntax in
let v0 = S.safe_int size in
S.safe_int 50 + ((S.safe_int 7 * v0) + (v0 lsr 1))
(* model N_IMap_mem *)
(* Approximating 0.048446 x term *)
let cost_N_IMap_mem size1 size2 =
let open S_syntax in
let v0 = size1 * log2 size2 in
S.safe_int 45 + (v0 lsr 5) + (v0 lsr 6)
(* model N_IMap_size *)
let cost_N_IMap_size = S.safe_int 10
(* model N_IMap_update *)
(* Approximating 0.097072 x term *)
let cost_N_IMap_update size1 size2 =
let open S_syntax in
let v0 = size1 * log2 size2 in
S.safe_int 55 + (v0 lsr 4) + (v0 lsr 5)
(* model N_IMul_bls12_381_fr *)
(* when benchmarking, compile bls12-381 without ADX *)
let cost_N_IMul_bls12_381_fr = S.safe_int 45
(* model N_IMul_bls12_381_fr_z *)
(* Approximating 1.059386 x term *)
(* when benchmarking, compile bls12-381 without ADX *)
let cost_N_IMul_bls12_381_fr_z size1 =
let open S_syntax in
let v0 = S.safe_int size1 in
S.safe_int 265 + v0 + (v0 lsr 4)
(* model N_IMul_bls12_381_g1 *)
(* when benchmarking, compile bls12-381 without ADX *)
let cost_N_IMul_bls12_381_g1 = S.safe_int 103_000
(* model N_IMul_bls12_381_g2 *)
(* when benchmarking, compile bls12-381 without ADX *)
let cost_N_IMul_bls12_381_g2 = S.safe_int 220_000
(* model N_IMul_bls12_381_z_fr *)
(* Approximating 1.068674 x term *)
(* when benchmarking, compile bls12-381 without ADX *)
let cost_N_IMul_bls12_381_z_fr size1 =
let open S_syntax in
let v0 = S.safe_int size1 in
S.safe_int 265 + v0 + (v0 lsr 4)
let cost_mul size1 size2 =
let open S_syntax in
let a = S.add (S.safe_int size1) (S.safe_int size2) in
let v0 = a * log2 a in
S.safe_int 55 + (v0 lsr 1) + (v0 lsr 2) + (v0 lsr 4)
(* model N_IMul_int *)
(* Approximating 0.857931 x term *)
let cost_N_IMul_int = cost_mul
(* model N_IMul_nat *)
(* Approximating 0.861823 x term *)
let cost_N_IMul_nat = cost_mul
(* model N_IMul_nattez *)
let cost_N_IMul_nattez = S.safe_int 50
(* model N_IMul_teznat *)
let cost_N_IMul_teznat = S.safe_int 50
(* model N_INeg_bls12_381_fr *)
(* when benchmarking, compile bls12-381 without ADX *)
let cost_N_INeg_bls12_381_fr = S.safe_int 25
(* model N_INeg_bls12_381_g1 *)
(* when benchmarking, compile bls12-381 without ADX *)
let cost_N_INeg_bls12_381_g1 = S.safe_int 50
(* model N_INeg_bls12_381_g2 *)
(* when benchmarking, compile bls12-381 without ADX *)
let cost_N_INeg_bls12_381_g2 = S.safe_int 70
(* model N_INeg *)
(* Approximating 0.066076 x term *)
let cost_N_INeg size =
let open S_syntax in
S.safe_int 25 + (S.safe_int size lsr 4)
(* model N_INeq *)
let cost_N_INeq = S.safe_int 10
(* model N_INil *)
let cost_N_INil = S.safe_int 10
(* model N_INot *)
let cost_N_INot = S.safe_int 10
(* model N_INot_int *)
(* Approximating 0.075541 x term *)
let cost_N_INot_int size =
let open S_syntax in
let v0 = S.safe_int size in
S.safe_int 25 + ((v0 lsr 4) + (v0 lsr 7))
(* model N_INow *)
let cost_N_INow = S.safe_int 10
(* model N_IMin_block_time *)
let cost_N_IMin_block_time = S.safe_int 20
(* model N_IOpen_chest *)
(* 612000 + chest * 19 + time * 19050 *)
let cost_N_IOpen_chest ~chest ~time =
let open S_syntax in
let v0 = S.safe_int chest in
let v1 = S.safe_int time in
S.safe_int 612_000 + (S.safe_int 19 * v0) + (S.safe_int 19050 * v1)
(* model N_IOr *)
let cost_N_IOr = S.safe_int 10
(* model N_IOr_nat *)
(* Approximating 0.075758 x term *)
let cost_N_IOr_nat = cost_linear_op_int
(* model N_IPairing_check_bls12_381 *)
(* when benchmarking, compile bls12-381 without ADX *)
let cost_N_IPairing_check_bls12_381 size =
S.add (S.safe_int 450_000) (S.mul (S.safe_int 342_500) (S.safe_int size))
(* model N_IRead_ticket *)
let cost_N_IRead_ticket = S.safe_int 10
(* model N_IRight *)
let cost_N_IRight = S.safe_int 10
(* model N_ISapling_empty_state *)
let cost_N_ISapling_empty_state = S.safe_int 10
(* model N_ISapling_verify_update *)
let cost_N_ISapling_verify_update size1 size2 bound_data =
let open S_syntax in
let v1 = S.safe_int size1 in
let v2 = S.safe_int size2 in
cost_N_IBlake2b bound_data + S.safe_int 310_000
+ (S.safe_int 5_575_000 * v1)
+ (S.safe_int 5_075_000 * v2)
(* model N_ISelf_address *)
let cost_N_ISelf_address = S.safe_int 10
(* model N_ISelf *)
let cost_N_ISelf = S.safe_int 10
(* model N_ISender *)
let cost_N_ISender = S.safe_int 10
(* model N_ISet_delegate *)
let cost_N_ISet_delegate = S.safe_int 30
(* model N_ISet_iter *)
(* Approximating 7.633555 x term *)
let cost_N_ISet_iter size =
let open S_syntax in
let v0 = S.safe_int size in
S.safe_int 50 + (S.safe_int 7 * v0) + (v0 lsr 1) + (v0 lsr 3)
(* model N_ISet_size *)
let cost_N_ISet_size = S.safe_int 10
(* model N_ISha256 *)
(* Approximating 4.763264 x term *)
let cost_N_ISha256 size =
let open S_syntax in
let v0 = S.safe_int size in
S.safe_int 600 + ((S.safe_int 4 * v0) + (v0 lsr 1) + (v0 lsr 2))
(* model N_ISha3 *)
(* Approximating 8.362339 x term *)
let cost_N_ISha3 = cost_N_IKeccak
(* model N_ISha512 *)
(* Approximating 3.074641 x term *)
let cost_N_ISha512 size =
let open S_syntax in
let v0 = S.safe_int size in
S.safe_int 680 + (S.safe_int 3 * v0)
(* model N_ISlice_bytes *)
(* Approximating 0.065752 x term *)
let cost_N_ISlice_bytes size =
let open S_syntax in
S.safe_int 25 + (S.safe_int size lsr 4)
(* model N_ISlice_string *)
(* Approximating 0.065688 x term *)
let cost_N_ISlice_string size =
let open S_syntax in
S.safe_int 25 + (S.safe_int size lsr 4)
(* model N_ISource *)
let cost_N_ISource = S.safe_int 10
(* model N_ISplit_ticket *)
(* Approximating 0.132362 x term *)
let cost_N_ISplit_ticket size1 size2 =
let open S_syntax in
let v1 = S.safe_int (Compare.Int.max size1 size2) in
S.safe_int 40 + (v1 lsr 3)
(* model N_IString_size *)
let cost_N_IString_size = S.safe_int 15
(* model N_ISub_int *)
(* Approximating 0.077849 x term *)
let cost_N_ISub_int = cost_linear_op_int
(* model N_ISub_tez *)
let cost_N_ISub_tez = S.safe_int 15
(* model N_ISub_tez_legacy *)
let cost_N_ISub_tez_legacy = S.safe_int 20
(* model N_ISub_timestamp_seconds *)
(* Approximating 0.077794 x term *)
let cost_N_ISub_timestamp_seconds = cost_linear_op_int
(* model N_ISwap *)
let cost_N_ISwap = S.safe_int 10
(* model N_ITicket *)
let cost_N_ITicket = S.safe_int 10
(* model N_ITotal_voting_power *)
let cost_N_ITotal_voting_power = S.safe_int 370
(* model N_ITransfer_tokens *)
let cost_N_ITransfer_tokens = S.safe_int 30
(* model N_IUncomb *)
(* Approximating 3.944710 x term *)
let cost_N_IUncomb size =
let open S_syntax in
let v0 = S.safe_int size in
S.safe_int 25 + (S.safe_int 4 * v0)
(* model N_IUnpair *)
let cost_N_IUnpair = S.safe_int 10
(* model N_IVoting_power *)
let cost_N_IVoting_power = S.safe_int 530
(* model N_IXor *)
let cost_N_IXor = S.safe_int 15
(* model N_IXor_nat *)
(* Approximating 0.075601 x term *)
let cost_N_IXor_nat = cost_linear_op_int
(* model N_KCons *)
let cost_N_KCons = S.safe_int 10
(* model N_KIter *)
let cost_N_KIter = S.safe_int 10
(* model N_KList_enter_body *)
(* Approximating 1.672196 x term *)
let cost_N_KList_enter_body xs size_ys =
match xs with
| [] ->
let open S_syntax in
let v0 = S.safe_int size_ys in
S.safe_int 25 + (v0 + (v0 lsr 1) + (v0 lsr 3))
| _ :: _ -> S.safe_int 25
(* model N_KList_exit_body *)
let cost_N_KList_exit_body = S.safe_int 10
(* model N_KLoop_in *)
let cost_N_KLoop_in = S.safe_int 10
(* model N_KLoop_in_left *)
let cost_N_KLoop_in_left = S.safe_int 10
(* model N_KMap_enter_body *)
let cost_N_KMap_enter_body = S.safe_int 80
(* model N_KNil *)
let cost_N_KNil = S.safe_int 10
(* model N_KReturn *)
let cost_N_KReturn = S.safe_int 10
(* model N_KView_exit *)
let cost_N_KView_exit = S.safe_int 20
(* model N_KMap_head *)
let cost_N_KMap_head = S.safe_int 20
(* model N_KUndip *)
let cost_N_KUndip = S.safe_int 10
(* model DECODING_BLS_FR *)
(* when benchmarking, compile bls12-381 without ADX, see
https://gitlab.com/dannywillems/ocaml-bls12-381/-/blob/71d0b4d467fbfaa6452d702fcc408d7a70916a80/README.md#install
*)
let cost_DECODING_BLS_FR = S.safe_int 120
(* model DECODING_BLS_G1 *)
(* when benchmarking, compile bls12-381 without ADX *)
let cost_DECODING_BLS_G1 = S.safe_int 54_600
(* model DECODING_BLS_G2 *)
(* when benchmarking, compile bls12-381 without ADX *)
let cost_DECODING_BLS_G2 = S.safe_int 69_000
(* model B58CHECK_DECODING_CHAIN_ID *)
let cost_B58CHECK_DECODING_CHAIN_ID = S.safe_int 1_600
(* model B58CHECK_DECODING_PUBLIC_KEY_HASH_ed25519 *)
let cost_B58CHECK_DECODING_PUBLIC_KEY_HASH_ed25519 = S.safe_int 3_300
(* model B58CHECK_DECODING_PUBLIC_KEY_HASH_p256 *)
let cost_B58CHECK_DECODING_PUBLIC_KEY_HASH_p256 = S.safe_int 3_300
(* model B58CHECK_DECODING_PUBLIC_KEY_HASH_secp256k1 *)
let cost_B58CHECK_DECODING_PUBLIC_KEY_HASH_secp256k1 = S.safe_int 3_300
(* model B58CHECK_DECODING_PUBLIC_KEY_ed25519 *)
let cost_B58CHECK_DECODING_PUBLIC_KEY_ed25519 = S.safe_int 4_200
(* model B58CHECK_DECODING_PUBLIC_KEY_p256 *)
let cost_B58CHECK_DECODING_PUBLIC_KEY_p256 = S.safe_int 325_000
(* model B58CHECK_DECODING_PUBLIC_KEY_secp256k1 *)
let cost_B58CHECK_DECODING_PUBLIC_KEY_secp256k1 = S.safe_int 9_000
(* model B58CHECK_DECODING_SIGNATURE_ed25519 *)
let cost_B58CHECK_DECODING_SIGNATURE_ed25519 = S.safe_int 6_400
(* model B58CHECK_DECODING_SIGNATURE_p256 *)
let cost_B58CHECK_DECODING_SIGNATURE_p256 = S.safe_int 6_400
(* model B58CHECK_DECODING_SIGNATURE_secp256k1 *)
let cost_B58CHECK_DECODING_SIGNATURE_secp256k1 = S.safe_int 6_400
(* model ENCODING_BLS_FR *)
let cost_ENCODING_BLS_FR = S.safe_int 80
(* model ENCODING_BLS_G1 *)
let cost_ENCODING_BLS_G1 = S.safe_int 3200
(* model ENCODING_BLS_G2 *)
let cost_ENCODING_BLS_G2 = S.safe_int 3900
(* model B58CHECK_ENCODING_CHAIN_ID *)
let cost_B58CHECK_ENCODING_CHAIN_ID = S.safe_int 1_800
(* model B58CHECK_ENCODING_PUBLIC_KEY_HASH_ed25519 *)
let cost_B58CHECK_ENCODING_PUBLIC_KEY_HASH_ed25519 = S.safe_int 3_200
(* model B58CHECK_ENCODING_PUBLIC_KEY_HASH_p256 *)
let cost_B58CHECK_ENCODING_PUBLIC_KEY_HASH_p256 = S.safe_int 3_200
(* model B58CHECK_ENCODING_PUBLIC_KEY_HASH_secp256k1 *)
let cost_B58CHECK_ENCODING_PUBLIC_KEY_HASH_secp256k1 = S.safe_int 3_200
(* model B58CHECK_ENCODING_PUBLIC_KEY_ed25519 *)
let cost_B58CHECK_ENCODING_PUBLIC_KEY_ed25519 = S.safe_int 4_500
(* model B58CHECK_ENCODING_PUBLIC_KEY_p256 *)
let cost_B58CHECK_ENCODING_PUBLIC_KEY_p256 = S.safe_int 4_550
(* model B58CHECK_ENCODING_PUBLIC_KEY_secp256k1 *)
let cost_B58CHECK_ENCODING_PUBLIC_KEY_secp256k1 = S.safe_int 4_950
(* model B58CHECK_ENCODING_SIGNATURE_ed25519 *)
let cost_B58CHECK_ENCODING_SIGNATURE_ed25519 = S.safe_int 8_300
(* model B58CHECK_ENCODING_SIGNATURE_p256 *)
let cost_B58CHECK_ENCODING_SIGNATURE_p256 = S.safe_int 8_300
(* model B58CHECK_ENCODING_SIGNATURE_secp256k1 *)
let cost_B58CHECK_ENCODING_SIGNATURE_secp256k1 = S.safe_int 8_300
(* model DECODING_CHAIN_ID *)
let cost_DECODING_CHAIN_ID = S.safe_int 50
(* model DECODING_PUBLIC_KEY_HASH_ed25519 *)
let cost_DECODING_PUBLIC_KEY_HASH_ed25519 = S.safe_int 50
(* model DECODING_PUBLIC_KEY_HASH_p256 *)
let cost_DECODING_PUBLIC_KEY_HASH_p256 = S.safe_int 50
(* model DECODING_PUBLIC_KEY_HASH_secp256k1 *)
let cost_DECODING_PUBLIC_KEY_HASH_secp256k1 = S.safe_int 50
(* model DECODING_PUBLIC_KEY_ed25519 *)
let cost_DECODING_PUBLIC_KEY_ed25519 = S.safe_int 60
(* model DECODING_PUBLIC_KEY_p256 *)
let cost_DECODING_PUBLIC_KEY_p256 = S.safe_int 320_000
(* model DECODING_PUBLIC_KEY_secp256k1 *)
let cost_DECODING_PUBLIC_KEY_secp256k1 = S.safe_int 4_900
(* model DECODING_SIGNATURE_ed25519 *)
let cost_DECODING_SIGNATURE_ed25519 = S.safe_int 35
(* model DECODING_SIGNATURE_p256 *)
let cost_DECODING_SIGNATURE_p256 = S.safe_int 35
(* model DECODING_SIGNATURE_secp256k1 *)
let cost_DECODING_SIGNATURE_secp256k1 = S.safe_int 35
(* model DECODING_Chest_key *)
let cost_DECODING_Chest_key = S.safe_int 5900
(* model DECODING_Chest *)
(* Approximating 0.039349 x term *)
let cost_DECODING_Chest ~bytes =
let open S_syntax in
let v0 = S.safe_int bytes in
S.safe_int 7400 + (v0 lsr 5) + (v0 lsr 7)
(* model ENCODING_CHAIN_ID *)
let cost_ENCODING_CHAIN_ID = S.safe_int 50
(* model ENCODING_PUBLIC_KEY_HASH_ed25519 *)
let cost_ENCODING_PUBLIC_KEY_HASH_ed25519 = S.safe_int 70
(* model ENCODING_PUBLIC_KEY_HASH_p256 *)
let cost_ENCODING_PUBLIC_KEY_HASH_p256 = S.safe_int 70
(* model ENCODING_PUBLIC_KEY_HASH_secp256k1 *)
let cost_ENCODING_PUBLIC_KEY_HASH_secp256k1 = S.safe_int 70
(* model ENCODING_PUBLIC_KEY_ed25519 *)
let cost_ENCODING_PUBLIC_KEY_ed25519 = S.safe_int 80
(* model ENCODING_PUBLIC_KEY_p256 *)
let cost_ENCODING_PUBLIC_KEY_p256 = S.safe_int 90
(* model ENCODING_PUBLIC_KEY_secp256k1 *)
let cost_ENCODING_PUBLIC_KEY_secp256k1 = S.safe_int 455
(* model ENCODING_SIGNATURE_ed25519 *)
let cost_ENCODING_SIGNATURE_ed25519 = S.safe_int 45
(* model ENCODING_SIGNATURE_p256 *)
let cost_ENCODING_SIGNATURE_p256 = S.safe_int 45
(* model ENCODING_SIGNATURE_secp256k1 *)
let cost_ENCODING_SIGNATURE_secp256k1 = S.safe_int 45
(* model ENCODING_Chest_key *)
let cost_ENCODING_Chest_key = S.safe_int 10_000
(* model ENCODING_Chest *)
(* Approximating 0.120086 x term *)
let cost_ENCODING_Chest ~plaintext_size =
let open S_syntax in
let v0 = S.safe_int plaintext_size in
S.safe_int 12_200 + (v0 lsr 3)
(* model TIMESTAMP_READABLE_DECODING *)
(* Approximating 0.045400 x term *)
let cost_TIMESTAMP_READABLE_DECODING ~bytes =
let open S_syntax in
let b = S.safe_int bytes in
let v0 = S.mul (S.sqrt b) b in
S.safe_int 105 + ((v0 lsr 5) + (v0 lsr 6))
(* model TIMESTAMP_READABLE_ENCODING *)
let cost_TIMESTAMP_READABLE_ENCODING = S.safe_int 820
(* model CHECK_PRINTABLE *)
let cost_CHECK_PRINTABLE size =
let open S_syntax in
S.safe_int 14 + (S.safe_int 10 * S.safe_int size)
(* model TY_EQ
This is the estimated cost of one iteration of ty_eq, extracted
and copied manually from the parameter fit for the TY_EQ benchmark
(the model is parametric on the size of the type, which we don't have
access to in O(1)). *)
let cost_TY_EQ = S.safe_int 60
(* model TYPECHECKING_CODE
This is the cost of one iteration of parse_instr, extracted by hand from the
parameter fit for the TYPECHECKING_CODE benchmark. *)
let cost_TYPECHECKING_CODE = S.safe_int 220
(* model UNPARSING_CODE
This is the cost of one iteration of unparse_instr, extracted by hand from the
parameter fit for the UNPARSING_CODE benchmark. *)
let cost_UNPARSING_CODE = S.safe_int 115
(* model TYPECHECKING_DATA
This is the cost of one iteration of parse_data, extracted by hand from the
parameter fit for the TYPECHECKING_DATA benchmark. *)
let cost_TYPECHECKING_DATA = S.safe_int 100
(* model UNPARSING_DATA
This is the cost of one iteration of unparse_data, extracted by hand from the
parameter fit for the UNPARSING_DATA benchmark. *)
let cost_UNPARSING_DATA = S.safe_int 45
(* model PARSE_TYPE
This is the cost of one iteration of parse_ty, extracted by hand from the
parameter fit for the PARSE_TYPE benchmark. *)
let cost_PARSE_TYPE = S.safe_int 60
(* model UNPARSE_TYPE
This is the cost of one iteration of unparse_ty, extracted by hand from the
parameter fit for the UNPARSE_TYPE benchmark. *)
let cost_UNPARSE_TYPE type_size = S.mul (S.safe_int 20) type_size
(* TODO: https://gitlab.com/tezos/tezos/-/issues/2264
Benchmark.
Currently approximated by 2 comparisons of the longest entrypoint. *)
let cost_FIND_ENTRYPOINT = cost_N_ICompare 31 31
(* model SAPLING_TRANSACTION_ENCODING *)
let cost_SAPLING_TRANSACTION_ENCODING ~inputs ~outputs ~bound_data =
S.safe_int (1500 + (inputs * 160) + (outputs * 320) + (bound_data lsr 3))
(* model SAPLING_DIFF_ENCODING *)
let cost_SAPLING_DIFF_ENCODING ~nfs ~cms =
S.safe_int ((nfs * 22) + (cms * 215))
(* model IEmit *)
let cost_N_IEmit = S.safe_int 30
end
module Interpreter = struct
open Generated_costs
let drop = atomic_step_cost cost_N_IDrop
let dup = atomic_step_cost cost_N_IDup
let swap = atomic_step_cost cost_N_ISwap
let cons_some = atomic_step_cost cost_N_ICons_some
let cons_none = atomic_step_cost cost_N_ICons_none
let if_none = atomic_step_cost cost_N_IIf_none
let opt_map = atomic_step_cost cost_opt_map
let cons_pair = atomic_step_cost cost_N_ICons_pair
let unpair = atomic_step_cost cost_N_IUnpair
let car = atomic_step_cost cost_N_ICar
let cdr = atomic_step_cost cost_N_ICdr
let cons_left = atomic_step_cost cost_N_ILeft
let cons_right = atomic_step_cost cost_N_IRight
let if_left = atomic_step_cost cost_N_IIf_left
let cons_list = atomic_step_cost cost_N_ICons_list
let nil = atomic_step_cost cost_N_INil
let if_cons = atomic_step_cost cost_N_IIf_cons
let list_map : 'a Script_typed_ir.boxed_list -> Gas.cost =
fun {length; _} -> atomic_step_cost (cost_N_IList_map length)
let list_size = atomic_step_cost cost_N_IList_size
let list_iter : 'a Script_typed_ir.boxed_list -> Gas.cost =
fun {length; _} -> atomic_step_cost (cost_N_IList_iter length)
let empty_set = atomic_step_cost cost_N_IEmpty_set
let set_iter (type a) (set : a Script_typed_ir.set) =
let (module Box) = Script_set.get set in
atomic_step_cost (cost_N_ISet_iter Box.size)
let set_size = atomic_step_cost cost_N_ISet_size
let empty_map = atomic_step_cost cost_N_IEmpty_map
let map_map (type k v) (map : (k, v) Script_typed_ir.map) =
let (module Box) = Script_map.get_module map in
atomic_step_cost (cost_N_IMap_map Box.size)
let map_iter (type k v) (map : (k, v) Script_typed_ir.map) =
let (module Box) = Script_map.get_module map in
atomic_step_cost (cost_N_IMap_iter Box.size)
let map_size = atomic_step_cost cost_N_IMap_size
let big_map_elt_size = S.safe_int Script_expr_hash.size
let big_map_mem ({size; _} : _ Script_typed_ir.big_map_overlay) =
atomic_step_cost (cost_N_IMap_mem big_map_elt_size (S.safe_int size))
let big_map_get ({size; _} : _ Script_typed_ir.big_map_overlay) =
atomic_step_cost (cost_N_IMap_get big_map_elt_size (S.safe_int size))
let big_map_update ({size; _} : _ Script_typed_ir.big_map_overlay) =
atomic_step_cost (cost_N_IMap_update big_map_elt_size (S.safe_int size))
let big_map_get_and_update ({size; _} : _ Script_typed_ir.big_map_overlay) =
atomic_step_cost
(cost_N_IMap_get_and_update big_map_elt_size (S.safe_int size))
let add_seconds_timestamp :
'a Script_int.num -> Script_timestamp.t -> Gas.cost =
fun seconds timestamp ->
let seconds_bytes = int_bytes seconds in
let timestamp_bytes = z_bytes (Script_timestamp.to_zint timestamp) in
atomic_step_cost
(cost_N_IAdd_seconds_to_timestamp seconds_bytes timestamp_bytes)
let add_timestamp_seconds :
Script_timestamp.t -> 'a Script_int.num -> Gas.cost =
fun timestamp seconds ->
let seconds_bytes = int_bytes seconds in
let timestamp_bytes = z_bytes (Script_timestamp.to_zint timestamp) in
atomic_step_cost
(cost_N_IAdd_timestamp_to_seconds timestamp_bytes seconds_bytes)
let sub_timestamp_seconds :
Script_timestamp.t -> 'a Script_int.num -> Gas.cost =
fun timestamp seconds ->
let seconds_bytes = int_bytes seconds in
let timestamp_bytes = z_bytes (Script_timestamp.to_zint timestamp) in
atomic_step_cost
(cost_N_ISub_timestamp_seconds timestamp_bytes seconds_bytes)
let diff_timestamps t1 t2 =
let t1_bytes = z_bytes (Script_timestamp.to_zint t1) in
let t2_bytes = z_bytes (Script_timestamp.to_zint t2) in
atomic_step_cost (cost_N_IDiff_timestamps t1_bytes t2_bytes)
let concat_string_pair s1 s2 =
atomic_step_cost
(cost_N_IConcat_string_pair
(Script_string.length s1)
(Script_string.length s2))
let slice_string s =
atomic_step_cost (cost_N_ISlice_string (Script_string.length s))
let string_size = atomic_step_cost cost_N_IString_size
let concat_bytes_pair b1 b2 =
atomic_step_cost
(cost_N_IConcat_bytes_pair (Bytes.length b1) (Bytes.length b2))
let slice_bytes b = atomic_step_cost (cost_N_ISlice_bytes (Bytes.length b))
let bytes_size = atomic_step_cost cost_N_IBytes_size
let add_tez = atomic_step_cost cost_N_IAdd_tez
let sub_tez = atomic_step_cost cost_N_ISub_tez
let sub_tez_legacy = atomic_step_cost cost_N_ISub_tez_legacy
let mul_teznat = atomic_step_cost cost_N_IMul_teznat
let mul_nattez = atomic_step_cost cost_N_IMul_nattez
let bool_or = atomic_step_cost cost_N_IOr
let bool_and = atomic_step_cost cost_N_IAnd
let bool_xor = atomic_step_cost cost_N_IXor
let bool_not = atomic_step_cost cost_N_INot
let is_nat = atomic_step_cost cost_N_IIs_nat
let abs_int i = atomic_step_cost (cost_N_IAbs_int (int_bytes i))
let int_nat = atomic_step_cost cost_N_IInt_nat
let neg i = atomic_step_cost (cost_N_INeg (int_bytes i))
let add_int i1 i2 =
atomic_step_cost (cost_N_IAdd_int (int_bytes i1) (int_bytes i2))
let add_nat i1 i2 =
atomic_step_cost (cost_N_IAdd_nat (int_bytes i1) (int_bytes i2))
let sub_int i1 i2 =
atomic_step_cost (cost_N_ISub_int (int_bytes i1) (int_bytes i2))
let mul_int i1 i2 =
atomic_step_cost (cost_N_IMul_int (int_bytes i1) (int_bytes i2))
let mul_nat i1 i2 =
atomic_step_cost (cost_N_IMul_nat (int_bytes i1) (int_bytes i2))
let ediv_teznat _tez _n = atomic_step_cost cost_N_IEdiv_teznat
let ediv_tez = atomic_step_cost cost_N_IEdiv_tez
let ediv_int i1 i2 =
atomic_step_cost (cost_N_IEdiv_int (int_bytes i1) (int_bytes i2))
let ediv_nat i1 i2 =
atomic_step_cost (cost_N_IEdiv_nat (int_bytes i1) (int_bytes i2))
let eq = atomic_step_cost cost_N_IEq
let lsl_nat shifted = atomic_step_cost (cost_N_ILsl_nat (int_bytes shifted))
let lsr_nat shifted = atomic_step_cost (cost_N_ILsr_nat (int_bytes shifted))
let or_nat n1 n2 =
atomic_step_cost (cost_N_IOr_nat (int_bytes n1) (int_bytes n2))
let and_nat n1 n2 =
atomic_step_cost (cost_N_IAnd_nat (int_bytes n1) (int_bytes n2))
let and_int_nat n1 n2 =
atomic_step_cost (cost_N_IAnd_int_nat (int_bytes n1) (int_bytes n2))
let xor_nat n1 n2 =
atomic_step_cost (cost_N_IXor_nat (int_bytes n1) (int_bytes n2))
let not_int i = atomic_step_cost (cost_N_INot_int (int_bytes i))
let if_ = atomic_step_cost cost_N_IIf
let loop = atomic_step_cost cost_N_ILoop
let loop_left = atomic_step_cost cost_N_ILoop_left
let dip = atomic_step_cost cost_N_IDip
let view = atomic_step_cost cost_N_IView
let check_signature (pkey : Signature.public_key) b =
let cost =
match pkey with
| Ed25519 _ -> cost_N_ICheck_signature_ed25519 (Bytes.length b)
| Secp256k1 _ -> cost_N_ICheck_signature_secp256k1 (Bytes.length b)
| P256 _ -> cost_N_ICheck_signature_p256 (Bytes.length b)
in
atomic_step_cost cost
let blake2b b = atomic_step_cost (cost_N_IBlake2b (Bytes.length b))
let sha256 b = atomic_step_cost (cost_N_ISha256 (Bytes.length b))
let sha512 b = atomic_step_cost (cost_N_ISha512 (Bytes.length b))
let dign n = atomic_step_cost (cost_N_IDig n)
let dugn n = atomic_step_cost (cost_N_IDug n)
let dipn n = atomic_step_cost (cost_N_IDipN n)
let dropn n = atomic_step_cost (cost_N_IDropN n)
let voting_power = atomic_step_cost cost_N_IVoting_power
let total_voting_power = atomic_step_cost cost_N_ITotal_voting_power
let keccak b = atomic_step_cost (cost_N_IKeccak (Bytes.length b))
let sha3 b = atomic_step_cost (cost_N_ISha3 (Bytes.length b))
let add_bls12_381_g1 = atomic_step_cost cost_N_IAdd_bls12_381_g1
let add_bls12_381_g2 = atomic_step_cost cost_N_IAdd_bls12_381_g2
let add_bls12_381_fr = atomic_step_cost cost_N_IAdd_bls12_381_fr
let mul_bls12_381_g1 = atomic_step_cost cost_N_IMul_bls12_381_g1
let mul_bls12_381_g2 = atomic_step_cost cost_N_IMul_bls12_381_g2
let mul_bls12_381_fr = atomic_step_cost cost_N_IMul_bls12_381_fr
let mul_bls12_381_fr_z z =
atomic_step_cost (cost_N_IMul_bls12_381_fr_z (int_bytes z))
let mul_bls12_381_z_fr z =
atomic_step_cost (cost_N_IMul_bls12_381_z_fr (int_bytes z))
let int_bls12_381_fr = atomic_step_cost cost_N_IInt_bls12_381_z_fr
let neg_bls12_381_g1 = atomic_step_cost cost_N_INeg_bls12_381_g1
let neg_bls12_381_g2 = atomic_step_cost cost_N_INeg_bls12_381_g2
let neg_bls12_381_fr = atomic_step_cost cost_N_INeg_bls12_381_fr
let neq = atomic_step_cost cost_N_INeq
let pairing_check_bls12_381 (l : 'a Script_typed_ir.boxed_list) =
atomic_step_cost (cost_N_IPairing_check_bls12_381 l.length)
let comb n = atomic_step_cost (cost_N_IComb n)
let uncomb n = atomic_step_cost (cost_N_IUncomb n)
let comb_get n = atomic_step_cost (cost_N_IComb_get n)
let comb_set n = atomic_step_cost (cost_N_IComb_set n)
let dupn n = atomic_step_cost (cost_N_IDupN n)
let sapling_verify_update ~inputs ~outputs ~bound_data =
atomic_step_cost (cost_N_ISapling_verify_update inputs outputs bound_data)
let sapling_verify_update_deprecated ~inputs ~outputs =
atomic_step_cost (cost_N_ISapling_verify_update inputs outputs 0)
let sapling_empty_state = atomic_step_cost cost_N_ISapling_empty_state
let halt = atomic_step_cost cost_N_IHalt
let const = atomic_step_cost cost_N_IConst
let empty_big_map = atomic_step_cost cost_N_IEmpty_big_map
let lt = atomic_step_cost cost_N_ILt
let le = atomic_step_cost cost_N_ILe
let gt = atomic_step_cost cost_N_IGt
let ge = atomic_step_cost cost_N_IGe
let exec = atomic_step_cost cost_N_IExec
let apply ~(rec_flag : bool) = atomic_step_cost (cost_N_IApply rec_flag)
let lambda = atomic_step_cost cost_N_ILambda
let address = atomic_step_cost cost_N_IAddress
let contract = atomic_step_cost cost_N_IContract
let transfer_tokens = atomic_step_cost cost_N_ITransfer_tokens
let implicit_account = atomic_step_cost cost_N_IImplicit_account
let create_contract = atomic_step_cost cost_N_ICreate_contract
let set_delegate = atomic_step_cost cost_N_ISet_delegate
let level = atomic_step_cost cost_N_ILevel
let now = atomic_step_cost cost_N_INow
let min_block_time = atomic_step_cost cost_N_IMin_block_time
let source = atomic_step_cost cost_N_ISource
let sender = atomic_step_cost cost_N_ISender
let self = atomic_step_cost cost_N_ISelf
let self_address = atomic_step_cost cost_N_ISelf_address
let amount = atomic_step_cost cost_N_IAmount
let chain_id = atomic_step_cost cost_N_IChainId
let ticket = atomic_step_cost cost_N_ITicket
let read_ticket = atomic_step_cost cost_N_IRead_ticket
let hash_key _ = atomic_step_cost cost_N_IHash_key
let split_ticket _ amount_a amount_b =
atomic_step_cost
(cost_N_ISplit_ticket (int_bytes amount_a) (int_bytes amount_b))
let open_chest ~chest ~time =
let plaintext =
Script_typed_ir.Script_timelock.get_plaintext_size chest
in
let log_time = Z.log2 Z.(add one time) in
atomic_step_cost (cost_N_IOpen_chest ~chest:plaintext ~time:log_time)
(* --------------------------------------------------------------------- *)
(* Semi-hand-crafted models *)
let compare_unit = atomic_step_cost (S.safe_int 10)
let compare_pair_tag = atomic_step_cost (S.safe_int 10)
let compare_union_tag = atomic_step_cost (S.safe_int 10)
let compare_option_tag = atomic_step_cost (S.safe_int 10)
let compare_bool = atomic_step_cost (cost_N_ICompare 1 1)
let compare_signature = atomic_step_cost (S.safe_int 92)
let compare_string s1 s2 =
atomic_step_cost
(cost_N_ICompare (Script_string.length s1) (Script_string.length s2))
let compare_bytes b1 b2 =
atomic_step_cost (cost_N_ICompare (Bytes.length b1) (Bytes.length b2))
let compare_mutez = atomic_step_cost (cost_N_ICompare 8 8)
let compare_int i1 i2 =
atomic_step_cost (cost_N_ICompare (int_bytes i1) (int_bytes i2))
let compare_nat n1 n2 =
atomic_step_cost (cost_N_ICompare (int_bytes n1) (int_bytes n2))
let compare_key_hash =
let sz = Signature.Public_key_hash.size in
atomic_step_cost (cost_N_ICompare sz sz)
let compare_key = atomic_step_cost (S.safe_int 92)
let compare_timestamp t1 t2 =
atomic_step_cost
(cost_N_ICompare
(z_bytes (Script_timestamp.to_zint t1))
(z_bytes (Script_timestamp.to_zint t2)))
(* Maximum size of an entrypoint in bytes *)
let entrypoint_size = 31
let compare_address =
let sz = Signature.Public_key_hash.size + entrypoint_size in
atomic_step_cost (cost_N_ICompare sz sz)
(** TODO: https://gitlab.com/tezos/tezos/-/issues/2340
Refine the gas model *)
let compare_tx_rollup_l2_address = atomic_step_cost (cost_N_ICompare 48 48)
let compare_chain_id = atomic_step_cost (S.safe_int 30)
(* Defunctionalized CPS *)
type cont =
| Compare : 'a Script_typed_ir.comparable_ty * 'a * 'a * cont -> cont
| Return : cont
let compare : type a. a Script_typed_ir.comparable_ty -> a -> a -> cost =
fun ty x y ->
let rec compare :
type a.
a Script_typed_ir.comparable_ty -> a -> a -> cost -> cont -> cost =
fun ty x y acc k ->
match ty with
| Unit_t -> (apply [@tailcall]) Gas.(acc +@ compare_unit) k
| Never_t -> ( match x with _ -> .)
| Bool_t -> (apply [@tailcall]) Gas.(acc +@ compare_bool) k
| String_t -> (apply [@tailcall]) Gas.(acc +@ compare_string x y) k
| Signature_t -> (apply [@tailcall]) Gas.(acc +@ compare_signature) k
| Bytes_t -> (apply [@tailcall]) Gas.(acc +@ compare_bytes x y) k
| Mutez_t -> (apply [@tailcall]) Gas.(acc +@ compare_mutez) k
| Int_t -> (apply [@tailcall]) Gas.(acc +@ compare_int x y) k
| Nat_t -> (apply [@tailcall]) Gas.(acc +@ compare_nat x y) k
| Key_hash_t -> (apply [@tailcall]) Gas.(acc +@ compare_key_hash) k
| Key_t -> (apply [@tailcall]) Gas.(acc +@ compare_key) k
| Timestamp_t ->
(apply [@tailcall]) Gas.(acc +@ compare_timestamp x y) k
| Address_t -> (apply [@tailcall]) Gas.(acc +@ compare_address) k
| Tx_rollup_l2_address_t ->
(apply [@tailcall]) Gas.(acc +@ compare_tx_rollup_l2_address) k
| Chain_id_t -> (apply [@tailcall]) Gas.(acc +@ compare_chain_id) k
| Pair_t (tl, tr, _, YesYes) ->
(* Reasonable over-approximation of the cost of lexicographic comparison. *)
let xl, xr = x in
let yl, yr = y in
(compare [@tailcall])
tl
xl
yl
Gas.(acc +@ compare_pair_tag)
(Compare (tr, xr, yr, k))
| Union_t (tl, tr, _, YesYes) -> (
match (x, y) with
| L x, L y ->
(compare [@tailcall]) tl x y Gas.(acc +@ compare_union_tag) k
| L _, R _ -> (apply [@tailcall]) Gas.(acc +@ compare_union_tag) k
| R _, L _ -> (apply [@tailcall]) Gas.(acc +@ compare_union_tag) k
| R x, R y ->
(compare [@tailcall]) tr x y Gas.(acc +@ compare_union_tag) k)
| Option_t (t, _, Yes) -> (
match (x, y) with
| None, None ->
(apply [@tailcall]) Gas.(acc +@ compare_option_tag) k
| None, Some _ ->
(apply [@tailcall]) Gas.(acc +@ compare_option_tag) k
| Some _, None ->
(apply [@tailcall]) Gas.(acc +@ compare_option_tag) k
| Some x, Some y ->
(compare [@tailcall]) t x y Gas.(acc +@ compare_option_tag) k)
and apply cost k =
match k with
| Compare (ty, x, y, k) -> (compare [@tailcall]) ty x y cost k
| Return -> cost
in
compare ty x y Gas.free Return
let set_mem (type a) (elt : a) (set : a Script_typed_ir.set) =
let open S_syntax in
let (module Box) = Script_set.get set in
let per_elt_cost = Box.OPS.elt_size elt |> Size.to_int |> S.safe_int in
let size = S.safe_int Box.size in
let intercept = atomic_step_cost (S.safe_int 115) in
Gas.(intercept +@ (log2 size *@ per_elt_cost))
let set_update (type a) (elt : a) (set : a Script_typed_ir.set) =
let open S_syntax in
let (module Box) = Script_set.get set in
let per_elt_cost = Box.OPS.elt_size elt |> Size.to_int |> S.safe_int in
let size = S.safe_int Box.size in
let intercept = atomic_step_cost (S.safe_int 130) in
(* The 2 factor reflects the update vs mem overhead as benchmarked
on non-structured data *)
Gas.(intercept +@ (S.safe_int 2 * log2 size *@ per_elt_cost))
let map_mem (type k v) (elt : k) (map : (k, v) Script_typed_ir.map) =
let open S_syntax in
let (module Box) = Script_map.get_module map in
let per_elt_cost = Box.OPS.key_size elt |> Size.to_int |> S.safe_int in
let size = S.safe_int Box.size in
let intercept = atomic_step_cost (S.safe_int 80) in
Gas.(intercept +@ (log2 size *@ per_elt_cost))
let map_get = map_mem
let map_update (type k v) (elt : k) (map : (k, v) Script_typed_ir.map) =
let open S_syntax in
let (module Box) = Script_map.get_module map in
let per_elt_cost = Box.OPS.key_size elt |> Size.to_int |> S.safe_int in
let size = S.safe_int Box.size in
let intercept = atomic_step_cost (S.safe_int 80) in
(* The 2 factor reflects the update vs mem overhead as benchmarked
on non-structured data *)
Gas.(intercept +@ (S.safe_int 2 * log2 size *@ per_elt_cost))
let map_get_and_update (type k v) (elt : k)
(map : (k, v) Script_typed_ir.map) =
let open S_syntax in
let (module Box) = Script_map.get_module map in
let per_elt_cost = Box.OPS.key_size elt |> Size.to_int |> S.safe_int in
let size = S.safe_int Box.size in
let intercept = atomic_step_cost (S.safe_int 80) in
(* The 3 factor reflects the update vs mem overhead as benchmarked
on non-structured data *)
Gas.(intercept +@ (S.safe_int 3 * log2 size *@ per_elt_cost))
let view_get (elt : Script_string.t) (m : Script_typed_ir.view_map) =
map_get elt m
let view_update (elt : Script_string.t) (m : Script_typed_ir.view_map) =
map_update elt m
let join_tickets :
'a Script_typed_ir.comparable_ty ->
'a Script_typed_ir.ticket ->
'a Script_typed_ir.ticket ->
Gas.cost =
fun ty ticket_a ticket_b ->
let contents_comparison =
compare ty ticket_a.contents ticket_b.contents
in
Gas.(
contents_comparison +@ compare_address
+@ add_nat ticket_a.amount ticket_b.amount)
let emit = atomic_step_cost cost_N_IEmit
(* Continuations *)
module Control = struct
let nil = atomic_step_cost cost_N_KNil
let cons = atomic_step_cost cost_N_KCons
let return = atomic_step_cost cost_N_KReturn
let view_exit = atomic_step_cost cost_N_KView_exit
let map_head = atomic_step_cost cost_N_KMap_head
let undip = atomic_step_cost cost_N_KUndip
let loop_in = atomic_step_cost cost_N_KLoop_in
let loop_in_left = atomic_step_cost cost_N_KLoop_in_left
let iter = atomic_step_cost cost_N_KIter
let list_enter_body xs ys_len =
atomic_step_cost (cost_N_KList_enter_body xs ys_len)
let list_exit_body = atomic_step_cost cost_N_KList_exit_body
let map_enter_body = atomic_step_cost cost_N_KMap_enter_body
let map_exit_body (type k v) (key : k) (map : (k, v) Script_typed_ir.map)
=
map_update key map
end
(* --------------------------------------------------------------------- *)
(* Hand-crafted models *)
(* The cost functions below where not benchmarked, a cost model was derived
from looking at similar instructions. *)
(* Cost for Concat_string is paid in two steps: when entering the interpreter,
the user pays for the cost of computing the information necessary to compute
the actual gas (so it's meta-gas): indeed, one needs to run through the
list of strings to compute the total allocated cost.
[concat_string_precheck] corresponds to the meta-gas cost of this computation.
*)
let concat_string_precheck (l : 'a Script_typed_ir.boxed_list) =
(* we set the precheck to be slightly more expensive than cost_N_IList_iter *)
atomic_step_cost (S.mul (S.safe_int l.length) (S.safe_int 10))
(* This is the cost of allocating a string and blitting existing ones into it. *)
let concat_string total_bytes =
atomic_step_cost
S.(add (S.safe_int 100) (S.ediv total_bytes (S.safe_int 10)))
(* Same story as Concat_string. *)
let concat_bytes total_bytes =
atomic_step_cost
S.(add (S.safe_int 100) (S.ediv total_bytes (S.safe_int 10)))
(* Cost of access taken care of in Contract_storage.get_balance_carbonated *)
let balance = Gas.free
(* Cost of Unpack pays two integer comparisons, and a Bytes slice *)
let unpack bytes =
let blen = Bytes.length bytes in
let open S_syntax in
atomic_step_cost (S.safe_int 260 + (S.safe_int blen lsr 3))
(* TODO benchmark *)
(* FIXME: imported from 006, needs proper benchmarks *)
let unpack_failed bytes =
(* We cannot instrument failed deserialization,
so we take worst case fees: a set of size 1 bytes values. *)
let blen = String.length bytes in
let len = S.safe_int blen in
let d = Z.numbits (Z.of_int blen) in
(len *@ alloc_mbytes_cost 1)
+@ len
*@ (S.safe_int d *@ (alloc_cost (S.safe_int 3) +@ step_cost S.one))
end
module Typechecking = struct
open Generated_costs
let public_key_optimized =
atomic_step_cost
@@ S.(
max
cost_DECODING_PUBLIC_KEY_ed25519
(max
cost_DECODING_PUBLIC_KEY_secp256k1
cost_DECODING_PUBLIC_KEY_p256))
let public_key_readable =
atomic_step_cost
@@ S.(
max
cost_B58CHECK_DECODING_PUBLIC_KEY_ed25519
(max
cost_B58CHECK_DECODING_PUBLIC_KEY_secp256k1
cost_B58CHECK_DECODING_PUBLIC_KEY_p256))
let key_hash_optimized =
atomic_step_cost
@@ S.(
max
cost_DECODING_PUBLIC_KEY_HASH_ed25519
(max
cost_DECODING_PUBLIC_KEY_HASH_secp256k1
cost_DECODING_PUBLIC_KEY_HASH_p256))
let key_hash_readable =
atomic_step_cost
@@ S.(
max
cost_B58CHECK_DECODING_PUBLIC_KEY_HASH_ed25519
(max
cost_B58CHECK_DECODING_PUBLIC_KEY_HASH_secp256k1
cost_B58CHECK_DECODING_PUBLIC_KEY_HASH_p256))
let signature_optimized =
atomic_step_cost
@@ S.(
max
cost_DECODING_SIGNATURE_ed25519
(max
cost_DECODING_SIGNATURE_secp256k1
cost_DECODING_SIGNATURE_p256))
let signature_readable =
atomic_step_cost
@@ S.(
max
cost_B58CHECK_DECODING_SIGNATURE_ed25519
(max
cost_B58CHECK_DECODING_SIGNATURE_secp256k1
cost_B58CHECK_DECODING_SIGNATURE_p256))
let chain_id_optimized = atomic_step_cost cost_DECODING_CHAIN_ID
let chain_id_readable = atomic_step_cost cost_B58CHECK_DECODING_CHAIN_ID
(* Reasonable approximation *)
let address_optimized = key_hash_optimized
(* Reasonable approximation *)
let contract_optimized = key_hash_optimized
(* Reasonable approximation *)
let contract_readable = key_hash_readable
let bls12_381_g1 = atomic_step_cost cost_DECODING_BLS_G1
let bls12_381_g2 = atomic_step_cost cost_DECODING_BLS_G2
let bls12_381_fr = atomic_step_cost cost_DECODING_BLS_FR
let check_printable s =
atomic_step_cost (cost_CHECK_PRINTABLE (String.length s))
let merge_cycle = atomic_step_cost cost_TY_EQ
let parse_type_cycle = atomic_step_cost cost_PARSE_TYPE
let parse_instr_cycle = atomic_step_cost cost_TYPECHECKING_CODE
let parse_data_cycle = atomic_step_cost cost_TYPECHECKING_DATA
(* Cost of a cycle of checking that a type is dupable *)
(* TODO: bench *)
let check_dupable_cycle = atomic_step_cost cost_TYPECHECKING_DATA
let find_entrypoint_cycle = atomic_step_cost cost_FIND_ENTRYPOINT
let bool = free
let unit = free
let timestamp_readable s =
atomic_step_cost
(cost_TIMESTAMP_READABLE_DECODING ~bytes:(String.length s))
(** TODO: https://gitlab.com/tezos/tezos/-/issues/2340
Refine the gas model *)
let tx_rollup_l2_address = bls12_381_g1
(* Balance stored at /contracts/index/hash/balance, on 64 bits *)
let contract_exists =
Gas.cost_of_repr @@ Storage_costs.read_access ~path_length:4 ~read_bytes:8
(* Constructing proof arguments consists in a decreasing loop in the result
monad, allocating at each step. We charge a reasonable overapproximation. *)
let proof_argument n =
atomic_step_cost (S.mul (S.safe_int n) (S.safe_int 50))
let chest_key = atomic_step_cost cost_DECODING_Chest_key
let chest ~bytes = atomic_step_cost (cost_DECODING_Chest ~bytes)
end
module Unparsing = struct
open Generated_costs
let public_key_optimized =
atomic_step_cost
@@ S.(
max
cost_ENCODING_PUBLIC_KEY_ed25519
(max
cost_ENCODING_PUBLIC_KEY_secp256k1
cost_ENCODING_PUBLIC_KEY_p256))
let public_key_readable =
atomic_step_cost
@@ S.(
max
cost_B58CHECK_ENCODING_PUBLIC_KEY_ed25519
(max
cost_B58CHECK_ENCODING_PUBLIC_KEY_secp256k1
cost_B58CHECK_ENCODING_PUBLIC_KEY_p256))
let key_hash_optimized =
atomic_step_cost
@@ S.(
max
cost_ENCODING_PUBLIC_KEY_HASH_ed25519
(max
cost_ENCODING_PUBLIC_KEY_HASH_secp256k1
cost_ENCODING_PUBLIC_KEY_HASH_p256))
let key_hash_readable =
atomic_step_cost
@@ S.(
max
cost_B58CHECK_ENCODING_PUBLIC_KEY_HASH_ed25519
(max
cost_B58CHECK_ENCODING_PUBLIC_KEY_HASH_secp256k1
cost_B58CHECK_ENCODING_PUBLIC_KEY_HASH_p256))
let signature_optimized =
atomic_step_cost
@@ S.(
max
cost_ENCODING_SIGNATURE_ed25519
(max
cost_ENCODING_SIGNATURE_secp256k1
cost_ENCODING_SIGNATURE_p256))
let signature_readable =
atomic_step_cost
@@ S.(
max
cost_B58CHECK_ENCODING_SIGNATURE_ed25519
(max
cost_B58CHECK_ENCODING_SIGNATURE_secp256k1
cost_B58CHECK_ENCODING_SIGNATURE_p256))
let chain_id_optimized = atomic_step_cost cost_ENCODING_CHAIN_ID
let chain_id_readable = atomic_step_cost cost_B58CHECK_ENCODING_CHAIN_ID
let timestamp_readable = atomic_step_cost cost_TIMESTAMP_READABLE_ENCODING
(* Reasonable approximation *)
let address_optimized = key_hash_optimized
(* Reasonable approximation *)
let contract_optimized = key_hash_optimized
(* Reasonable approximation *)
let contract_readable = key_hash_readable
let bls12_381_g1 = atomic_step_cost cost_ENCODING_BLS_G1
let bls12_381_g2 = atomic_step_cost cost_ENCODING_BLS_G2
let bls12_381_fr = atomic_step_cost cost_ENCODING_BLS_FR
let unparse_type ty =
atomic_step_cost
@@ cost_UNPARSE_TYPE Script_typed_ir.(ty_size ty |> Type_size.to_int)
let unparse_instr_cycle = atomic_step_cost cost_UNPARSING_CODE
let unparse_data_cycle = atomic_step_cost cost_UNPARSING_DATA
let unit = Gas.free
(** TODO: https://gitlab.com/tezos/tezos/-/issues/2340
Refine the gas model *)
let tx_rollup_l2_address = bls12_381_g1
(* Reuse 006 costs. *)
let operation bytes = Script.bytes_node_cost bytes
let sapling_transaction (t : Sapling.transaction) =
let inputs = Size.sapling_transaction_inputs t in
let outputs = Size.sapling_transaction_outputs t in
let bound_data = Size.sapling_transaction_bound_data t in
atomic_step_cost
(cost_SAPLING_TRANSACTION_ENCODING ~inputs ~outputs ~bound_data)
let sapling_transaction_deprecated (t : Sapling.Legacy.transaction) =
let inputs = List.length t.inputs in
let outputs = List.length t.outputs in
atomic_step_cost
(cost_SAPLING_TRANSACTION_ENCODING ~inputs ~outputs ~bound_data:0)
let sapling_diff (d : Sapling.diff) =
let nfs = List.length d.nullifiers in
let cms = List.length d.commitments_and_ciphertexts in
atomic_step_cost (cost_SAPLING_DIFF_ENCODING ~nfs ~cms)
let chest_key = atomic_step_cost cost_ENCODING_Chest_key
let chest ~plaintext_size =
atomic_step_cost (cost_ENCODING_Chest ~plaintext_size)
end
end
module Internal_for_tests = struct
let int_cost_of_manager_operation = Cost_of.manager_operation_int
end