1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022(*****************************************************************************)(* *)(* Open Source License *)(* Copyright (c) 2018 Nomadic Development. <contact@tezcore.com> *)(* Copyright (c) 2021-2022 Nomadic Labs, <contact@nomadic-labs.com> *)(* Copyright (c) 2022 TriliTech <contact@trili.tech> *)(* *)(* 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. *)(* *)(*****************************************************************************)openProtocolopenAlpha_context(** The assumed number of blocks between operation-creation time and
the actual time when the operation is included in a block. *)letdefault_operation_inclusion_latency=3typeEnvironment.Error_monad.error+=Cannot_parse_operation(* `Branch *)typeEnvironment.Error_monad.error+=Cannot_serialize_logtypeEnvironment.Error_monad.error+=Cannot_retrieve_predecessor_levellet()=Environment.Error_monad.register_error_kind`Branch~id:"operation.cannot_parse"~title:"Cannot parse operation"~description:"The operation is ill-formed or for another protocol version"~pp:(funppf()->Format.fprintfppf"The operation cannot be parsed")Data_encoding.unit(functionCannot_parse_operation->Some()|_->None)(fun()->Cannot_parse_operation);(* Cannot serialize log *)Environment.Error_monad.register_error_kind`Temporary~id:"michelson_v1.cannot_serialize_log"~title:"Not enough gas to serialize execution trace"~description:"Execution trace with stacks was to big to be serialized with the \
provided gas"Data_encoding.empty(functionCannot_serialize_log->Some()|_->None)(fun()->Cannot_serialize_log);Environment.Error_monad.register_error_kind`Temporary~id:"cannot_retrieve_predecessor_level"~title:"Cannot retrieve predecessor level"~description:"Cannot retrieve predecessor level."Data_encoding.empty(functionCannot_retrieve_predecessor_level->Some()|_->None)(fun()->Cannot_retrieve_predecessor_level)moduleView_helpers=structopenTezos_michelinetypeEnvironment.Error_monad.error+=Viewed_contract_has_no_scripttypeEnvironment.Error_monad.error+=View_callback_origination_failedtypeEnvironment.Error_monad.error+=|Illformed_view_typeofEntrypoint.t*Script.exprtypeEnvironment.Error_monad.error+=|View_never_returnsofEntrypoint.t*Contract.ttypeEnvironment.Error_monad.error+=|View_unexpected_returnofEntrypoint.t*Contract.ttypeEnvironment.Error_monad.error+=View_not_foundofContract.t*stringtypeEnvironment.Error_monad.error+=Viewer_unexpected_storagelet()=Environment.Error_monad.register_error_kind`Permanent~id:"viewedContractHasNoScript"~title:"Viewed contract has no script"~description:"A view was called on a contract with no script."~pp:(funppf()->Format.fprintfppf"A view was called on a contract with no script.")Data_encoding.(unit)(functionViewed_contract_has_no_script->Some()|_->None)(fun()->Viewed_contract_has_no_script);Environment.Error_monad.register_error_kind`Permanent~id:"viewCallbackOriginationFailed"~title:"View callback origination failed"~description:"View callback origination failed"~pp:(funppf()->Format.fprintfppf"Error during origination of view callback contract.")Data_encoding.(unit)(functionView_callback_origination_failed->Some()|_->None)(fun()->View_callback_origination_failed);Environment.Error_monad.register_error_kind`Permanent~id:"illformedViewType"~title:"An entrypoint type is incompatible with TZIP-4 view type."~description:"An entrypoint type is incompatible with TZIP-4 view type."~pp:(funppf(entrypoint,typ)->Format.fprintfppf"The view %a has type %a, it is not compatible with a TZIP-4 view \
type."Entrypoint.ppentrypointMicheline_printer.print_expr(Micheline_printer.printable(funx->x)(Michelson_v1_primitives.strings_of_primstyp)))Data_encoding.(obj2(req"entrypoint"Entrypoint.simple_encoding)(req"type"Script.expr_encoding))(functionIllformed_view_type(etp,exp)->Some(etp,exp)|_->None)(fun(etp,exp)->Illformed_view_type(etp,exp));Environment.Error_monad.register_error_kind`Permanent~id:"viewNeverReturns"~title:"A view never returned a transaction to the given callback contract"~description:"A view never initiated a transaction to the given callback contract."~pp:(funppf(entrypoint,callback)->Format.fprintfppf"The view %a never initiated a transaction to the given callback \
contract %a."Entrypoint.ppentrypointContract.ppcallback)Data_encoding.(obj2(req"entrypoint"Entrypoint.simple_encoding)(req"callback"Contract.encoding))(functionView_never_returns(e,c)->Some(e,c)|_->None)(fun(e,c)->View_never_returns(e,c));Environment.Error_monad.register_error_kind`Permanent~id:"viewUnexpectedReturn"~title:"A view returned an unexpected list of operations"~description:"A view initiated a list of operations while the TZIP-4 standard \
expects only a transaction to the given callback contract."~pp:(funppf(entrypoint,callback)->Format.fprintfppf"The view %a initiated a list of operations while the TZIP-4 \
standard expects only a transaction to the given callback contract \
%a."Entrypoint.ppentrypointContract.ppcallback)Data_encoding.(obj2(req"entrypoint"Entrypoint.simple_encoding)(req"callback"Contract.encoding))(functionView_never_returns(e,c)->Some(e,c)|_->None)(fun(e,c)->View_never_returns(e,c));Environment.Error_monad.register_error_kind`Permanent~id:"viewNotFound"~title:"A view could not be found"~description:"The contract does not have a view of the given name."~pp:(funppf(contract,name)->Format.fprintfppf"The contract %a does not have a view named `%s`."Contract.ppcontractname)Data_encoding.(obj2(req"contract"Contract.encoding)(req"view"string))(functionView_not_found(k,n)->Some(k,n)|_->None)(fun(k,n)->View_not_found(k,n));Environment.Error_monad.register_error_kind`Permanent~id:"viewerUnexpectedStorage"~title:"A VIEW instruction returned an unexpected value"~description:"A VIEW instruction returned an unexpected value."~pp:(funppf()->Format.fprintfppf"The simulated view returned an unexpected value.")Data_encoding.unit(functionViewer_unexpected_storage->Some()|_->None)(fun()->Viewer_unexpected_storage)(* This script is actually never run, its usage is to ensure a
contract that has the type `contract <ty>` is originated, which
will be required as callback of the view. *)letmake_tzip4_viewer_scriptty:Script.t=letloc=0inletty=Micheline.roottyinletcode=Micheline.strip_locations@@Micheline.Seq(loc,[Micheline.Prim(loc,Script.K_parameter,[ty],[]);Micheline.Prim(loc,Script.K_storage,[Micheline.Prim(loc,Script.T_unit,[],[])],[]);Micheline.Prim(loc,Script.K_code,[Micheline.Prim(loc,Script.I_FAILWITH,[],[])],[]);])inletstorage=Micheline.strip_locations(Micheline.Prim(loc,Script.D_Unit,[],[]))in{code=Script.lazy_exprcode;storage=Script.lazy_exprstorage}letmake_view_parameterinputcallback=letloc=0inMicheline.strip_locations(Micheline.Prim(loc,Script.D_Pair,[input;Micheline.Bytes(loc,Data_encoding.Binary.to_bytes_exnContract.encodingcallback);],[]))letextract_view_output_typeentrypointty=matchMicheline.roottywith|Micheline.Prim(_,Script.T_pair,[_;Micheline.Prim(_,Script.T_contract,[ty],_)],_)->ok(Micheline.strip_locationsty)|_->Environment.Error_monad.error(Illformed_view_type(entrypoint,ty))(* 'view' entrypoints returns their value by calling a callback contract, thus
the expected result is a unique internal transaction to this callback. *)letextract_parameter_from_operationsentrypointoperationscallback=letunexpected_return=Environment.Error_monad.error@@View_unexpected_return(entrypoint,callback)inmatchoperationswith|[Script_typed_ir.Internal_operation{operation=Transaction{transaction={destination;parameters;entrypoint=_;amount=_};parameters=_;parameters_ty=_;location=_;};source=_;nonce=_;};]whenDestination.equaldestination(Contractcallback)->okparameters|[]->Environment.Error_monad.error(View_never_returns(entrypoint,callback))|_->unexpected_return(* [make_michelson_viewer_script contract view input input_ty output_ty]
generates a script that calls a view from a given contract, and stores the
result in its storage. *)letmake_michelson_viewer_scriptaddressviewinputinput_tyoutput_ty:Script.t=letloc=0inletaddress=Micheline.String(loc,Contract.to_b58checkaddress)inletpushtyvalue=Micheline.Prim(loc,Script.I_PUSH,[ty;value],[])inletstorage_decl=Micheline.Prim(loc,Script.T_option,[output_ty],[])inletbody=Micheline.Seq(loc,[Micheline.Prim(loc,Script.I_DROP,[],[]);push(Micheline.Prim(loc,Script.T_address,[],[]))address;pushinput_ty(Micheline.rootinput);Micheline.Prim(loc,Script.I_VIEW,[Micheline.String(loc,view);output_ty],[]);Micheline.Prim(loc,Script.I_NIL,[Micheline.Prim(loc,Script.T_operation,[],[])],[]);Micheline.Prim(loc,Script.I_PAIR,[],[]);])inletcode=Micheline.strip_locations@@Micheline.Seq(loc,[Micheline.Prim(loc,Script.K_parameter,[Micheline.Prim(loc,Script.T_unit,[],[])],[]);Micheline.Prim(loc,Script.K_storage,[storage_decl],[]);Micheline.Prim(loc,Script.K_code,[body],[]);])inletstorage=Micheline.strip_locations(Micheline.Prim(loc,Script.D_None,[],[]))in{code=Script.lazy_exprcode;storage=Script.lazy_exprstorage}(* Extracts the value from the mock script generated by
[make_michelson_viewer_script]. *)letextract_value_from_storage(storage:Script.expr)=matchMicheline.rootstoragewith|Micheline.Prim(_,Script.D_Some,[value],[])->okvalue|_->Environment.Error_monad.error@@Viewer_unexpected_storageendmoduleRPC=structopenEnvironmentopenAlpha_contextopenEnvironment.Error_monadletparse_operation(op:Operation.raw)=matchData_encoding.Binary.of_bytes_optOperation.protocol_data_encodingop.protowith|Someprotocol_data->ok{shell=op.shell;protocol_data}|None->errorCannot_parse_operationletpath=Tezos_rpc.Path.(open_root/"helpers")moduleRegistration=structletpatched_services=ref(RPC_directory.empty:Updater.rpc_contextTezos_rpc.Directory.t)letregister0_fullctxt~chunkedsf=patched_services:=RPC_directory.register~chunked!patched_servicess(functxtqi->Services_registration.rpc_initctxt`Head_level>>=?functxt->fctxtqi)letregister0~chunkedsf=register0_fullctxt~chunkeds(fun{context;_}->fcontext)letregister0_fullctxt_successor_level~chunkedsf=patched_services:=RPC_directory.register~chunked!patched_servicess(functxtqi->letmode=ifq#successor_levelthen`Successor_levelelse`Head_levelinServices_registration.rpc_initctxtmode>>=?functxt->fctxtqi)letregister0_successor_level~chunkedsf=register0_fullctxt_successor_level~chunkeds(fun{context;_}->fcontext)letregister0_noctxt~chunkedsf=patched_services:=RPC_directory.register~chunked!patched_servicess(fun_qi->fqi)letopt_register0_fullctxt~chunkedsf=patched_services:=RPC_directory.opt_register~chunked!patched_servicess(functxtqi->Services_registration.rpc_initctxt`Head_level>>=?functxt->fctxtqi)letopt_register0~chunkedsf=opt_register0_fullctxt~chunkeds(fun{context;_}->fcontext)letregister1_fullctxt~chunkedsf=patched_services:=RPC_directory.register~chunked!patched_servicess(fun(ctxt,arg)qi->Services_registration.rpc_initctxt`Head_level>>=?functxt->fctxtargqi)letregister1~chunkedsf=register1_fullctxt~chunkeds(fun{context;_}x->fcontextx)letregister2_fullctxt~chunkedsf=patched_services:=RPC_directory.register~chunked!patched_servicess(fun((ctxt,arg1),arg2)qi->Services_registration.rpc_initctxt`Head_level>>=?functxt->fctxtarg1arg2qi)letregister2~chunkedsf=register2_fullctxt~chunkeds(fun{context;_}a1a2qi->fcontexta1a2qi)endletunparsing_mode_encoding=letopenScript_ir_translatorinletopenData_encodinginunion~tag_size:`Uint8[case(Tag0)~title:"Readable"(constant"Readable")(function|Readable->Some()|Optimized|Optimized_legacy->None)(fun()->Readable);case(Tag1)~title:"Optimized"(constant"Optimized")(function|Optimized->Some()|Readable|Optimized_legacy->None)(fun()->Optimized);case(Tag2)~title:"Optimized_legacy"(constant"Optimized_legacy")(function|Optimized_legacy->Some()|Readable|Optimized->None)(fun()->Optimized_legacy);]moduleScripts=structmoduleS=structopenData_encodingletpath=Tezos_rpc.Path.(path/"scripts")letrun_code_input_encoding=merge_objs(obj10(req"script"Script.expr_encoding)(req"storage"Script.expr_encoding)(req"input"Script.expr_encoding)(req"amount"Tez.encoding)(opt"balance"Tez.encoding)(req"chain_id"Chain_id.encoding)(opt"source"Contract.encoding)(opt"payer"Contract.encoding)(opt"self"Contract.encoding)(dft"entrypoint"Entrypoint.simple_encodingEntrypoint.default))(obj4(opt"unparsing_mode"unparsing_mode_encoding)(opt"gas"Gas.Arith.z_integral_encoding)(opt"now"Script_timestamp.encoding)(opt"level"Script_int.n_encoding))letrun_code_output_encoding=conv(fun(storage,operations,lazy_storage_diff)->(storage,operations,lazy_storage_diff))(fun(storage,operations,lazy_storage_diff)->(storage,operations,lazy_storage_diff))(obj3(req"storage"Script.expr_encoding)(req"operations"(listApply_results.internal_contents_encoding))(opt"lazy_storage_diff"Lazy_storage.encoding))lettrace_code_input_encoding=run_code_input_encodinglettrace_encoding=def"scripted.trace"@@list@@obj3(req"location"Script.location_encoding)(req"gas"Gas.encoding)(req"stack"(listScript.expr_encoding))lettrace_code_output_encoding=conv(fun(storage,operations,trace,lazy_storage_diff)->(storage,operations,trace,lazy_storage_diff))(fun(storage,operations,trace,lazy_storage_diff)->(storage,operations,trace,lazy_storage_diff))(obj4(req"storage"Script.expr_encoding)(req"operations"(listApply_results.internal_contents_encoding))(req"trace"trace_encoding)(opt"lazy_storage_diff"Lazy_storage.encoding))letrun_tzip4_view_encoding=letopenData_encodinginobj10(req"contract"Contract.encoding)(req"entrypoint"Entrypoint.simple_encoding)(req"input"Script.expr_encoding)(req"chain_id"Chain_id.encoding)(opt"source"Contract.encoding)(opt"payer"Contract.encoding)(opt"gas"Gas.Arith.z_integral_encoding)(req"unparsing_mode"unparsing_mode_encoding)(opt"now"Script_timestamp.encoding)(opt"level"Script_int.n_encoding)letrun_script_view_encoding=letopenData_encodinginmerge_objs(obj10(req"contract"Contract.encoding)(req"view"string)(req"input"Script.expr_encoding)(dft"unlimited_gas"boolfalse)(req"chain_id"Chain_id.encoding)(opt"source"Contract.encoding)(opt"payer"Contract.encoding)(opt"gas"Gas.Arith.z_integral_encoding)(req"unparsing_mode"unparsing_mode_encoding)(opt"now"Script_timestamp.encoding))(obj1(opt"level"Script_int.n_encoding))letrun_code=Tezos_rpc.Service.post_service~description:"Run a piece of code in the current context"~query:Tezos_rpc.Query.empty~input:run_code_input_encoding~output:run_code_output_encodingTezos_rpc.Path.(path/"run_code")lettrace_code=Tezos_rpc.Service.post_service~description:"Run a piece of code in the current context, keeping a trace"~query:Tezos_rpc.Query.empty~input:trace_code_input_encoding~output:trace_code_output_encodingTezos_rpc.Path.(path/"trace_code")letrun_tzip4_view=Tezos_rpc.Service.post_service~description:"Simulate a call to a view following the TZIP-4 standard. See \
https://gitlab.com/tzip/tzip/-/blob/master/proposals/tzip-4/tzip-4.md#view-entrypoints."~input:run_tzip4_view_encoding~output:(obj1(req"data"Script.expr_encoding))~query:Tezos_rpc.Query.empty(* This path should be deprecated in the future *)Tezos_rpc.Path.(path/"run_view")letrun_script_view=Tezos_rpc.Service.post_service~description:"Simulate a call to a michelson view"~input:run_script_view_encoding~output:(obj1(req"data"Script.expr_encoding))~query:Tezos_rpc.Query.emptyTezos_rpc.Path.(path/"run_script_view")lettypecheck_code=Tezos_rpc.Service.post_service~description:"Typecheck a piece of code in the current context"~query:Tezos_rpc.Query.empty~input:(obj4(req"program"Script.expr_encoding)(opt"gas"Gas.Arith.z_integral_encoding)(opt"legacy"bool)(opt"show_types"bool))~output:(obj2(req"type_map"Script_tc_errors_registration.type_map_enc)(req"gas"Gas.encoding))Tezos_rpc.Path.(path/"typecheck_code")letscript_size=Tezos_rpc.Service.post_service~description:"Compute the size of a script in the current context"~query:Tezos_rpc.Query.empty~input:(obj4(req"program"Script.expr_encoding)(req"storage"Script.expr_encoding)(opt"gas"Gas.Arith.z_integral_encoding)(opt"legacy"bool))~output:(obj1(req"script_size"int31))Tezos_rpc.Path.(path/"script_size")lettypecheck_data=Tezos_rpc.Service.post_service~description:"Check that some data expression is well formed and of a given \
type in the current context"~query:Tezos_rpc.Query.empty~input:(obj4(req"data"Script.expr_encoding)(req"type"Script.expr_encoding)(opt"gas"Gas.Arith.z_integral_encoding)(opt"legacy"bool))~output:(obj1(req"gas"Gas.encoding))Tezos_rpc.Path.(path/"typecheck_data")letpack_data=Tezos_rpc.Service.post_service~description:"Computes the serialized version of some data expression using the \
same algorithm as script instruction PACK"~input:(obj3(req"data"Script.expr_encoding)(req"type"Script.expr_encoding)(opt"gas"Gas.Arith.z_integral_encoding))~output:(obj2(req"packed"bytes)(req"gas"Gas.encoding))~query:Tezos_rpc.Query.emptyTezos_rpc.Path.(path/"pack_data")letnormalize_data=Tezos_rpc.Service.post_service~description:"Normalizes some data expression using the requested unparsing mode"~input:(obj4(req"data"Script.expr_encoding)(req"type"Script.expr_encoding)(req"unparsing_mode"unparsing_mode_encoding)(opt"legacy"bool))~output:(obj1(req"normalized"Script.expr_encoding))~query:Tezos_rpc.Query.emptyTezos_rpc.Path.(path/"normalize_data")letnormalize_script=Tezos_rpc.Service.post_service~description:"Normalizes a Michelson script using the requested unparsing mode"~input:(obj2(req"script"Script.expr_encoding)(req"unparsing_mode"unparsing_mode_encoding))~output:(obj1(req"normalized"Script.expr_encoding))~query:Tezos_rpc.Query.emptyTezos_rpc.Path.(path/"normalize_script")letnormalize_type=Tezos_rpc.Service.post_service~description:"Normalizes some Michelson type by expanding `pair a b c` as `pair \
a (pair b c)"~input:(obj1(req"type"Script.expr_encoding))~output:(obj1(req"normalized"Script.expr_encoding))~query:Tezos_rpc.Query.emptyTezos_rpc.Path.(path/"normalize_type")letrun_operation=Tezos_rpc.Service.post_service~description:"Run an operation with the context of the given block and without \
signature checks. Return the operation application result, \
including the consumed gas."~query:Tezos_rpc.Query.empty~input:(obj2(req"operation"Operation.encoding)(req"chain_id"Chain_id.encoding))~output:Apply_results.operation_data_and_metadata_encodingTezos_rpc.Path.(path/"run_operation")letsimulate_query=letopenTezos_rpc.Queryinquery(funsuccessor_level->objectmethodsuccessor_level=successor_levelend)|+flag~descr:"If true, the simulation is done on the successor level of the \
current context.""successor_level"(funt->t#successor_level)|>sealletsimulate_operation=Tezos_rpc.Service.post_service~description:"Simulate running an operation at some future moment (based on the \
number of blocks given in the `latency` argument), and return the \
operation application result. The result is the same as \
run_operation except for the consumed gas, which depends on the \
contents of the cache at that future moment. This RPC estimates \
future gas consumption by trying to predict the state of the \
cache using some heuristics."~query:simulate_query~input:(obj4(opt"blocks_before_activation"int32)(req"operation"Operation.encoding)(req"chain_id"Chain_id.encoding)(dft"latency"int16default_operation_inclusion_latency))~output:Apply_results.operation_data_and_metadata_encodingTezos_rpc.Path.(path/"simulate_operation")letsimulate_tx_rollup_operation=Tezos_rpc.Service.post_service~description:"Simulate a tx rollup operation"~query:Tezos_rpc.Query.empty~input:(obj4(opt"blocks_before_activation"int32)(req"operation"Operation.encoding)(req"chain_id"Chain_id.encoding)(dft"latency"int16default_operation_inclusion_latency))~output:Apply_results.operation_data_and_metadata_encodingTezos_rpc.Path.(path/"simulate_tx_rollup_operation")letentrypoint_type=Tezos_rpc.Service.post_service~description:"Return the type of the given entrypoint"~query:Tezos_rpc.Query.empty~input:(obj2(req"script"Script.expr_encoding)(dft"entrypoint"Entrypoint.simple_encodingEntrypoint.default))~output:(obj1(req"entrypoint_type"Script.expr_encoding))Tezos_rpc.Path.(path/"entrypoint")letlist_entrypoints=Tezos_rpc.Service.post_service~description:"Return the list of entrypoints of the given script"~query:Tezos_rpc.Query.empty~input:(obj1(req"script"Script.expr_encoding))~output:(obj2(dft"unreachable"(Data_encoding.list(obj1(req"path"(Data_encoding.listMichelson_v1_primitives.prim_encoding))))[])(req"entrypoints"(assocScript.expr_encoding)))Tezos_rpc.Path.(path/"entrypoints")endmoduletypeUNPARSING_MODE=sigvalunparsing_mode:Script_ir_translator.unparsing_modeendmoduleTraced_interpreter(Unparsing_mode:UNPARSING_MODE)=structtypelog_element=|Log:context*Script.location*('a*'s)*('a,'s)Script_typed_ir.stack_ty->log_elementletunparse_stackctxt(stack,stack_ty)=(* We drop the gas limit as this function is only used for debugging/errors. *)letctxt=Gas.set_unlimitedctxtinletrecunparse_stack:typeas.(a,s)Script_typed_ir.stack_ty*(a*s)->Script.exprlisttzresultLwt.t=function|Bot_t,(EmptyCell,EmptyCell)->return_nil|Item_t(ty,rest_ty),(v,rest)->Script_ir_translator.unparse_datactxtUnparsing_mode.unparsing_modetyv>>=?fun(data,_ctxt)->unparse_stack(rest_ty,rest)>|=?funrest->letdata=Micheline.strip_locationsdataindata::restinunparse_stack(stack_ty,stack)lettrace_logger():Script_typed_ir.logger=letlog:log_elementlistref=ref[]inletlog_interp_ctxtlocstystack=log:=Log(ctxt,loc,stack,sty)::!loginletlog_entry__ctxt_loc_sty_stack=()inletlog_exit_ctxtlocstystack=log:=Log(ctxt,loc,stack,sty)::!loginletlog_control_=()inletget_log()=List.map_es(fun(Log(ctxt,loc,stack,stack_ty))->traceCannot_serialize_log(unparse_stackctxt(stack,stack_ty))>>=?funstack->return(loc,Gas.levelctxt,stack))!log>>=?funres->return(Some(List.revres))in{log_exit;log_entry;log_interp;get_log;log_control}letexecutectxtstep_constants~script~entrypoint~parameter=letopenScript_interpreterinletlogger=trace_logger()inexecute~logger~cached_script:NonectxtUnparsing_mode.unparsing_modestep_constants~script~entrypoint~parameter~internal:true>>=?funres->logger.get_log()>|=?funtrace->lettrace=Option.value~default:[]tracein(res,trace)endlettypecheck_data:legacy:bool->context->Script.expr*Script.expr->contexttzresultLwt.t=fun~legacyctxt(data,exp_ty)->record_trace(Script_tc_errors.Ill_formed_type(None,exp_ty,0))(Script_ir_translator.parse_passable_tyctxt~legacy(Micheline.rootexp_ty))>>?=fun(Ex_tyexp_ty,ctxt)->trace_eval(fun()->letexp_ty=Script_ir_translator.serialize_ty_for_errorexp_tyinScript_tc_errors.Ill_typed_data(None,data,exp_ty))(letallow_forged=true(* Safe since we ignore the value afterwards. *)inScript_ir_translator.parse_datactxt~legacy~allow_forgedexp_ty(Micheline.rootdata))>|=?fun(_,ctxt)->ctxtmoduleUnparse_types=struct(* Same as the unparsing functions for types in Script_ir_translator but
does not consume gas and never folds (pair a (pair b c)) *)openMichelineopenMichelson_v1_primitivesopenScript_typed_irletrecunparse_comparable_ty:typealoc.loc:loc->acomparable_ty->(loc,Script.prim)Micheline.node=fun~loc->function|Unit_t->Prim(loc,T_unit,[],[])|Never_t->Prim(loc,T_never,[],[])|Int_t->Prim(loc,T_int,[],[])|Nat_t->Prim(loc,T_nat,[],[])|Signature_t->Prim(loc,T_signature,[],[])|String_t->Prim(loc,T_string,[],[])|Bytes_t->Prim(loc,T_bytes,[],[])|Mutez_t->Prim(loc,T_mutez,[],[])|Bool_t->Prim(loc,T_bool,[],[])|Key_hash_t->Prim(loc,T_key_hash,[],[])|Key_t->Prim(loc,T_key,[],[])|Timestamp_t->Prim(loc,T_timestamp,[],[])|Address_t->Prim(loc,T_address,[],[])|Tx_rollup_l2_address_t->Prim(loc,T_tx_rollup_l2_address,[],[])|Chain_id_t->Prim(loc,T_chain_id,[],[])|Pair_t(l,r,_meta,YesYes)->lettl=unparse_comparable_ty~loclinlettr=unparse_comparable_ty~locrinPrim(loc,T_pair,[tl;tr],[])|Union_t(l,r,_meta,YesYes)->lettl=unparse_comparable_ty~loclinlettr=unparse_comparable_ty~locrinPrim(loc,T_or,[tl;tr],[])|Option_t(t,_meta,Yes)->Prim(loc,T_option,[unparse_comparable_ty~loct],[])letunparse_memo_size~locmemo_size=letz=Alpha_context.Sapling.Memo_size.unparse_to_zmemo_sizeinInt(loc,z)letrecunparse_ty:typeaacloc.loc:loc->(a,ac)ty->(loc,Script.prim)Micheline.node=fun~locty->letreturn(name,args,annot)=Prim(loc,name,args,annot)inmatchtywith|Unit_t->return(T_unit,[],[])|Int_t->return(T_int,[],[])|Nat_t->return(T_nat,[],[])|Signature_t->return(T_signature,[],[])|String_t->return(T_string,[],[])|Bytes_t->return(T_bytes,[],[])|Mutez_t->return(T_mutez,[],[])|Bool_t->return(T_bool,[],[])|Key_hash_t->return(T_key_hash,[],[])|Key_t->return(T_key,[],[])|Timestamp_t->return(T_timestamp,[],[])|Address_t->return(T_address,[],[])|Tx_rollup_l2_address_t->return(T_tx_rollup_l2_address,[],[])|Operation_t->return(T_operation,[],[])|Chain_id_t->return(T_chain_id,[],[])|Never_t->return(T_never,[],[])|Bls12_381_g1_t->return(T_bls12_381_g1,[],[])|Bls12_381_g2_t->return(T_bls12_381_g2,[],[])|Bls12_381_fr_t->return(T_bls12_381_fr,[],[])|Contract_t(ut,_meta)->lett=unparse_ty~locutinreturn(T_contract,[t],[])|Pair_t(utl,utr,_meta,_)->letannot=[]inlettl=unparse_ty~locutlinlettr=unparse_ty~locutrinreturn(T_pair,[tl;tr],annot)|Union_t(utl,utr,_meta,_)->letannot=[]inlettl=unparse_ty~locutlinlettr=unparse_ty~locutrinreturn(T_or,[tl;tr],annot)|Lambda_t(uta,utr,_meta)->letta=unparse_ty~locutainlettr=unparse_ty~locutrinreturn(T_lambda,[ta;tr],[])|Option_t(ut,_meta,_)->letannot=[]inletut=unparse_ty~locutinreturn(T_option,[ut],annot)|List_t(ut,_meta)->lett=unparse_ty~locutinreturn(T_list,[t],[])|Ticket_t(ut,_meta)->lett=unparse_comparable_ty~locutinreturn(T_ticket,[t],[])|Set_t(ut,_meta)->lett=unparse_comparable_ty~locutinreturn(T_set,[t],[])|Map_t(uta,utr,_meta)->letta=unparse_comparable_ty~locutainlettr=unparse_ty~locutrinreturn(T_map,[ta;tr],[])|Big_map_t(uta,utr,_meta)->letta=unparse_comparable_ty~locutainlettr=unparse_ty~locutrinreturn(T_big_map,[ta;tr],[])|Sapling_transaction_tmemo_size->return(T_sapling_transaction,[unparse_memo_size~locmemo_size],[])|Sapling_transaction_deprecated_tmemo_size->return(T_sapling_transaction_deprecated,[unparse_memo_size~locmemo_size],[])|Sapling_state_tmemo_size->return(T_sapling_state,[unparse_memo_size~locmemo_size],[])|Chest_t->return(T_chest,[],[])|Chest_key_t->return(T_chest_key,[],[])endletrun_operation_servicectxt()({shell;protocol_data=Operation_dataprotocol_data},chain_id)=(* this code is a duplicate of Apply without signature check *)letretcontents=(Operation_dataprotocol_data,Apply_results.Operation_metadata{contents})inletoperation:_operation={shell;protocol_data}inlethash=Operation.hash{shell;protocol_data}inletctxt=Origination_nonce.initctxthashinletpayload_producer=Tezos_crypto.Signature.V0.Public_key_hash.zeroinmatchprotocol_data.contentswith|Single(Manager_operation_)asop->Apply.precheck_manager_contents_listctxtop~mempool_mode:true>>=?fun(ctxt,prechecked_contents_list)->(* removed signature check here *)Apply.apply_manager_contents_listctxtOptimized~payload_producerchain_idprechecked_contents_list>|=fun(_ctxt,result)->ok@@retresult|Cons(Manager_operation_,_)asop->Apply.precheck_manager_contents_listctxtop~mempool_mode:true>>=?fun(ctxt,prechecked_contents_list)->(* removed signature check here *)Apply.apply_manager_contents_listctxtOptimized~payload_producerchain_idprechecked_contents_list>|=fun(_ctxt,result)->ok@@retresult|_->letpredecessor_level=matchAlpha_context.Level.predctxt(Alpha_context.Level.currentctxt)with|Somelevel->level|None->assertfalseinAlpha_context.Round.getctxt>>=?funpredecessor_round->Apply.apply_contents_listctxtchain_id(Partial_construction{predecessor_level;predecessor_round;grand_parent_round=Round.zero;})Optimized~payload_produceroperationoperation.protocol_data.contents>|=?fun(_ctxt,result)->retresult(*
The execution of an operation depends on the state of the
cache. In particular, gas consumption is usually impacted by
cache hits and misses.
Unfortunately, the state of the cache is different between the
context at operation-creation time and the context when is
included in a block.
Therefore, the simulation tries to predict the state of the
cache in a [time_in_blocks] assumed to be close to the inclusion
time of the operation.
*)letsimulate_operation_servicectxt(_simulate_query:<successor_level:bool>)(blocks_before_activation,op,chain_id,time_in_blocks)=Cache.Admin.future_cache_expectationctxt~time_in_blocks?blocks_before_activation>>=?functxt->run_operation_servicectxt()(op,chain_id)letdefault_from_contextctxtget=function|None->getctxt|Somex->returnx(* A convenience type for return values of [ensure_contracts_exist] below. *)typerun_code_config={balance:Tez.t;self:Contract.t;payer:Contract.t;source:Contract.t;}(* 4_000_000 ꜩ *)letdefault_balance=Tez.of_mutez_exn4_000_000_000_000Lletregister()=letoriginate_dummy_contractctxtscriptbalance=letctxt=Origination_nonce.initctxtOperation_hash.zeroinLwt.return(Contract.fresh_contract_from_current_noncectxt)>>=?fun(ctxt,dummy_contract)->Contract.raw_originatectxt~prepaid_bootstrap_storage:falsedummy_contract~script:(script,None)>>=?functxt->Token.transfer~origin:Simulationctxt`Minted(`Contractdummy_contract)balance>>=?fun(ctxt,_)->return(ctxt,dummy_contract)inletconfigure_contractsctxtscriptbalance~src_opt~pay_opt~self_opt=(matchself_optwith|None->letbalance=Option.value~default:default_balancebalanceinoriginate_dummy_contractctxtscriptbalance>>=?fun(ctxt,addr)->return(ctxt,addr,balance)|Someaddr->default_from_contextctxt(func->Contract.get_balancecaddr)balance>>=?funbal->return(ctxt,addr,bal))>>=?fun(ctxt,self,balance)->letsource,payer=match(src_opt,pay_opt)with|None,None->(self,self)|Somec,None|None,Somec->(c,c)|Somesrc,Somepay->(src,pay)inreturn(ctxt,{balance;self;source;payer})inletscript_entrypoint_typectxtexprentrypoint=letctxt=Gas.set_unlimitedctxtinletlegacy=falseinletopenScript_ir_translatorinparse_toplevelctxt~legacyexpr>>=?fun({arg_type;_},ctxt)->Lwt.return(parse_parameter_ty_and_entrypointsctxt~legacyarg_type>>?fun(Ex_parameter_ty_and_entrypoints{arg_type;entrypoints},_)->Gas_monad.runctxt@@Script_ir_translator.find_entrypoint~error_details:Informativearg_typeentrypointsentrypoint>>?fun(r,_ctxt)->r>|?fun(Ex_ty_cstr{original_type_expr;_})->Micheline.strip_locationsoriginal_type_expr)inletscript_view_typectxtcontractexprview=letctxt=Gas.set_unlimitedctxtinletlegacy=falseinletopenScript_ir_translatorinparse_toplevelctxt~legacyexpr>>=?fun({views;_},_)->Lwt.return(Script_string.of_stringview>>?funview_name->matchScript_map.getview_nameviewswith|None->error(View_helpers.View_not_found(contract,view))|SomeScript_typed_ir.{input_ty;output_ty;_}->ok(input_ty,output_ty))inRegistration.register0~chunked:trueS.run_code(functxt()((code,storage,parameter,amount,balance,chain_id,src_opt,pay_opt,self_opt,entrypoint),(unparsing_mode,gas,now,level))->letunparsing_mode=Option.value~default:Readableunparsing_modeinletstorage=Script.lazy_exprstorageinletcode=Script.lazy_exprcodeinconfigure_contractsctxt{storage;code}balance~src_opt~pay_opt~self_opt>>=?fun(ctxt,{self;source;payer;balance})->letgas=matchgaswith|Somegas->gas|None->Constants.hard_gas_limit_per_operationctxtinletctxt=Gas.set_limitctxtgasinletnow=matchnowwithNone->Script_timestamp.nowctxt|Somet->tinletlevel=matchlevelwith|None->(Level.currentctxt).level|>Raw_level.to_int32|>Script_int.of_int32|>Script_int.abs|Somez->zinletstep_constants=letopenScript_interpreterin{source;payer;self;amount;balance;chain_id;now;level}inScript_interpreter.executectxtunparsing_modestep_constants~cached_script:None~script:{storage;code}~entrypoint~parameter~internal:true>|=?fun({script=_;code_size=_;Script_interpreter.storage;operations;lazy_storage_diff;ticket_diffs=_;},_)->(storage,Apply_results.contents_of_packed_internal_operationsoperations,lazy_storage_diff));Registration.register0~chunked:trueS.trace_code(functxt()((code,storage,parameter,amount,balance,chain_id,src_opt,pay_opt,self_opt,entrypoint),(unparsing_mode,gas,now,level))->letunparsing_mode=Option.value~default:Readableunparsing_modeinletstorage=Script.lazy_exprstorageinletcode=Script.lazy_exprcodeinconfigure_contractsctxt{storage;code}balance~src_opt~pay_opt~self_opt>>=?fun(ctxt,{self;source;payer;balance})->letgas=matchgaswith|Somegas->gas|None->Constants.hard_gas_limit_per_operationctxtinletctxt=Gas.set_limitctxtgasinletnow=matchnowwithNone->Script_timestamp.nowctxt|Somet->tinletlevel=matchlevelwith|None->(Level.currentctxt).level|>Raw_level.to_int32|>Script_int.of_int32|>Script_int.abs|Somez->zinletstep_constants=letopenScript_interpreterin{source;payer;self;amount;balance;chain_id;now;level}inletmoduleUnparsing_mode=structletunparsing_mode=unparsing_modeendinletmoduleInterp=Traced_interpreter(Unparsing_mode)inInterp.executectxtstep_constants~script:{storage;code}~entrypoint~parameter>|=?fun(({script=_;code_size=_;Script_interpreter.storage;operations;lazy_storage_diff;ticket_diffs=_;},_ctxt),trace)->(storage,Apply_results.contents_of_packed_internal_operationsoperations,trace,lazy_storage_diff));Registration.register0~chunked:trueS.run_tzip4_view(functxt()(contract,entrypoint,input,chain_id,source,payer,gas,unparsing_mode,now,level)->Contract.get_scriptctxtcontract>>=?fun(ctxt,script_opt)->Option.fold~some:ok~none:(errorView_helpers.Viewed_contract_has_no_script)script_opt>>?=funscript->Script_repr.(force_decodescript.code)>>?=fundecoded_script->script_entrypoint_typectxtdecoded_scriptentrypoint>>=?funview_ty->View_helpers.extract_view_output_typeentrypointview_ty>>?=funty->Contract.get_balancectxtcontract>>=?funbalance->Error_monad.traceView_helpers.View_callback_origination_failed@@originate_dummy_contractctxt(View_helpers.make_tzip4_viewer_scriptty)Tez.zero>>=?fun(ctxt,viewer_contract)->letsource,payer=match(source,payer)with|Somesource,Somepayer->(source,payer)|Somesource,None->(source,source)|None,Somepayer->(payer,payer)|None,None->(contract,contract)inletgas=Option.value~default:(Constants.hard_gas_limit_per_operationctxt)gasinletctxt=Gas.set_limitctxtgasinletnow=matchnowwithNone->Script_timestamp.nowctxt|Somet->tinletlevel=matchlevelwith|None->(Level.currentctxt).level|>Raw_level.to_int32|>Script_int.of_int32|>Script_int.abs|Somez->zinletstep_constants=letopenScript_interpreterin{source;payer;self=contract;amount=Tez.zero;balance;chain_id;now;level;}inletparameter=View_helpers.make_view_parameter(Micheline.rootinput)viewer_contractinScript_interpreter.executectxtunparsing_modestep_constants~script~cached_script:None~entrypoint~parameter~internal:true>>=?fun({Script_interpreter.operations;script=_;code_size=_;storage=_;lazy_storage_diff=_;ticket_diffs=_;},_ctxt)->View_helpers.extract_parameter_from_operationsentrypointoperationsviewer_contract>>?=funparameter->Lwt.return(Script_repr.force_decodeparameter));Registration.register0~chunked:trueS.run_script_view(functxt()((contract,view,input,unlimited_gas,chain_id,source,payer,gas,unparsing_mode,now),level)->Contract.get_scriptctxtcontract>>=?fun(ctxt,script_opt)->Option.fold~some:ok~none:(Error_monad.errorView_helpers.Viewed_contract_has_no_script)script_opt>>?=funscript->Script_repr.(force_decodescript.code)>>?=fundecoded_script->script_view_typectxtcontractdecoded_scriptview>>=?fun(input_ty,output_ty)->Contract.get_balancectxtcontract>>=?funbalance->letsource,payer=match(source,payer)with|Somesource,Somepayer->(source,payer)|Somesource,None->(source,source)|None,Somepayer->(payer,payer)|None,None->(contract,contract)inletnow=matchnowwithNone->Script_timestamp.nowctxt|Somet->tin(* Using [Gas.set_unlimited] won't work, since the interpreter doesn't
use this mode (see !4034#note_774734253) and still consumes gas.
Our best shot to emulate this is to use the maximum amount of
milligas possible which is represented by [2^62 - 1] according to
[Saturation_repr.saturated], which is [max_int]. *)letmax_gas=Gas.fp_of_milligas_intmax_intinletgas=Option.value~default:(Constants.hard_gas_limit_per_operationctxt)gasinletctxt=ifunlimited_gasthenGas.set_limitctxtmax_gaselseGas.set_limitctxtgasinletlevel=Option.valuelevel~default:((Level.currentctxt).level|>Raw_level.to_int32|>Script_int.of_int32|>Script_int.abs)inletstep_constants={Script_interpreter.source;payer;self=contract;amount=Tez.zero;balance;chain_id;now;level;}inletviewer_script=View_helpers.make_michelson_viewer_scriptcontractviewinputinput_tyoutput_tyinletparameter=Micheline.(strip_locations(Prim(0,Script.D_Unit,[],[])))inScript_interpreter.executectxtunparsing_modestep_constants~script:viewer_script~cached_script:None~entrypoint:Entrypoint.default~parameter~internal:true>>=?fun({Script_interpreter.operations=_;script=_;code_size=_;storage;lazy_storage_diff=_;ticket_diffs=_;},_ctxt)->View_helpers.extract_value_from_storagestorage>>?=funvalue->return(Micheline.strip_locationsvalue));Registration.register0~chunked:falseS.typecheck_code(functxt()(expr,maybe_gas,legacy,show_types)->letlegacy=Option.value~default:falselegacyinletshow_types=Option.value~default:trueshow_typesinletctxt=matchmaybe_gaswith|None->Gas.set_unlimitedctxt|Somegas->Gas.set_limitctxtgasinScript_ir_translator.typecheck_code~legacy~show_typesctxtexpr>|=?fun(res,ctxt)->(res,Gas.levelctxt));Registration.register0~chunked:falseS.script_size(functxt()(expr,storage,maybe_gas,legacy)->letlegacy=Option.value~default:falselegacyinletctxt=matchmaybe_gaswith|None->Gas.set_unlimitedctxt|Somegas->Gas.set_limitctxtgasinletcode=Script.lazy_exprexprinScript_ir_translator.parse_code~legacyctxt~code>>=?fun(Ex_code(Code{code;arg_type;storage_type;views;entrypoints;code_size;}),ctxt)->Script_ir_translator.parse_data~legacy~allow_forged:truectxtstorage_type(Micheline.rootstorage)>>=?fun(storage,_)->letscript=Script_ir_translator.Ex_script(Script{code;arg_type;storage_type;views;entrypoints;code_size;storage;})inletsize,cost=Script_ir_translator.script_sizescriptinGas.consumectxtcost>>?=fun_ctxt->return@@size);Registration.register0~chunked:falseS.typecheck_data(functxt()(data,ty,maybe_gas,legacy)->letlegacy=Option.value~default:falselegacyinletctxt=matchmaybe_gaswith|None->Gas.set_unlimitedctxt|Somegas->Gas.set_limitctxtgasintypecheck_data~legacyctxt(data,ty)>|=?functxt->Gas.levelctxt);Registration.register0~chunked:trueS.pack_data(functxt()(expr,typ,maybe_gas)->letopenScript_ir_translatorinletctxt=matchmaybe_gaswith|None->Gas.set_unlimitedctxt|Somegas->Gas.set_limitctxtgasinparse_packable_tyctxt~legacy:true(Micheline.roottyp)>>?=fun(Ex_tytyp,ctxt)->parse_datactxt~legacy:true~allow_forged:truetyp(Micheline.rootexpr)>>=?fun(data,ctxt)->Script_ir_translator.pack_datactxttypdata>|=?fun(bytes,ctxt)->(bytes,Gas.levelctxt));Registration.register0~chunked:trueS.normalize_data(functxt()(expr,typ,unparsing_mode,legacy)->letopenScript_ir_translatorinletlegacy=Option.value~default:falselegacyinletctxt=Gas.set_unlimitedctxtinScript_ir_translator.parse_any_tyctxt~legacy(Micheline.roottyp)>>?=fun(Ex_tytyp,ctxt)->parse_datactxt~legacy~allow_forged:truetyp(Micheline.rootexpr)>>=?fun(data,ctxt)->Script_ir_translator.unparse_datactxtunparsing_modetypdata>|=?fun(normalized,_ctxt)->Micheline.strip_locationsnormalized);Registration.register0~chunked:trueS.normalize_script(functxt()(script,unparsing_mode)->letctxt=Gas.set_unlimitedctxtinScript_ir_translator.unparse_codectxtunparsing_mode(Micheline.rootscript)>|=?fun(normalized,_ctxt)->Micheline.strip_locationsnormalized);Registration.register0~chunked:trueS.normalize_type(functxt()typ->letopenScript_ir_translatorinletctxt=Gas.set_unlimitedctxtin(* Unfortunately, Script_ir_translator.parse_any_ty is not exported *)Script_ir_translator.parse_tyctxt~legacy:true~allow_lazy_storage:true~allow_operation:true~allow_contract:true~allow_ticket:true(Micheline.roottyp)>>?=fun(Ex_tytyp,_ctxt)->letnormalized=Unparse_types.unparse_ty~loc:()typinreturn@@Micheline.strip_locationsnormalized);Registration.register0~chunked:trueS.run_operationrun_operation_service;Registration.register0_successor_level~chunked:trueS.simulate_operationsimulate_operation_service;Registration.register0~chunked:trueS.entrypoint_type(functxt()(expr,entrypoint)->script_entrypoint_typectxtexprentrypoint);Registration.register0~chunked:trueS.list_entrypoints(functxt()expr->letctxt=Gas.set_unlimitedctxtinletlegacy=falseinletopenScript_ir_translatorinparse_toplevel~legacyctxtexpr>>=?fun({arg_type;_},ctxt)->Lwt.return(parse_parameter_ty_and_entrypointsctxt~legacyarg_type>|?fun(Ex_parameter_ty_and_entrypoints{arg_type;entrypoints},_)->letunreachable_entrypoint,map=Script_ir_translator.list_entrypoints_uncarbonatedarg_typeentrypointsin(unreachable_entrypoint,Entrypoint.Map.fold(funentry(_ex_ty,original_type_expr)acc->(Entrypoint.to_stringentry,Micheline.strip_locationsoriginal_type_expr)::acc)map[])))letrun_code?unparsing_mode?gas?(entrypoint=Entrypoint.default)?balance~script~storage~input~amount~chain_id~source~payer~self~now~levelctxtblock=RPC_context.make_call0S.run_codectxtblock()((script,storage,input,amount,balance,chain_id,source,payer,self,entrypoint),(unparsing_mode,gas,now,level))lettrace_code?unparsing_mode?gas?(entrypoint=Entrypoint.default)?balance~script~storage~input~amount~chain_id~source~payer~self~now~levelctxtblock=RPC_context.make_call0S.trace_codectxtblock()((script,storage,input,amount,balance,chain_id,source,payer,self,entrypoint),(unparsing_mode,gas,now,level))letrun_tzip4_view?gas~contract~entrypoint~input~chain_id~now~level?source?payer~unparsing_modectxtblock=RPC_context.make_call0S.run_tzip4_viewctxtblock()(contract,entrypoint,input,chain_id,source,payer,gas,unparsing_mode,now,level)(** [run_script_view] is an helper function to call the corresponding
RPC. [unlimited_gas] is set to [false] by default. *)letrun_script_view?gas~contract~view~input?(unlimited_gas=false)~chain_id~now~level?source?payer~unparsing_modectxtblock=RPC_context.make_call0S.run_script_viewctxtblock()((contract,view,input,unlimited_gas,chain_id,source,payer,gas,unparsing_mode,now),level)lettypecheck_code?gas?legacy~script?show_typesctxtblock=RPC_context.make_call0S.typecheck_codectxtblock()(script,gas,legacy,show_types)letscript_size?gas?legacy~script~storagectxtblock=RPC_context.make_call0S.script_sizectxtblock()(script,storage,gas,legacy)lettypecheck_data?gas?legacy~data~tyctxtblock=RPC_context.make_call0S.typecheck_datactxtblock()(data,ty,gas,legacy)letpack_data?gas~data~tyctxtblock=RPC_context.make_call0S.pack_datactxtblock()(data,ty,gas)letnormalize_data?legacy~data~ty~unparsing_modectxtblock=RPC_context.make_call0S.normalize_datactxtblock()(data,ty,unparsing_mode,legacy)letnormalize_script~script~unparsing_modectxtblock=RPC_context.make_call0S.normalize_scriptctxtblock()(script,unparsing_mode)letnormalize_type~tyctxtblock=RPC_context.make_call0S.normalize_typectxtblock()tyletrun_operation~op~chain_idctxtblock=RPC_context.make_call0S.run_operationctxtblock()(op,chain_id)letsimulate_operation~op~chain_id~latency?(successor_level=false)?blocks_before_activationctxtblock=RPC_context.make_call0S.simulate_operationctxtblock(objectmethodsuccessor_level=successor_levelend)(blocks_before_activation,op,chain_id,latency)letentrypoint_type~script~entrypointctxtblock=RPC_context.make_call0S.entrypoint_typectxtblock()(script,entrypoint)letlist_entrypointsctxtblock~script=RPC_context.make_call0S.list_entrypointsctxtblock()scriptendmoduleContract=structmoduleS=structletpath=(RPC_path.(open_root/"context"/"contracts"):RPC_context.tTezos_rpc.Path.context)letget_storage_normalized=letopenData_encodinginRPC_service.post_service~description:"Access the data of the contract and normalize it using the \
requested unparsing mode."~input:(obj1(req"unparsing_mode"unparsing_mode_encoding))~query:RPC_query.empty~output:(optionScript.expr_encoding)RPC_path.(path/:Contract.rpc_arg/"storage"/"normalized")letget_script_normalized=letopenData_encodinginRPC_service.post_service~description:"Access the script of the contract and normalize it using the \
requested unparsing mode."~input:(obj2(req"unparsing_mode"unparsing_mode_encoding)(dft"normalize_types"boolfalse))~query:RPC_query.empty~output:(optionScript.encoding)RPC_path.(path/:Contract.rpc_arg/"script"/"normalized")endletregister()=(* Patched RPC: get_storage *)Registration.register1~chunked:trueS.get_storage_normalized(functxtcontract()unparsing_mode->Contract.get_scriptctxtcontract>>=?fun(ctxt,script)->matchscriptwith|None->return_none|Somescript->letctxt=Gas.set_unlimitedctxtinletopenScript_ir_translatorinparse_scriptctxt~legacy:true~allow_forged_in_storage:truescript>>=?fun(Ex_script(Script{storage;storage_type;_}),ctxt)->unparse_datactxtunparsing_modestorage_typestorage>|=?fun(storage,_ctxt)->Some(Micheline.strip_locationsstorage));(* Patched RPC: get_script *)Registration.register1~chunked:trueS.get_script_normalized(functxtcontract()(unparsing_mode,normalize_types)->Contract.get_scriptctxtcontract>>=?fun(ctxt,script)->matchscriptwith|None->return_none|Somescript->letctxt=Gas.set_unlimitedctxtinScript_ir_translator.parse_and_unparse_script_unaccountedctxt~legacy:true~allow_forged_in_storage:trueunparsing_mode~normalize_typesscript>>=?fun(script,_ctxt)->return_somescript)letget_storage_normalizedctxtblock~contract~unparsing_mode=RPC_context.make_call1S.get_storage_normalizedctxtblockcontract()unparsing_modeletget_script_normalizedctxtblock~contract~unparsing_mode~normalize_types=RPC_context.make_call1S.get_script_normalizedctxtblockcontract()(unparsing_mode,normalize_types)endmoduleBig_map=structmoduleS=structletpath=(RPC_path.(open_root/"context"/"big_maps"):RPC_context.tRPC_path.context)letbig_map_get_normalized=letopenData_encodinginRPC_service.post_service~description:"Access the value associated with a key in a big map, normalize \
the output using the requested unparsing mode."~query:RPC_query.empty~input:(obj1(req"unparsing_mode"unparsing_mode_encoding))~output:Script.expr_encodingRPC_path.(path/:Big_map.Id.rpc_arg/:Script_expr_hash.rpc_arg/"normalized")endletregister()=Registration.register2~chunked:trueS.big_map_get_normalized(functxtidkey()unparsing_mode->letopenScript_ir_translatorinletctxt=Gas.set_unlimitedctxtinBig_map.existsctxtid>>=?fun(ctxt,types)->matchtypeswith|None->raiseNot_found|Some(_,value_type)->(parse_big_map_value_tyctxt~legacy:true(Micheline.rootvalue_type)>>?=fun(Ex_tyvalue_type,ctxt)->Big_map.get_optctxtidkey>>=?fun(_ctxt,value)->matchvaluewith|None->raiseNot_found|Somevalue->parse_datactxt~legacy:true~allow_forged:truevalue_type(Micheline.rootvalue)>>=?fun(value,ctxt)->unparse_datactxtunparsing_modevalue_typevalue>|=?fun(value,_ctxt)->Micheline.strip_locationsvalue))letbig_map_get_normalizedctxtblockidkey~unparsing_mode=RPC_context.make_call2S.big_map_get_normalizedctxtblockidkey()unparsing_modeendmoduleSc_rollup=structopenData_encodingmoduleS=structletpath:RPC_context.tRPC_path.context=RPC_path.(open_root/"context"/"sc_rollup")letkind=RPC_service.get_service~description:"Kind of smart-contract rollup"~query:RPC_query.empty~output:(obj1(opt"kind"Sc_rollup.Kind.encoding))RPC_path.(path/:Sc_rollup.Address.rpc_arg/"kind")letinbox=RPC_service.get_service~description:"Inbox for a smart-contract rollup"~query:RPC_query.empty~output:Sc_rollup.Inbox.encodingRPC_path.(path/:Sc_rollup.Address.rpc_arg/"inbox")letinitial_level=RPC_service.get_service~description:"Initial level for a smart-contract rollup"~query:RPC_query.empty~output:Raw_level_repr.encodingRPC_path.(path/:Sc_rollup.Address.rpc_arg/"initial_level")letroot=RPC_service.get_service~description:"List of all originated smart contract rollups"~query:RPC_query.empty~output:(Data_encoding.listSc_rollup.Address.encoding)pathendletkindctxtblocksc_rollup_address=RPC_context.make_call1S.kindctxtblocksc_rollup_address()letregister_inbox()=Registration.register1~chunked:trueS.inbox(functxtrollup()()->Stdlib.Format.eprintf"@[Context level at RPC time at %a@]@."Level.pp(Level.currentctxt);Sc_rollup.inboxctxtrollup>>=?fun(inbox,_ctxt)->returninbox)letregister_kind()=Registration.register1~chunked:trueS.kind@@functxtaddress()()->Alpha_context.Sc_rollup.kindctxtaddress(* TODO: https://gitlab.com/tezos/tezos/-/issues/2688 *)letregister_initial_level()=Registration.register1~chunked:trueS.initial_level@@functxtaddress()()->Alpha_context.Sc_rollup.initial_levelctxtaddressletregister_root()=Registration.register0~chunked:trueS.root(funcontext()()->Sc_rollup.listcontext)letregister()=register_kind();register_inbox();register_initial_level();register_root()letlistctxtblock=RPC_context.make_call0S.rootctxtblock()()letinitial_levelctxtblocksc_rollup_address=RPC_context.make_call1S.initial_levelctxtblocksc_rollup_address()endmoduleTx_rollup=structopenData_encodingmoduleS=structletpath:RPC_context.tRPC_path.context=RPC_path.(open_root/"context"/"tx_rollup")lethas_bond=RPC_service.get_service~description:"Returns true if the public key hash already deposited a bond for \
the given rollup"~query:RPC_query.empty~output:boolRPC_path.(path/:Tx_rollup.rpc_arg/"has_bond"/:Signature.Public_key_hash.rpc_arg)endletregister_has_bond()=Registration.register2~chunked:falseS.has_bond(functxtrollupoperator()()->Tx_rollup_commitment.has_bondctxtrollupoperator>>=?fun(_ctxt,has_bond)->returnhas_bond)letregister()=register_has_bond()lethas_bondctxtblockrollupoperator=RPC_context.make_call2S.has_bondctxtblockrollupoperator()()endmoduleForge=structmoduleS=structopenData_encodingletpath=Tezos_rpc.Path.(path/"forge")letoperations=Tezos_rpc.Service.post_service~description:"Forge an operation"~query:Tezos_rpc.Query.empty~input:Operation.unsigned_encoding~output:bytesTezos_rpc.Path.(path/"operations")letempty_proof_of_work_nonce=Bytes.makeConstants_repr.proof_of_work_nonce_size'\000'letprotocol_data=Tezos_rpc.Service.post_service~description:"Forge the protocol-specific part of a block header"~query:Tezos_rpc.Query.empty~input:(obj5(req"payload_hash"Block_payload_hash.encoding)(req"payload_round"Round.encoding)(opt"nonce_hash"Nonce_hash.encoding)(dft"proof_of_work_nonce"(Fixed.bytesAlpha_context.Constants.proof_of_work_nonce_size)empty_proof_of_work_nonce)Liquidity_baking.(dft"liquidity_baking_toggle_vote"liquidity_baking_toggle_vote_encodingLB_pass))~output:(obj1(req"protocol_data"bytes))Tezos_rpc.Path.(path/"protocol_data")moduleTx_rollup=structopenData_encodingletpath=Tezos_rpc.Path.(path/"tx_rollup")moduleInbox=structletpath=Tezos_rpc.Path.(path/"inbox")letmessage_hash=Tezos_rpc.Service.post_service~description:"Compute the hash of a message"~query:Tezos_rpc.Query.empty~input:(obj1(req"message"Tx_rollup_message.encoding))~output:(obj1(req"hash"Tx_rollup_message_hash.encoding))Tezos_rpc.Path.(path/"message_hash")letmerkle_tree_hash=Tezos_rpc.Service.post_service~description:"Compute the merkle tree hash of an inbox"~query:Tezos_rpc.Query.empty~input:(obj1(req"message_hashes"(listTx_rollup_message_hash.encoding)))~output:(obj1(req"hash"Tx_rollup_inbox.Merkle.root_encoding))Tezos_rpc.Path.(path/"merkle_tree_hash")letmerkle_tree_path=Tezos_rpc.Service.post_service~description:"Compute a path of an inbox message in a merkle tree"~query:Tezos_rpc.Query.empty~input:(obj2(req"message_hashes"(listTx_rollup_message_hash.encoding))(req"position"int16))~output:(obj1(req"path"Tx_rollup_inbox.Merkle.path_encoding))Tezos_rpc.Path.(path/"merkle_tree_path")endmoduleCommitment=structletpath=Tezos_rpc.Path.(path/"commitment")letmerkle_tree_hash=Tezos_rpc.Service.post_service~description:"Compute the merkle tree hash of a commitment"~query:Tezos_rpc.Query.empty~input:(obj1(req"message_result_hashes"(listTx_rollup_message_result_hash.encoding)))~output:(obj1(req"hash"Tx_rollup_commitment.Merkle_hash.encoding))Tezos_rpc.Path.(path/"merkle_tree_hash")letmerkle_tree_path=Tezos_rpc.Service.post_service~description:"Compute a path of a message result hash in the commitment \
merkle tree"~query:Tezos_rpc.Query.empty~input:(obj2(req"message_result_hashes"(listTx_rollup_message_result_hash.encoding))(req"position"int16))~output:(obj1(req"path"Tx_rollup_commitment.Merkle.path_encoding))Tezos_rpc.Path.(path/"merkle_tree_path")letmessage_result_hash=Tezos_rpc.Service.post_service~description:"Compute the message result hash"~query:Tezos_rpc.Query.empty~input:Tx_rollup_message_result.encoding~output:(obj1(req"hash"Tx_rollup_message_result_hash.encoding))Tezos_rpc.Path.(path/"message_result_hash")endmoduleWithdraw=structletpath=Tezos_rpc.Path.(path/"withdraw")letwithdraw_list_hash=Tezos_rpc.Service.post_service~description:"Compute the hash of a withdraw list"~query:Tezos_rpc.Query.empty~input:(obj1(req"withdraw_list"(listTx_rollup_withdraw.encoding)))~output:(obj1(req"hash"Tx_rollup_withdraw_list_hash.encoding))Tezos_rpc.Path.(path/"withdraw_list_hash")endendendletregister()=Registration.register0_noctxt~chunked:trueS.operations(fun()(shell,proto)->return(Data_encoding.Binary.to_bytes_exnOperation.unsigned_encoding(shell,proto)));Registration.register0_noctxt~chunked:trueS.protocol_data(fun()(payload_hash,payload_round,seed_nonce_hash,proof_of_work_nonce,liquidity_baking_toggle_vote)->return(Data_encoding.Binary.to_bytes_exnBlock_header.contents_encoding{payload_hash;payload_round;seed_nonce_hash;proof_of_work_nonce;liquidity_baking_toggle_vote;}));Registration.register0_noctxt~chunked:trueS.Tx_rollup.Inbox.message_hash(fun()message->return(Tx_rollup_message_hash.hash_uncarbonatedmessage));Registration.register0_noctxt~chunked:trueS.Tx_rollup.Inbox.merkle_tree_hash(fun()message_hashes->return(Tx_rollup_inbox.Merkle.merklize_listmessage_hashes));Registration.register0_noctxt~chunked:trueS.Tx_rollup.Inbox.merkle_tree_path(fun()(message_hashes,position)->Lwt.return(Tx_rollup_inbox.Merkle.compute_pathmessage_hashesposition));Registration.register0_noctxt~chunked:trueS.Tx_rollup.Commitment.merkle_tree_hash(fun()message_result_hashes->letopenTx_rollup_commitment.Merkleinlettree=List.fold_leftsnocnilmessage_result_hashesinreturn(roottree));Registration.register0_noctxt~chunked:trueS.Tx_rollup.Commitment.merkle_tree_path(fun()(message_result_hashes,position)->letopenTx_rollup_commitment.Merkleinlettree=List.fold_leftsnocnilmessage_result_hashesinLwt.return(compute_pathtreeposition));Registration.register0_noctxt~chunked:trueS.Tx_rollup.Commitment.message_result_hash(fun()message_result->return(Tx_rollup_message_result_hash.hash_uncarbonatedmessage_result));Registration.register0_noctxt~chunked:trueS.Tx_rollup.Withdraw.withdraw_list_hash(fun()withdrawals->return(Tx_rollup_withdraw_list_hash.hash_uncarbonatedwithdrawals))moduleManager=structletoperationsctxtblock~branch~source?sourcePubKey~counter~fee~gas_limit~storage_limitoperations=Contract_services.manager_keyctxtblocksource>>=function|Error_ase->Lwt.returne|Okrevealed->letops=List.map(fun(Manageroperation)->Contents(Manager_operation{source;counter;operation;fee;gas_limit;storage_limit;}))operationsinletops=match(sourcePubKey,revealed)with|None,_|_,Some_->ops|Somepk,None->letoperation=RevealpkinContents(Manager_operation{source;counter;operation;fee;gas_limit;storage_limit;})::opsinEnvironment.wrap_tzresult@@Operation.of_listops>>?=funops->RPC_context.make_call0S.operationsctxtblock()({branch},ops)letrevealctxtblock~branch~source~sourcePubKey~counter~fee()=operationsctxtblock~branch~source~sourcePubKey~counter~fee~gas_limit:Gas.Arith.zero~storage_limit:Z.zero[]lettransactionctxtblock~branch~source?sourcePubKey~counter~amount~destination?(entrypoint=Entrypoint.default)?parameters~gas_limit~storage_limit~fee()=letparameters=Option.fold~some:Script.lazy_expr~none:Script.unit_parameterparametersinoperationsctxtblock~branch~source?sourcePubKey~counter~fee~gas_limit~storage_limit[Manager(Transaction{amount;parameters;destination;entrypoint})]letoriginationctxtblock~branch~source?sourcePubKey~counter~balance?delegatePubKey~script~gas_limit~storage_limit~fee()=operationsctxtblock~branch~source?sourcePubKey~counter~fee~gas_limit~storage_limit[Manager(Origination{delegate=delegatePubKey;script;credit=balance});]letdelegationctxtblock~branch~source?sourcePubKey~counter~feedelegate=operationsctxtblock~branch~source?sourcePubKey~counter~fee~gas_limit:Gas.Arith.zero~storage_limit:Z.zero[Manager(Delegationdelegate)]endletoperationctxtblock~branchoperation=RPC_context.make_call0S.operationsctxtblock()({branch},Contents_list(Singleoperation))letendorsementctxtb~branch~consensus_content()=operationctxtb~branch(Endorsementconsensus_content)letproposalsctxtb~branch~source~period~proposals()=operationctxtb~branch(Proposals{source;period;proposals})letballotctxtb~branch~source~period~proposal~ballot()=operationctxtb~branch(Ballot{source;period;proposal;ballot})letfailing_noopctxtb~branch~message()=operationctxtb~branch(Failing_noopmessage)letseed_nonce_revelationctxtblock~branch~level~nonce()=operationctxtblock~branch(Seed_nonce_revelation{level;nonce})letdouble_baking_evidencectxtblock~branch~bh1~bh2()=operationctxtblock~branch(Double_baking_evidence{bh1;bh2})letdouble_endorsement_evidencectxtblock~branch~op1~op2()=operationctxtblock~branch(Double_endorsement_evidence{op1;op2})letdouble_preendorsement_evidencectxtblock~branch~op1~op2()=operationctxtblock~branch(Double_preendorsement_evidence{op1;op2})letempty_proof_of_work_nonce=Bytes.makeConstants_repr.proof_of_work_nonce_size'\000'letprotocol_datactxtblock?(payload_hash=Block_payload_hash.zero)?(payload_round=Round.zero)?seed_nonce_hash?(proof_of_work_nonce=empty_proof_of_work_nonce)~liquidity_baking_toggle_vote()=RPC_context.make_call0S.protocol_datactxtblock()(payload_hash,payload_round,seed_nonce_hash,proof_of_work_nonce,liquidity_baking_toggle_vote)endmoduleParse=structmoduleS=structopenData_encodingletpath=Tezos_rpc.Path.(path/"parse")letoperations=Tezos_rpc.Service.post_service~description:"Parse operations"~query:Tezos_rpc.Query.empty~input:(obj2(req"operations"(list(dynamic_sizeOperation.raw_encoding)))(opt"check_signature"bool))~output:(list(dynamic_sizeOperation.encoding))Tezos_rpc.Path.(path/"operations")letblock=Tezos_rpc.Service.post_service~description:"Parse a block"~query:Tezos_rpc.Query.empty~input:Block_header.raw_encoding~output:Block_header.protocol_data_encodingTezos_rpc.Path.(path/"block")endletparse_protocol_dataprotocol_data=matchData_encoding.Binary.of_bytes_optBlock_header.protocol_data_encodingprotocol_datawith|None->Stdlib.failwith"Cant_parse_protocol_data"|Someprotocol_data->protocol_dataletregister()=Registration.register0~chunked:trueS.operations(fun_ctxt()(operations,check)->List.map_es(funraw->parse_operationraw>>?=funop->(matchcheckwith|Sometrue->return_unit(* FIXME *)(* I.check_signature ctxt *)(* op.protocol_data.signature op.shell op.protocol_data.contents *)|Somefalse|None->return_unit)>|=?fun()->op)operations);Registration.register0_noctxt~chunked:falseS.block(fun()raw_block->return@@parse_protocol_dataraw_block.protocol_data)letoperationsctxtblock?checkoperations=RPC_context.make_call0S.operationsctxtblock()(operations,check)letblockctxtblockshellprotocol_data=RPC_context.make_call0S.blockctxtblock()({shell;protocol_data}:Block_header.raw)end(* Compute the estimated starting time of a [round] at a future
[level], given the head's level [current_level], timestamp
[current_timestamp], and round [current_round]. Assumes blocks at
intermediate levels are produced at round 0. *)letestimated_timeround_durations~current_level~current_round~current_timestamp~level~round=ifLevel.(level<=current_level)thenResult.return_noneelseRound.of_intround>>?funround->Round.timestamp_of_roundround_durations~round~predecessor_timestamp:current_timestamp~predecessor_round:current_round>>?funround_start_at_next_level->letstep=Round.round_durationround_durationsRound.zeroinletdiff=Level.difflevelcurrent_levelinPeriod.mult(Int32.preddiff)step>>?fundelay->Timestamp.(round_start_at_next_level+?delay)>>?funtimestamp->Result.return_sometimestampletrequested_levels~default_levelctxtcycleslevels=match(levels,cycles)with|[],[]->[default_level]|levels,cycles->(* explicitly fail when requested levels or cycle are in the past...
or too far in the future...
TODO: https://gitlab.com/tezos/tezos/-/issues/2335
this old comment (from version Alpha) conflicts with
the specification of the RPCs that use this code.
*)List.sort_uniqLevel.compare(List.rev_append(List.rev_map(Level.from_rawctxt)levels)(List.concat_map(Level.levels_in_cyclectxt)cycles))moduleBaking_rights=structtypet={level:Raw_level.t;delegate:Tezos_crypto.Signature.V0.Public_key_hash.t;round:int;timestamp:Timestamp.toption;}letencoding=letopenData_encodinginconv(fun{level;delegate;round;timestamp}->(level,delegate,round,timestamp))(fun(level,delegate,round,timestamp)->{level;delegate;round;timestamp})(obj4(req"level"Raw_level.encoding)(req"delegate"Tezos_crypto.Signature.V0.Public_key_hash.encoding)(req"round"uint16)(opt"estimated_time"Timestamp.encoding))letdefault_max_round=64moduleS=structopenData_encodingletpath=RPC_path.(open_root/"helpers"/"baking_rights")typebaking_rights_query={levels:Raw_level.tlist;cycle:Cycle.toption;delegates:Tezos_crypto.Signature.V0.Public_key_hash.tlist;max_round:intoption;all:bool;}letbaking_rights_query=letopenRPC_queryinquery(funlevelscycledelegatesmax_roundall->{levels;cycle;delegates;max_round;all})|+multi_field"level"Raw_level.rpc_arg(funt->t.levels)|+opt_field"cycle"Cycle.rpc_arg(funt->t.cycle)|+multi_field"delegate"Signature.Public_key_hash.rpc_arg(funt->t.delegates)|+opt_field"max_round"RPC_arg.uint(funt->t.max_round)|+flag"all"(funt->t.all)|>sealletbaking_rights=RPC_service.get_service~description:(Format.sprintf"Retrieves the list of delegates allowed to bake a block.\n\
By default, it gives the best baking opportunities (in terms \
of rounds) for bakers that have at least one opportunity below \
the %dth round for the next block.\n\
Parameters `level` and `cycle` can be used to specify the \
(valid) level(s) in the past or future at which the baking \
rights have to be returned.\n\
Parameter `delegate` can be used to restrict the results to \
the given delegates. If parameter `all` is set, all the baking \
opportunities for each baker at each level are returned, \
instead of just the first one.\n\
Returns the list of baking opportunities up to round %d. Also \
returns the minimal timestamps that correspond to these \
opportunities. The timestamps are omitted for levels in the \
past, and are only estimates for levels higher that the next \
block's, based on the hypothesis that all predecessor blocks \
were baked at the first round."default_max_rounddefault_max_round)~query:baking_rights_query~output:(listencoding)pathendletbaking_rights_at_levelctxtmax_roundlevel=Baking.baking_rightsctxtlevel>>=?fundelegates->Round.getctxt>>=?funcurrent_round->letcurrent_level=Level.currentctxtinletcurrent_timestamp=Timestamp.currentctxtinletround_durations=Alpha_context.Constants.round_durationsctxtinletreclooplaccround=ifCompare.Int.(round>max_round)thenreturn(List.revacc)elselet(Misc.LCons(pk,next))=linletdelegate=Tezos_crypto.Signature.V0.Public_key.hashpkinestimated_timeround_durations~current_level~current_round~current_timestamp~level~round>>?=funtimestamp->letacc={level=level.level;delegate;round;timestamp}::accinnext()>>=?funl->looplacc(round+1)inloopdelegates[]0letremove_duplicated_delegatesrights=List.rev@@fst@@List.fold_left(fun(acc,previous)r->ifTezos_crypto.Signature.V0.Public_key_hash.Set.exists(Tezos_crypto.Signature.V0.Public_key_hash.equalr.delegate)previousthen(acc,previous)else(r::acc,Tezos_crypto.Signature.V0.Public_key_hash.Set.addr.delegateprevious))([],Tezos_crypto.Signature.V0.Public_key_hash.Set.empty)rightsletregister()=Registration.register0~chunked:trueS.baking_rights(functxtq()->letcycles=matchq.cyclewithNone->[]|Somecycle->[cycle]inletlevels=requested_levels~default_level:(Level.succctxt(Level.currentctxt))ctxtcyclesq.levelsinletmax_round=matchq.max_roundwith|None->default_max_round|Somemax_round->Compare.Int.minmax_round(Constants.consensus_committee_sizectxt)inList.map_es(baking_rights_at_levelctxtmax_round)levels>|=?funrights->letrights=ifq.allthenList.concatrightselseList.concat_mapremove_duplicated_delegatesrightsinmatchq.delegateswith|[]->rights|_::_asdelegates->letis_requestedp=List.exists(Tezos_crypto.Signature.V0.Public_key_hash.equalp.delegate)delegatesinList.filteris_requestedrights)letgetctxt?(levels=[])?cycle?(delegates=[])?(all=false)?max_roundblock=RPC_context.make_call0S.baking_rightsctxtblock{levels;cycle;delegates;max_round;all}()endmoduleEndorsing_rights=structtypedelegate_rights={delegate:Tezos_crypto.Signature.V0.Public_key_hash.t;first_slot:Slot.t;endorsing_power:int;}typet={level:Raw_level.t;delegates_rights:delegate_rightslist;estimated_time:Time.toption;}letdelegate_rights_encoding=letopenData_encodinginconv(fun{delegate;first_slot;endorsing_power}->(delegate,first_slot,endorsing_power))(fun(delegate,first_slot,endorsing_power)->{delegate;first_slot;endorsing_power})(obj3(req"delegate"Tezos_crypto.Signature.V0.Public_key_hash.encoding)(req"first_slot"Slot.encoding)(req"endorsing_power"uint16))letencoding=letopenData_encodinginconv(fun{level;delegates_rights;estimated_time}->(level,delegates_rights,estimated_time))(fun(level,delegates_rights,estimated_time)->{level;delegates_rights;estimated_time})(obj3(req"level"Raw_level.encoding)(req"delegates"(listdelegate_rights_encoding))(opt"estimated_time"Timestamp.encoding))moduleS=structopenData_encodingletpath=RPC_path.(path/"endorsing_rights")typeendorsing_rights_query={levels:Raw_level.tlist;cycle:Cycle.toption;delegates:Tezos_crypto.Signature.V0.Public_key_hash.tlist;}letendorsing_rights_query=letopenRPC_queryinquery(funlevelscycledelegates->{levels;cycle;delegates})|+multi_field"level"Raw_level.rpc_arg(funt->t.levels)|+opt_field"cycle"Cycle.rpc_arg(funt->t.cycle)|+multi_field"delegate"Signature.Public_key_hash.rpc_arg(funt->t.delegates)|>sealletendorsing_rights=RPC_service.get_service~description:"Retrieves the delegates allowed to endorse a block.\n\
By default, it gives the endorsing power for delegates that have \
at least one endorsing slot for the next block.\n\
Parameters `level` and `cycle` can be used to specify the (valid) \
level(s) in the past or future at which the endorsing rights have \
to be returned. Parameter `delegate` can be used to restrict the \
results to the given delegates.\n\
Returns the smallest endorsing slots and the endorsing power. \
Also returns the minimal timestamp that corresponds to endorsing \
at the given level. The timestamps are omitted for levels in the \
past, and are only estimates for levels higher that the next \
block's, based on the hypothesis that all predecessor blocks were \
baked at the first round."~query:endorsing_rights_query~output:(listencoding)pathendletendorsing_rights_at_levelctxtlevel=Baking.endorsing_rights_by_first_slotctxtlevel>>=?fun(ctxt,rights)->Round.getctxt>>=?funcurrent_round->letcurrent_level=Level.currentctxtinletcurrent_timestamp=Timestamp.currentctxtinletround_durations=Alpha_context.Constants.round_durationsctxtinestimated_timeround_durations~current_level~current_round~current_timestamp~level~round:0>>?=funestimated_time->letrights=Slot.Map.fold(funfirst_slot(_pk,delegate,endorsing_power)acc->{delegate;first_slot;endorsing_power}::acc)rights[]inreturn{level=level.level;delegates_rights=rights;estimated_time}letregister()=Registration.register0~chunked:trueS.endorsing_rights(functxtq()->letcycles=matchq.cyclewithNone->[]|Somecycle->[cycle]inletlevels=requested_levels~default_level:(Level.currentctxt)ctxtcyclesq.levelsinList.map_es(endorsing_rights_at_levelctxt)levels>|=?funrights_per_level->matchq.delegateswith|[]->rights_per_level|_::_asdelegates->List.filter_map(funrights_at_level->letis_requestedp=List.exists(Tezos_crypto.Signature.V0.Public_key_hash.equalp.delegate)delegatesinmatchList.filteris_requestedrights_at_level.delegates_rightswith|[]->None|delegates_rights->Some{rights_at_levelwithdelegates_rights})rights_per_level)letgetctxt?(levels=[])?cycle?(delegates=[])block=RPC_context.make_call0S.endorsing_rightsctxtblock{levels;cycle;delegates}()endmoduleValidators=structtypet={level:Raw_level.t;delegate:Tezos_crypto.Signature.V0.Public_key_hash.t;slots:Slot.tlist;}letencoding=letopenData_encodinginconv(fun{level;delegate;slots}->(level,delegate,slots))(fun(level,delegate,slots)->{level;delegate;slots})(obj3(req"level"Raw_level.encoding)(req"delegate"Tezos_crypto.Signature.V0.Public_key_hash.encoding)(req"slots"(listSlot.encoding)))moduleS=structopenData_encodingletpath=RPC_path.(path/"validators")typevalidators_query={levels:Raw_level.tlist;delegates:Tezos_crypto.Signature.V0.Public_key_hash.tlist;}letvalidators_query=letopenRPC_queryinquery(funlevelsdelegates->{levels;delegates})|+multi_field"level"Raw_level.rpc_arg(funt->t.levels)|+multi_field"delegate"Signature.Public_key_hash.rpc_arg(funt->t.delegates)|>sealletvalidators=RPC_service.get_service~description:"Retrieves the level, the endorsement slots and the public key \
hash of each delegate allowed to endorse a block.\n\
By default, it provides this information for the next level.\n\
Parameter `level` can be used to specify the (valid) level(s) in \
the past or future at which the endorsement rights have to be \
returned. Parameter `delegate` can be used to restrict the \
results to the given delegates.\n"~query:validators_query~output:(listencoding)pathendletendorsing_slots_at_levelctxtlevel=Baking.endorsing_rightsctxtlevel>|=?fun(_,rights)->Signature.Public_key_hash.Map.fold(fundelegateslotsacc->{level=level.level;delegate;slots}::acc)(rights:>Slot.tlistSignature.Public_key_hash.Map.t)[]letregister()=Registration.register0~chunked:trueS.validators(functxtq()->letlevels=requested_levels~default_level:(Level.currentctxt)ctxt[]q.levelsinList.concat_map_es(endorsing_slots_at_levelctxt)levels>|=?funrights->matchq.delegateswith|[]->rights|_::_asdelegates->letis_requestedp=List.exists(Tezos_crypto.Signature.V0.Public_key_hash.equalp.delegate)delegatesinList.filteris_requestedrights)letgetctxt?(levels=[])?(delegates=[])block=RPC_context.make_call0S.validatorsctxtblock{levels;delegates}()endmoduleS=structopenData_encodingtypelevel_query={offset:int32}letlevel_query:level_queryTezos_rpc.Query.t=letopenTezos_rpc.Queryinquery(funoffset->{offset})|+field"offset"Tezos_rpc.Arg.int320l(funt->t.offset)|>sealletcurrent_level=Tezos_rpc.Service.get_service~description:"Returns the level of the interrogated block, or the one of a block \
located `offset` blocks after it in the chain. For instance, the \
next block if `offset` is 1. The offset cannot be negative."~query:level_query~output:Level.encodingTezos_rpc.Path.(path/"current_level")letlevels_in_current_cycle=Tezos_rpc.Service.get_service~description:"Levels of a cycle"~query:level_query~output:(obj2(req"first"Raw_level.encoding)(req"last"Raw_level.encoding))Tezos_rpc.Path.(path/"levels_in_current_cycle")letround=Tezos_rpc.Service.get_service~description:"Returns the round of the interrogated block, or the one of a block \
located `offset` blocks after in the chain (or before when \
negative). For instance, the next block if `offset` is 1."~query:Tezos_rpc.Query.empty~output:Round.encodingTezos_rpc.Path.(path/"round")endtypeEnvironment.Error_monad.error+=Negative_level_offsetlet()=Environment.Error_monad.register_error_kind`Permanent~id:"negative_level_offset"~title:"The specified level offset is negative"~description:"The specified level offset is negative"~pp:(funppf()->Format.fprintfppf"The specified level offset should be positive.")Data_encoding.unit(functionNegative_level_offset->Some()|_->None)(fun()->Negative_level_offset)letregister()=Scripts.register();Forge.register();Parse.register();Contract.register();Big_map.register();Baking_rights.register();Endorsing_rights.register();Validators.register();Sc_rollup.register();Tx_rollup.register();Registration.register0~chunked:falseS.current_level(functxtq()->ifq.offset<0lthenfailNegative_level_offsetelseLwt.return(Level.from_raw_with_offsetctxt~offset:q.offset(Level.currentctxt).level));Registration.opt_register0~chunked:trueS.levels_in_current_cycle(functxtq()->letrev_levels=Level.levels_in_current_cyclectxt~offset:q.offset()inmatchrev_levelswith|[]->return_none|[level]->return(Some(level.level,level.level))|last::default_first::rest->(* The [rev_levels] list is reversed, the last level is the head *)letfirst=List.lastdefault_firstrestinreturn(Some(first.level,last.level)));Registration.register0~chunked:falseS.round(functxt()()->Round.getctxt)letcurrent_levelctxt?(offset=0l)block=RPC_context.make_call0S.current_levelctxtblock{offset}()letlevels_in_current_cyclectxt?(offset=0l)block=RPC_context.make_call0S.levels_in_current_cyclectxtblock{offset}()letrpc_services=register();Tezos_rpc.Directory.mergerpc_services!Registration.patched_servicesend