123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262(*****************************************************************************)(* *)(* 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. *)(* *)(*****************************************************************************)typelocation=Micheline.canonical_locationletlocation_encoding=Micheline.canonical_location_encodingtypeannot=Micheline.annottypeexpr=Michelson_v1_primitives.primMicheline.canonicaltypelazy_expr=exprData_encoding.lazy_ttypenode=(location,Michelson_v1_primitives.prim)Micheline.nodeletexpr_encoding=Micheline.canonical_encoding_v1~variant:"michelson_v1"Michelson_v1_primitives.prim_encodingtypeerror+=Lazy_script_decode(* `Permanent *)let()=register_error_kind`Permanent~id:"invalid_binary_format"~title:"Invalid binary format"~description:"Could not deserialize some piece of data from its binary representation"Data_encoding.empty(functionLazy_script_decode->Some()|_->None)(fun()->Lazy_script_decode)letlazy_expr_encoding=Data_encoding.lazy_encodingexpr_encodingletlazy_exprexpr=Data_encoding.make_lazyexpr_encodingexprtypet={code:lazy_expr;storage:lazy_expr}letencoding=letopenData_encodingindef"scripted.contracts"@@conv(fun{code;storage}->(code,storage))(fun(code,storage)->{code;storage})(obj2(req"code"lazy_expr_encoding)(req"storage"lazy_expr_encoding))letint_node_size_of_numbitsn=(1,1+((n+63)/64))letint_node_sizen=int_node_size_of_numbits(Z.numbitsn)letstring_node_size_of_lengths=(1,1+((s+7)/8))letstring_node_sizes=string_node_size_of_length(String.lengths)letbytes_node_size_of_lengths=(* approx cost of indirection to the C heap *)(2,1+((s+7)/8)+12)letbytes_node_sizes=bytes_node_size_of_length(MBytes.lengths)letprim_node_size_nonrec_of_lengthsn_argsannots=letannots_length=List.fold_left(funaccs->acc+String.lengths)0annotsinifCompare.Int.(annots_length=0)then(1+n_args,2+(2*n_args))else(2+n_args,4+(2*n_args)+((annots_length+7)/8))letprim_node_size_nonrecargsannots=letn_args=List.lengthargsinprim_node_size_nonrec_of_lengthsn_argsannotsletseq_node_size_nonrec_of_lengthn_args=(1+n_args,2+(2*n_args))letseq_node_size_nonrecargs=letn_args=List.lengthargsinseq_node_size_nonrec_of_lengthn_argsletconvert_pair(i1,i2)=(Z.of_inti1,Z.of_inti2)letrecnode_sizenode=letopenMichelineinmatchnodewith|Int(_,n)->convert_pair(int_node_sizen)|String(_,s)->convert_pair(string_node_sizes)|Bytes(_,s)->convert_pair(bytes_node_sizes)|Prim(_,_,args,annot)->List.fold_left(fun(blocks,words)node->let(nblocks,nwords)=node_sizenodein(Z.addblocksnblocks,Z.addwordsnwords))(convert_pair(prim_node_size_nonrecargsannot))args|Seq(_,args)->List.fold_left(fun(blocks,words)node->let(nblocks,nwords)=node_sizenodein(Z.addblocksnblocks,Z.addwordsnwords))(convert_pair(seq_node_size_nonrecargs))argsletexpr_sizeexpr=node_size(Micheline.rootexpr)lettraversal_costnode=let(blocks,_words)=node_sizenodeinGas_limit_repr.step_costblocksletcost_of_size(blocks,words)=letopenGas_limit_reprin(Compare.Z.maxZ.zero(Z.subblocksZ.one)*@alloc_costZ.zero)+@alloc_costwords+@step_costblocksletcost_of_size_intpair=cost_of_size(convert_pairpair)letint_node_costn=cost_of_size_int(int_node_sizen)letint_node_cost_of_numbitsn=cost_of_size_int(int_node_size_of_numbitsn)letstring_node_costs=cost_of_size_int(string_node_sizes)letstring_node_cost_of_lengths=cost_of_size_int(string_node_size_of_lengths)letbytes_node_costs=cost_of_size_int(bytes_node_sizes)letbytes_node_cost_of_lengths=cost_of_size_int(bytes_node_size_of_lengths)letprim_node_cost_nonrecargsannot=cost_of_size_int(prim_node_size_nonrecargsannot)letseq_node_cost_nonrecargs=cost_of_size_int(seq_node_size_nonrecargs)letseq_node_cost_nonrec_of_lengthn_args=cost_of_size_int(seq_node_size_nonrec_of_lengthn_args)letdeserialized_costexpr=cost_of_size(expr_sizeexpr)letserialized_costbytes=letopenGas_limit_reprinalloc_mbytes_cost(MBytes.lengthbytes)letforce_decodelexpr=letaccount_deserialization_cost=Data_encoding.apply_lazy~fun_value:(fun_->false)~fun_bytes:(fun_->true)~fun_combine:(fun__->false)lexprinmatchData_encoding.force_decodelexprwith|Somev->ifaccount_deserialization_costthenok(v,deserialized_costv)elseok(v,Gas_limit_repr.free)|None->errorLazy_script_decodeletforce_bytesexpr=letopenGas_limit_reprinletaccount_serialization_cost=Data_encoding.apply_lazy~fun_value:(funv->Somev)~fun_bytes:(fun_->None)~fun_combine:(fun__->None)exprinmatchData_encoding.force_bytesexprwith|bytes->(matchaccount_serialization_costwith|Somev->ok(bytes,traversal_cost(Micheline.rootv)+@serialized_costbytes)|None->ok(bytes,Gas_limit_repr.free))|exception_->errorLazy_script_decodeletminimal_deserialize_costlexpr=Data_encoding.apply_lazy~fun_value:(fun_->Gas_limit_repr.free)~fun_bytes:(funb->serialized_costb)~fun_combine:(func_free_->c_free)lexprletunit=Micheline.strip_locations(Prim(0,Michelson_v1_primitives.D_Unit,[],[]))letunit_parameter=lazy_exprunitletis_unit_parameter=letunit_bytes=Data_encoding.force_bytesunit_parameterinData_encoding.apply_lazy~fun_value:(funv->matchMicheline.rootvwith|Prim(_,Michelson_v1_primitives.D_Unit,[],[])->true|_->false)~fun_bytes:(funb->MBytes.(=)bunit_bytes)~fun_combine:(funres_->res)letrecstrip_annotationsnode=letopenMichelineinmatchnodewith|(Int(_,_)|String(_,_)|Bytes(_,_))asleaf->leaf|Prim(loc,name,args,_)->Prim(loc,name,List.mapstrip_annotationsargs,[])|Seq(loc,args)->Seq(loc,List.mapstrip_annotationsargs)letrecmicheline_nodesnodeacck=matchnodewith|Micheline.Int(_,_)->k(acc+1)|Micheline.String(_,_)->k(acc+1)|Micheline.Bytes(_,_)->k(acc+1)|Micheline.Prim(_,_,subterms,_)->micheline_nodes_listsubterms(acc+1)k|Micheline.Seq(_,subterms)->micheline_nodes_listsubterms(acc+1)kandmicheline_nodes_listsubtermsacck=matchsubtermswith|[]->kacc|n::nodes->micheline_nodes_listnodesacc(funacc->micheline_nodesnacck)letmicheline_nodesnode=micheline_nodesnode0(funx->x)letcost_MICHELINE_STRIP_LOCATIONSsize=Z.mul(Z.of_intsize)(Z.of_int100)letstrip_locations_costnode=letnodes=micheline_nodesnodeinGas_limit_repr.atomic_step_cost(cost_MICHELINE_STRIP_LOCATIONSnodes)