123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210(*****************************************************************************)(* *)(* Open Source License *)(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)(* *)(* 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. *)(* *)(*****************************************************************************)letdecimals=3typefp_tagtypeintegral_tagmoduleS=Saturation_repr(* 1 gas unit *)letscaling_factor=S.mul_safe_of_int_exn1000moduleArith=structtype'at=S.may_saturateS.ttypefp=fp_tagttypeintegral=integral_tagtletscaling_factor=scaling_factorletsub=S.subletadd=S.addletzero=S.zeroletmin=S.minletmax=S.maxletcompare=S.comparelet(<)=S.(<)let(<>)=S.(<>)let(>)=S.(>)let(<=)=S.(<=)let(>=)=S.(>=)let(=)=S.(=)letequal=S.equalletof_int_opt=S.of_int_optletfatally_saturated_inti=failwith(string_of_inti^" should not be saturated.")letfatally_saturated_zz=failwith(Z.to_stringz^" should not be saturated.")letintegral_of_int_exni=S.(matchof_int_optiwith|None->fatally_saturated_inti|Somei'->letr=scale_fastscaling_factori'inifr=saturatedthenfatally_saturated_intielser)letintegral_exnz=matchZ.to_intzwith|i->integral_of_int_exni|exceptionZ.Overflow->fatally_saturated_zzletintegral_to_z(i:integral):Z.t=S.(to_z(ediviscaling_factor))letceilx=letr=S.eremxscaling_factorinifr=zerothenxelseaddx(subscaling_factorr)letfloorx=subx(S.eremxscaling_factor)letfpx=xletppfmtrfp=letq=S.(edivfpscaling_factor|>to_int)inletr=S.(eremfpscaling_factor|>to_int)inifCompare.Int.(r=0)thenFormat.fprintffmtr"%d"qelseFormat.fprintffmtr"%d.%0*d"qdecimalsrletpp_integral=ppletn_fp_encoding:fpData_encoding.t=S.n_encodingletz_fp_encoding:fpData_encoding.t=S.z_encodingletn_integral_encoding:integralData_encoding.t=Data_encoding.convintegral_to_zintegral_exnData_encoding.nletz_integral_encoding:integralData_encoding.t=Data_encoding.convintegral_to_zintegral_exnData_encoding.zletunsafe_fpx=matchof_int_opt(Z.to_intx)with|Someint->int|None->fatally_saturated_zxletsub_opt=S.sub_optendtypet=Unaccounted|Limitedof{remaining:Arith.fp}typecost=S.may_saturateS.tletencoding=letopenData_encodinginunion[case(Tag0)~title:"Limited"Arith.z_fp_encoding(functionLimited{remaining}->Someremaining|_->None)(funremaining->Limited{remaining});case(Tag1)~title:"Unaccounted"(constant"unaccounted")(functionUnaccounted->Some()|_->None)(fun()->Unaccounted);]letppppf=function|Unaccounted->Format.fprintfppf"unaccounted"|Limited{remaining}->Format.fprintfppf"%a units remaining"Arith.ppremainingletcost_encoding=S.z_encodingletpp_costfmtz=S.ppfmtz(* 2 units of gas *)letallocation_weight=S.(mul_fastscaling_factor(S.mul_safe_of_int_exn2))|>S.mul_safe_exnletstep_weight=scaling_factor(* 100 units of gas *)letread_base_weight=S.(mul_fastscaling_factor(S.mul_safe_of_int_exn100))|>S.mul_safe_exn(* 160 units of gas *)letwrite_base_weight=S.(mul_fastscaling_factor(S.mul_safe_of_int_exn160))|>S.mul_safe_exn(* 10 units of gas *)letbyte_read_weight=S.(mul_fastscaling_factor(S.mul_safe_of_int_exn10))|>S.mul_safe_exn(* 15 units of gas *)letbyte_written_weight=S.(mul_fastscaling_factor(S.mul_safe_of_int_exn15))|>S.mul_safe_exnletcost_to_milligas(cost:cost):Arith.fp=costletraw_consumegas_countercost=letgas=cost_to_milligascostinArith.sub_optgas_countergasletalloc_costn=S.scale_fastallocation_weightS.(addn(S.mul_safe_of_int_exn1))letalloc_bytes_costn=alloc_cost(S.safe_int((n+7)/8))letatomic_step_cost:'aS.t->cost=S.may_saturateletstep_costn=S.scale_faststep_weightnletfree=S.zeroletread_bytes_costn=S.addread_base_weight(S.scale_fastbyte_read_weight(S.safe_intn))letwrite_bytes_costn=S.addwrite_base_weight(S.scale_fastbyte_written_weight(S.safe_intn))let(+@)xy=S.addxylet(*@)xy=S.mulxyletalloc_mbytes_costn=alloc_cost(S.mul_safe_of_int_exn12)+@alloc_bytes_costn