123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661(*****************************************************************************)(* *)(* Open Source License *)(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)(* Copyright (c) 2022 Nomadic Labs <contact@nomadic-labs.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. *)(* *)(*****************************************************************************)(* Tezos Protocol Implementation - Low level Repr. of Operations *)moduleKind=structtypepreattestation_consensus_kind=Preattestation_consensus_kindtypeattestation_consensus_kind=Attestation_consensus_kindtype'aconsensus=|Preattestation_kind:preattestation_consensus_kindconsensus|Attestation_kind:attestation_consensus_kindconsensustypepreattestation=preattestation_consensus_kindconsensustypeattestation=attestation_consensus_kindconsensustypedal_attestation=Dal_attestation_kindtypeseed_nonce_revelation=Seed_nonce_revelation_kindtypevdf_revelation=Vdf_revelation_kindtype'adouble_consensus_operation_evidence=|Double_consensus_operation_evidencetypedouble_attestation_evidence=attestation_consensus_kinddouble_consensus_operation_evidencetypedouble_preattestation_evidence=preattestation_consensus_kinddouble_consensus_operation_evidencetypedouble_baking_evidence=Double_baking_evidence_kindtypeactivate_account=Activate_account_kindtypeproposals=Proposals_kindtypeballot=Ballot_kindtypereveal=Reveal_kindtypetransaction=Transaction_kindtypeorigination=Origination_kindtypedelegation=Delegation_kindtypeevent=Event_kindtypeincrease_paid_storage=Increase_paid_storage_kindtypeupdate_consensus_key=Update_consensus_key_kindtypedrain_delegate=Drain_delegate_kindtypefailing_noop=Failing_noop_kindtyperegister_global_constant=Register_global_constant_kindtypetransfer_ticket=Transfer_ticket_kindtypedal_publish_slot_header=Dal_publish_slot_header_kindtypesc_rollup_originate=Sc_rollup_originate_kindtypesc_rollup_add_messages=Sc_rollup_add_messages_kindtypesc_rollup_cement=Sc_rollup_cement_kindtypesc_rollup_publish=Sc_rollup_publish_kindtypesc_rollup_refute=Sc_rollup_refute_kindtypesc_rollup_timeout=Sc_rollup_timeout_kindtypesc_rollup_execute_outbox_message=|Sc_rollup_execute_outbox_message_kindtypesc_rollup_recover_bond=Sc_rollup_recover_bond_kindtypezk_rollup_origination=Zk_rollup_origination_kindtypezk_rollup_publish=Zk_rollup_publish_kindtypezk_rollup_update=Zk_rollup_update_kindtype'amanager=|Reveal_manager_kind:revealmanager|Transaction_manager_kind:transactionmanager|Origination_manager_kind:originationmanager|Delegation_manager_kind:delegationmanager|Event_manager_kind:eventmanager|Register_global_constant_manager_kind:register_global_constantmanager|Increase_paid_storage_manager_kind:increase_paid_storagemanager|Update_consensus_key_manager_kind:update_consensus_keymanager|Transfer_ticket_manager_kind:transfer_ticketmanager|Dal_publish_slot_header_manager_kind:dal_publish_slot_headermanager|Sc_rollup_originate_manager_kind:sc_rollup_originatemanager|Sc_rollup_add_messages_manager_kind:sc_rollup_add_messagesmanager|Sc_rollup_cement_manager_kind:sc_rollup_cementmanager|Sc_rollup_publish_manager_kind:sc_rollup_publishmanager|Sc_rollup_refute_manager_kind:sc_rollup_refutemanager|Sc_rollup_timeout_manager_kind:sc_rollup_timeoutmanager|Sc_rollup_execute_outbox_message_manager_kind:sc_rollup_execute_outbox_messagemanager|Sc_rollup_recover_bond_manager_kind:sc_rollup_recover_bondmanager|Zk_rollup_origination_manager_kind:zk_rollup_originationmanager|Zk_rollup_publish_manager_kind:zk_rollup_publishmanager|Zk_rollup_update_manager_kind:zk_rollup_updatemanagerendtype'aconsensus_operation_type=|Attestation:Kind.attestationconsensus_operation_type|Preattestation:Kind.preattestationconsensus_operation_typetypeconsensus_content={slot:Slot_repr.t;level:Raw_level_repr.t;(* The level is not required to validate an attestation when it corresponds
to the current payload, but if we want to filter attestations, we need
the level. *)round:Round_repr.t;block_payload_hash:Block_payload_hash.t;(* NOTE: This could be just the hash of the set of operations (the
actual payload). The grandfather block hash should already be
fixed by the operation.shell.branch field. This is not really
important but could make things easier for debugging *)}letconsensus_content_encoding=letopenData_encodinginconv(fun{slot;level;round;block_payload_hash}->(slot,level,round,block_payload_hash))(fun(slot,level,round,block_payload_hash)->{slot;level;round;block_payload_hash})(obj4(req"slot"Slot_repr.encoding)(req"level"Raw_level_repr.encoding)(req"round"Round_repr.encoding)(req"block_payload_hash"Block_payload_hash.encoding))letpp_consensus_contentppfcontent=Format.fprintfppf"(%ld, %a, %a, %a)"(Raw_level_repr.to_int32content.level)Round_repr.ppcontent.roundSlot_repr.ppcontent.slotBlock_payload_hash.pp_shortcontent.block_payload_hashtypeconsensus_watermark=|AttestationofChain_id.t|PreattestationofChain_id.t|Dal_attestationofChain_id.tletto_watermark=function|Preattestationchain_id->Signature.Custom(Bytes.cat(Bytes.of_string"\x12")(Chain_id.to_byteschain_id))|Dal_attestationchain_id(* FIXME: https://gitlab.com/tezos/tezos/-/issues/4479
We reuse the watermark of an attestation. This is because this
operation is temporary and aims to be merged with an attestation
later on. Moreover, there is a leak of abstraction with the shell
which makes adding a new watermark a bit awkward. *)|Attestationchain_id->Signature.Custom(Bytes.cat(Bytes.of_string"\x13")(Chain_id.to_byteschain_id))letof_watermark=function|Signature.Customb->ifCompare.Int.(Bytes.lengthb>0)thenmatchBytes.getb0with|'\x12'->Option.map(funchain_id->Preattestationchain_id)(Chain_id.of_bytes_opt(Bytes.subb1(Bytes.lengthb-1)))|'\x13'->Option.map(funchain_id->Attestationchain_id)(Chain_id.of_bytes_opt(Bytes.subb1(Bytes.lengthb-1)))|_->NoneelseNone|_->Nonetyperaw=Operation.t={shell:Operation.shell_header;proto:bytes}letraw_encoding=Operation.encodingtype'kindoperation={shell:Operation.shell_header;protocol_data:'kindprotocol_data;}and'kindprotocol_data={contents:'kindcontents_list;signature:Signature.toption;}and_contents_list=|Single:'kindcontents->'kindcontents_list|Cons:'kindKind.managercontents*'restKind.managercontents_list->('kind*'rest)Kind.managercontents_listand_contents=|Preattestation:consensus_content->Kind.preattestationcontents|Attestation:consensus_content->Kind.attestationcontents|Dal_attestation:Dal_attestation_repr.operation->Kind.dal_attestationcontents|Seed_nonce_revelation:{level:Raw_level_repr.t;nonce:Seed_repr.nonce;}->Kind.seed_nonce_revelationcontents|Vdf_revelation:{solution:Seed_repr.vdf_solution;}->Kind.vdf_revelationcontents|Double_preattestation_evidence:{op1:Kind.preattestationoperation;op2:Kind.preattestationoperation;}->Kind.double_preattestation_evidencecontents|Double_attestation_evidence:{op1:Kind.attestationoperation;op2:Kind.attestationoperation;}->Kind.double_attestation_evidencecontents|Double_baking_evidence:{bh1:Block_header_repr.t;bh2:Block_header_repr.t;}->Kind.double_baking_evidencecontents|Activate_account:{id:Ed25519.Public_key_hash.t;activation_code:Blinded_public_key_hash.activation_code;}->Kind.activate_accountcontents|Proposals:{source:Signature.Public_key_hash.t;period:int32;proposals:Protocol_hash.tlist;}->Kind.proposalscontents|Ballot:{source:Signature.Public_key_hash.t;period:int32;proposal:Protocol_hash.t;ballot:Vote_repr.ballot;}->Kind.ballotcontents|Drain_delegate:{consensus_key:Signature.Public_key_hash.t;delegate:Signature.Public_key_hash.t;destination:Signature.Public_key_hash.t;}->Kind.drain_delegatecontents|Failing_noop:string->Kind.failing_noopcontents|Manager_operation:{source:Signature.public_key_hash;fee:Tez_repr.tez;counter:Manager_counter_repr.t;operation:'kindmanager_operation;gas_limit:Gas_limit_repr.Arith.integral;storage_limit:Z.t;}->'kindKind.managercontentsand_manager_operation=|Reveal:Signature.Public_key.t->Kind.revealmanager_operation|Transaction:{amount:Tez_repr.tez;parameters:Script_repr.lazy_expr;entrypoint:Entrypoint_repr.t;destination:Contract_repr.t;}->Kind.transactionmanager_operation|Origination:{delegate:Signature.Public_key_hash.toption;script:Script_repr.t;credit:Tez_repr.tez;}->Kind.originationmanager_operation|Delegation:Signature.Public_key_hash.toption->Kind.delegationmanager_operation|Register_global_constant:{value:Script_repr.lazy_expr;}->Kind.register_global_constantmanager_operation|Increase_paid_storage:{amount_in_bytes:Z.t;destination:Contract_hash.t;}->Kind.increase_paid_storagemanager_operation|Update_consensus_key:Signature.Public_key.t->Kind.update_consensus_keymanager_operation|Transfer_ticket:{contents:Script_repr.lazy_expr;ty:Script_repr.lazy_expr;ticketer:Contract_repr.t;amount:Ticket_amount.t;destination:Contract_repr.t;entrypoint:Entrypoint_repr.t;}->Kind.transfer_ticketmanager_operation|Dal_publish_slot_header:Dal_operations_repr.Publish_slot_header.t->Kind.dal_publish_slot_headermanager_operation|Sc_rollup_originate:{kind:Sc_rollups.Kind.t;boot_sector:string;parameters_ty:Script_repr.lazy_expr;whitelist:Sc_rollup_whitelist_repr.toption;}->Kind.sc_rollup_originatemanager_operation|Sc_rollup_add_messages:{messages:stringlist;}->Kind.sc_rollup_add_messagesmanager_operation|Sc_rollup_cement:{rollup:Sc_rollup_repr.t;}->Kind.sc_rollup_cementmanager_operation|Sc_rollup_publish:{rollup:Sc_rollup_repr.t;commitment:Sc_rollup_commitment_repr.t;}->Kind.sc_rollup_publishmanager_operation|Sc_rollup_refute:{rollup:Sc_rollup_repr.t;opponent:Sc_rollup_repr.Staker.t;refutation:Sc_rollup_game_repr.refutation;}->Kind.sc_rollup_refutemanager_operation|Sc_rollup_timeout:{rollup:Sc_rollup_repr.t;stakers:Sc_rollup_game_repr.Index.t;}->Kind.sc_rollup_timeoutmanager_operation|Sc_rollup_execute_outbox_message:{rollup:Sc_rollup_repr.t;cemented_commitment:Sc_rollup_commitment_repr.Hash.t;output_proof:string;}->Kind.sc_rollup_execute_outbox_messagemanager_operation|Sc_rollup_recover_bond:{sc_rollup:Sc_rollup_repr.t;staker:Signature.public_key_hash;}->Kind.sc_rollup_recover_bondmanager_operation|Zk_rollup_origination:{public_parameters:Plonk.public_parameters;circuits_info:[`Public|`Private|`Fee]Zk_rollup_account_repr.SMap.t;init_state:Zk_rollup_state_repr.t;nb_ops:int;}->Kind.zk_rollup_originationmanager_operation|Zk_rollup_publish:{zk_rollup:Zk_rollup_repr.t;ops:(Zk_rollup_operation_repr.t*Zk_rollup_ticket_repr.toption)list;}->Kind.zk_rollup_publishmanager_operation|Zk_rollup_update:{zk_rollup:Zk_rollup_repr.t;update:Zk_rollup_update_repr.t;}->Kind.zk_rollup_updatemanager_operationletmanager_kind:typekind.kindmanager_operation->kindKind.manager=function|Reveal_->Kind.Reveal_manager_kind|Transaction_->Kind.Transaction_manager_kind|Origination_->Kind.Origination_manager_kind|Delegation_->Kind.Delegation_manager_kind|Register_global_constant_->Kind.Register_global_constant_manager_kind|Increase_paid_storage_->Kind.Increase_paid_storage_manager_kind|Update_consensus_key_->Kind.Update_consensus_key_manager_kind|Transfer_ticket_->Kind.Transfer_ticket_manager_kind|Dal_publish_slot_header_->Kind.Dal_publish_slot_header_manager_kind|Sc_rollup_originate_->Kind.Sc_rollup_originate_manager_kind|Sc_rollup_add_messages_->Kind.Sc_rollup_add_messages_manager_kind|Sc_rollup_cement_->Kind.Sc_rollup_cement_manager_kind|Sc_rollup_publish_->Kind.Sc_rollup_publish_manager_kind|Sc_rollup_refute_->Kind.Sc_rollup_refute_manager_kind|Sc_rollup_timeout_->Kind.Sc_rollup_timeout_manager_kind|Sc_rollup_execute_outbox_message_->Kind.Sc_rollup_execute_outbox_message_manager_kind|Sc_rollup_recover_bond_->Kind.Sc_rollup_recover_bond_manager_kind|Zk_rollup_origination_->Kind.Zk_rollup_origination_manager_kind|Zk_rollup_publish_->Kind.Zk_rollup_publish_manager_kind|Zk_rollup_update_->Kind.Zk_rollup_update_manager_kindtypepacked_manager_operation=|Manager:'kindmanager_operation->packed_manager_operationtypepacked_contents=Contents:'kindcontents->packed_contentstypepacked_contents_list=|Contents_list:'kindcontents_list->packed_contents_listtypepacked_protocol_data=|Operation_data:'kindprotocol_data->packed_protocol_datatypepacked_operation={shell:Operation.shell_header;protocol_data:packed_protocol_data;}letpack({shell;protocol_data}:_operation):packed_operation={shell;protocol_data=Operation_dataprotocol_data}letreccontents_list_to_list:typea.acontents_list->_=function|Singleo->[Contentso]|Cons(o,os)->Contentso::contents_list_to_listosletto_list=functionContents_listl->contents_list_to_listl(* This first version of of_list has the type (_, string) result expected by
the conv_with_guard combinator of Data_encoding. For a more conventional
return type see [of_list] below. *)letof_list_internalcontents=letrecof_list_internalacc=function|[]->Okacc|Contentso::os->(match(o,acc)with|(Manager_operation_,Contents_list(Single(Manager_operation_)asrest))->(of_list_internal[@tailcall])(Contents_list(Cons(o,rest)))os|Manager_operation_,Contents_list(Cons_asrest)->(of_list_internal[@tailcall])(Contents_list(Cons(o,rest)))os|_->Error"Operation list of length > 1 should only contain manager \
operations.")inmatchList.revcontentswith|[]->Error"Operation lists should not be empty."|Contentso::os->of_list_internal(Contents_list(Singleo))ostypeerror+=Contents_list_errorofstring(* `Permanent *)letof_listl=matchof_list_internallwith|Okcontents->Okcontents|Errors->error@@Contents_list_errorslettx_rollup_operation_tag_offset=150lettx_rollup_operation_origination_tag=tx_rollup_operation_tag_offset+0lettx_rollup_operation_submit_batch_tag=tx_rollup_operation_tag_offset+1lettx_rollup_operation_commit_tag=tx_rollup_operation_tag_offset+2lettx_rollup_operation_return_bond_tag=tx_rollup_operation_tag_offset+3lettx_rollup_operation_finalize_commitment_tag=tx_rollup_operation_tag_offset+4lettx_rollup_operation_remove_commitment_tag=tx_rollup_operation_tag_offset+5lettx_rollup_operation_rejection_tag=tx_rollup_operation_tag_offset+6lettx_rollup_operation_dispatch_tickets_tag=tx_rollup_operation_tag_offset+7(** The following operation tags cannot be used again, it is checked
at compilation time. *)lettx_rollup_forbidden_operation_tags=[tx_rollup_operation_origination_tag;tx_rollup_operation_submit_batch_tag;tx_rollup_operation_commit_tag;tx_rollup_operation_return_bond_tag;tx_rollup_operation_finalize_commitment_tag;tx_rollup_operation_remove_commitment_tag;tx_rollup_operation_rejection_tag;tx_rollup_operation_dispatch_tickets_tag;]lettransfer_ticket_tag=tx_rollup_operation_tag_offset+8letsc_rollup_operation_tag_offset=200letsc_rollup_operation_origination_tag=sc_rollup_operation_tag_offset+0letsc_rollup_operation_add_message_tag=sc_rollup_operation_tag_offset+1letsc_rollup_operation_cement_tag=sc_rollup_operation_tag_offset+2letsc_rollup_operation_publish_tag=sc_rollup_operation_tag_offset+3letsc_rollup_operation_refute_tag=sc_rollup_operation_tag_offset+4letsc_rollup_operation_timeout_tag=sc_rollup_operation_tag_offset+5letsc_rollup_execute_outbox_message_tag=sc_rollup_operation_tag_offset+6letsc_rollup_operation_recover_bond_tag=sc_rollup_operation_tag_offset+7letdal_offset=230letdal_publish_slot_header_tag=dal_offset+0letzk_rollup_operation_tag_offset=250letzk_rollup_operation_create_tag=zk_rollup_operation_tag_offset+0letzk_rollup_operation_publish_tag=zk_rollup_operation_tag_offset+1letzk_rollup_operation_update_tag=zk_rollup_operation_tag_offset+2moduleEncoding=structopenData_encoding(** These tags can not be used yet for operations. *)letreserved_tagt=(* These tags are reserved for future extensions: [fd] - [ff]. *)Compare.Int.(t>=0xfd)||(* These tags were used by old operations.
The operations have been removed in protocol proposal N, it can
be unblocked in the future (e.g. proposal O, P etc.). *)List.exists(Compare.Int.equalt)tx_rollup_forbidden_operation_tagsletsignature_prefix_tag=0xfflet()=assert(reserved_tagsignature_prefix_tag)letcasetagnameargsprojinj=casetag~title:(String.capitalize_asciiname)(merge_objs(obj1(req"kind"(constantname)))args)(funx->matchprojxwithNone->None|Somex->Some((),x))(fun((),x)->injx)moduleManager_operations=structtype'kindcase=|MCase:{tag:int;name:string;encoding:'aData_encoding.t;select:packed_manager_operation->'kindmanager_operationoption;proj:'kindmanager_operation->'a;inj:'a->'kindmanager_operation;}->'kindcaseletreveal_case=MCase{tag=0;name="reveal";encoding=obj1(req"public_key"Signature.Public_key.encoding);select=(functionManager(Reveal_asop)->Someop|_->None);proj=(functionRevealpkh->pkh);inj=(funpkh->Revealpkh);}lettransaction_case=MCase{tag=1;name="transaction";encoding=obj3(req"amount"Tez_repr.encoding)(req"destination"Contract_repr.encoding)(opt"parameters"(obj2(req"entrypoint"Entrypoint_repr.smart_encoding)(req"value"Script_repr.lazy_expr_encoding)));select=(functionManager(Transaction_asop)->Someop|_->None);proj=(function|Transaction{amount;destination;parameters;entrypoint}->letparameters=ifScript_repr.is_unit_parameterparameters&&Entrypoint_repr.is_defaultentrypointthenNoneelseSome(entrypoint,parameters)in(amount,destination,parameters));inj=(fun(amount,destination,parameters)->letentrypoint,parameters=matchparameterswith|None->(Entrypoint_repr.default,Script_repr.unit_parameter)|Some(entrypoint,value)->(entrypoint,value)inTransaction{amount;destination;parameters;entrypoint});}letorigination_case=MCase{tag=2;name="origination";encoding=obj3(req"balance"Tez_repr.encoding)(opt"delegate"Signature.Public_key_hash.encoding)(req"script"Script_repr.encoding);select=(functionManager(Origination_asop)->Someop|_->None);proj=(function|Origination{credit;delegate;script}->(credit,delegate,script));inj=(fun(credit,delegate,script)->Origination{credit;delegate;script});}letdelegation_case=MCase{tag=3;name="delegation";encoding=obj1(opt"delegate"Signature.Public_key_hash.encoding);select=(functionManager(Delegation_asop)->Someop|_->None);proj=(functionDelegationkey->key);inj=(funkey->Delegationkey);}letregister_global_constant_case=MCase{tag=4;name="register_global_constant";encoding=obj1(req"value"Script_repr.lazy_expr_encoding);select=(function|Manager(Register_global_constant_asop)->Someop|_->None);proj=(functionRegister_global_constant{value}->value);inj=(funvalue->Register_global_constant{value});}(* Tag 5 was for Set_deposits_limit. *)letincrease_paid_storage_case=MCase{tag=9;name="increase_paid_storage";encoding=obj2(req"amount"Data_encoding.z)(req"destination"Contract_repr.originated_encoding);select=(function|Manager(Increase_paid_storage_asop)->Someop|_->None);proj=(function|Increase_paid_storage{amount_in_bytes;destination}->(amount_in_bytes,destination));inj=(fun(amount_in_bytes,destination)->Increase_paid_storage{amount_in_bytes;destination});}letupdate_consensus_key_tag=6letupdate_consensus_key_case=MCase{tag=update_consensus_key_tag;name="update_consensus_key";encoding=obj1(req"pk"Signature.Public_key.encoding);select=(function|Manager(Update_consensus_key_asop)->Someop|_->None);proj=(functionUpdate_consensus_keyconsensus_pk->consensus_pk);inj=(funconsensus_pk->Update_consensus_keyconsensus_pk);}lettransfer_ticket_case=MCase{tag=transfer_ticket_tag;name="transfer_ticket";encoding=obj6(req"ticket_contents"Script_repr.lazy_expr_encoding)(req"ticket_ty"Script_repr.lazy_expr_encoding)(req"ticket_ticketer"Contract_repr.encoding)(req"ticket_amount"Ticket_amount.encoding)(req"destination"Contract_repr.encoding)(req"entrypoint"Entrypoint_repr.simple_encoding);select=(function|Manager(Transfer_ticket_asop)->Someop|_->None);proj=(function|Transfer_ticket{contents;ty;ticketer;amount;destination;entrypoint}->(contents,ty,ticketer,amount,destination,entrypoint));inj=(fun(contents,ty,ticketer,amount,destination,entrypoint)->Transfer_ticket{contents;ty;ticketer;amount;destination;entrypoint});}letzk_rollup_origination_case=MCase{tag=zk_rollup_operation_create_tag;name="zk_rollup_origination";encoding=obj4(req"public_parameters"Plonk.public_parameters_encoding)(req"circuits_info"Zk_rollup_account_repr.circuits_info_encoding)(req"init_state"Zk_rollup_state_repr.encoding)(* TODO https://gitlab.com/tezos/tezos/-/issues/3655
Encoding of non-negative [nb_ops] for origination *)(req"nb_ops"int31);select=(function|Manager(Zk_rollup_origination_asop)->Someop|_->None);proj=(function|Zk_rollup_origination{public_parameters;circuits_info;init_state;nb_ops}->(public_parameters,circuits_info,init_state,nb_ops));inj=(fun(public_parameters,circuits_info,init_state,nb_ops)->Zk_rollup_origination{public_parameters;circuits_info;init_state;nb_ops});}letzk_rollup_publish_case=MCase{tag=zk_rollup_operation_publish_tag;name="zk_rollup_publish";encoding=obj2(req"zk_rollup"Zk_rollup_repr.Address.encoding)(req"op"@@Data_encoding.list(tup2Zk_rollup_operation_repr.encoding(optionZk_rollup_ticket_repr.encoding)));select=(function|Manager(Zk_rollup_publish_asop)->Someop|_->None);proj=(functionZk_rollup_publish{zk_rollup;ops}->(zk_rollup,ops));inj=(fun(zk_rollup,ops)->Zk_rollup_publish{zk_rollup;ops});}letzk_rollup_update_case=MCase{tag=zk_rollup_operation_update_tag;name="zk_rollup_update";encoding=obj2(req"zk_rollup"Zk_rollup_repr.Address.encoding)(req"update"Zk_rollup_update_repr.encoding);select=(function|Manager(Zk_rollup_update_asop)->Someop|_->None);proj=(function|Zk_rollup_update{zk_rollup;update}->(zk_rollup,update));inj=(fun(zk_rollup,update)->Zk_rollup_update{zk_rollup;update});}letsc_rollup_originate_case=MCase{tag=sc_rollup_operation_origination_tag;name="smart_rollup_originate";encoding=obj4(req"pvm_kind"Sc_rollups.Kind.encoding)(req"kernel"(stringHex))(req"parameters_ty"Script_repr.lazy_expr_encoding)(opt"whitelist"Sc_rollup_whitelist_repr.encoding);select=(function|Manager(Sc_rollup_originate_asop)->Someop|_->None);proj=(function|Sc_rollup_originate{kind;boot_sector;parameters_ty;whitelist}->(kind,boot_sector,parameters_ty,whitelist));inj=(fun(kind,boot_sector,parameters_ty,whitelist)->Sc_rollup_originate{kind;boot_sector;parameters_ty;whitelist});}letdal_publish_slot_header_case=MCase{tag=dal_publish_slot_header_tag;name="dal_publish_slot_header";encoding=obj1(req"slot_header"Dal_operations_repr.Publish_slot_header.encoding);select=(function|Manager(Dal_publish_slot_header_asop)->Someop|_->None);proj=(functionDal_publish_slot_headerslot_header->slot_header);inj=(funslot_header->Dal_publish_slot_headerslot_header);}letsc_rollup_add_messages_case=MCase{tag=sc_rollup_operation_add_message_tag;name="smart_rollup_add_messages";encoding=obj1(req"message"(list(stringHex)));select=(function|Manager(Sc_rollup_add_messages_asop)->Someop|_->None);proj=(functionSc_rollup_add_messages{messages}->messages);inj=(funmessages->Sc_rollup_add_messages{messages});}letsc_rollup_cement_case=MCase{tag=sc_rollup_operation_cement_tag;name="smart_rollup_cement";encoding=obj1(req"rollup"Sc_rollup_repr.encoding);select=(function|Manager(Sc_rollup_cement_asop)->Someop|_->None);proj=(functionSc_rollup_cement{rollup}->rollup);inj=(funrollup->Sc_rollup_cement{rollup});}letsc_rollup_publish_case=MCase{tag=sc_rollup_operation_publish_tag;name="smart_rollup_publish";encoding=obj2(req"rollup"Sc_rollup_repr.encoding)(req"commitment"Sc_rollup_commitment_repr.encoding);select=(function|Manager(Sc_rollup_publish_asop)->Someop|_->None);proj=(function|Sc_rollup_publish{rollup;commitment}->(rollup,commitment));inj=(fun(rollup,commitment)->Sc_rollup_publish{rollup;commitment});}letsc_rollup_refute_case=MCase{tag=sc_rollup_operation_refute_tag;name="smart_rollup_refute";encoding=obj3(req"rollup"Sc_rollup_repr.encoding)(req"opponent"Sc_rollup_repr.Staker.encoding)(req"refutation"Sc_rollup_game_repr.refutation_encoding);select=(function|Manager(Sc_rollup_refute_asop)->Someop|_->None);proj=(function|Sc_rollup_refute{rollup;opponent;refutation}->(rollup,opponent,refutation));inj=(fun(rollup,opponent,refutation)->Sc_rollup_refute{rollup;opponent;refutation});}letsc_rollup_timeout_case=MCase{tag=sc_rollup_operation_timeout_tag;name="smart_rollup_timeout";encoding=obj2(req"rollup"Sc_rollup_repr.encoding)(req"stakers"Sc_rollup_game_repr.Index.encoding);select=(function|Manager(Sc_rollup_timeout_asop)->Someop|_->None);proj=(function|Sc_rollup_timeout{rollup;stakers}->(rollup,stakers));inj=(fun(rollup,stakers)->Sc_rollup_timeout{rollup;stakers});}letsc_rollup_execute_outbox_message_case=MCase{tag=sc_rollup_execute_outbox_message_tag;name="smart_rollup_execute_outbox_message";encoding=obj3(req"rollup"Sc_rollup_repr.encoding)(req"cemented_commitment"Sc_rollup_commitment_repr.Hash.encoding)(req"output_proof"(stringHex));select=(function|Manager(Sc_rollup_execute_outbox_message_asop)->Someop|_->None);proj=(function|Sc_rollup_execute_outbox_message{rollup;cemented_commitment;output_proof}->(rollup,cemented_commitment,output_proof));inj=(fun(rollup,cemented_commitment,output_proof)->Sc_rollup_execute_outbox_message{rollup;cemented_commitment;output_proof});}letsc_rollup_recover_bond_case=MCase{tag=sc_rollup_operation_recover_bond_tag;name="smart_rollup_recover_bond";encoding=obj2(req"rollup"Sc_rollup_repr.Address.encoding)(req"staker"Signature.Public_key_hash.encoding);select=(function|Manager(Sc_rollup_recover_bond_asop)->Someop|_->None);proj=(function|Sc_rollup_recover_bond{sc_rollup;staker}->(sc_rollup,staker));inj=(fun(sc_rollup,staker)->Sc_rollup_recover_bond{sc_rollup;staker});}endtype'bcase=|Case:{tag:int;name:string;encoding:'aData_encoding.t;select:packed_contents->'bcontentsoption;proj:'bcontents->'a;inj:'a->'bcontents;}->'bcaseletpreendorsement_case=Case{tag=20;name="preendorsement";encoding=consensus_content_encoding;select=(functionContents(Preattestation_asop)->Someop|_->None);proj=(fun(Preattestationpreattestation)->preattestation);inj=(funpreattestation->Preattestationpreattestation);}letpreattestation_case=Case{tag=20;name="preattestation";encoding=consensus_content_encoding;select=(functionContents(Preattestation_asop)->Someop|_->None);proj=(fun(Preattestationpreattestation)->preattestation);inj=(funpreattestation->Preattestationpreattestation);}letpreendorsement_encoding=letmake(Case{tag;name;encoding;select=_;proj;inj})=case(Tagtag)nameencoding(funo->Some(projo))(funx->injx)inletto_list:Kind.preattestationcontents_list->_=function|Singleo->oinletof_list:Kind.preattestationcontents->_=function|o->Singleoindef"inlined.preendorsement"@@conv(fun({shell;protocol_data={contents;signature}}:_operation)->(shell,(contents,signature)))(fun(shell,(contents,signature)):_operation->{shell;protocol_data={contents;signature}})(merge_objsOperation.shell_header_encoding(obj2(req"operations"(convto_listof_list@@def"inlined.preendorsement.contents"@@union[makepreendorsement_case]))(varopt"signature"Signature.encoding)))letpreattestation_encoding=letmake(Case{tag;name;encoding;select=_;proj;inj})=case(Tagtag)nameencoding(funo->Some(projo))(funx->injx)inletto_list:Kind.preattestationcontents_list->_=function|Singleo->oinletof_list:Kind.preattestationcontents->_=function|o->Singleoindef"inlined.preattestation"@@conv(fun({shell;protocol_data={contents;signature}}:_operation)->(shell,(contents,signature)))(fun(shell,(contents,signature)):_operation->{shell;protocol_data={contents;signature}})(merge_objsOperation.shell_header_encoding(obj2(req"operations"(convto_listof_list@@def"inlined.preattestation.contents"@@union[makepreattestation_case]))(varopt"signature"Signature.encoding)))letendorsement_encoding=obj4(req"slot"Slot_repr.encoding)(req"level"Raw_level_repr.encoding)(req"round"Round_repr.encoding)(req"block_payload_hash"Block_payload_hash.encoding)letendorsement_case=Case{tag=21;name="endorsement";encoding=endorsement_encoding;select=(functionContents(Attestation_asop)->Someop|_->None);proj=(fun(Attestationconsensus_content)->(consensus_content.slot,consensus_content.level,consensus_content.round,consensus_content.block_payload_hash));inj=(fun(slot,level,round,block_payload_hash)->Attestation{slot;level;round;block_payload_hash});}letattestation_case=Case{tag=21;name="attestation";encoding=endorsement_encoding;select=(functionContents(Attestation_asop)->Someop|_->None);proj=(fun(Attestationconsensus_content)->(consensus_content.slot,consensus_content.level,consensus_content.round,consensus_content.block_payload_hash));inj=(fun(slot,level,round,block_payload_hash)->Attestation{slot;level;round;block_payload_hash});}letendorsement_encoding=letmake(Case{tag;name;encoding;select=_;proj;inj})=case(Tagtag)nameencoding(funo->Some(projo))(funx->injx)inletto_list:Kind.attestationcontents_list->_=fun(Singleo)->oinletof_list:Kind.attestationcontents->_=funo->Singleoindef"inlined.endorsement"@@conv(fun({shell;protocol_data={contents;signature}}:_operation)->(shell,(contents,signature)))(fun(shell,(contents,signature)):_operation->{shell;protocol_data={contents;signature}})(merge_objsOperation.shell_header_encoding(obj2(req"operations"(convto_listof_list@@def"inlined.endorsement_mempool.contents"@@union[makeendorsement_case]))(varopt"signature"Signature.encoding)))letattestation_encoding=letmake(Case{tag;name;encoding;select=_;proj;inj})=case(Tagtag)nameencoding(funo->Some(projo))(funx->injx)inletto_list:Kind.attestationcontents_list->_=fun(Singleo)->oinletof_list:Kind.attestationcontents->_=funo->Singleoindef"inlined.attestation"@@conv(fun({shell;protocol_data={contents;signature}}:_operation)->(shell,(contents,signature)))(fun(shell,(contents,signature)):_operation->{shell;protocol_data={contents;signature}})(merge_objsOperation.shell_header_encoding(obj2(req"operations"(convto_listof_list@@def"inlined.attestation_mempool.contents"@@union[makeattestation_case]))(varopt"signature"Signature.encoding)))letdal_attestation_encoding=obj3(req"attestor"Signature.Public_key_hash.encoding)(req"attestation"Dal_attestation_repr.encoding)(req"level"Raw_level_repr.encoding)letdal_attestation_case=Case{tag=22;name="dal_attestation";encoding=dal_attestation_encoding;select=(functionContents(Dal_attestation_asop)->Someop|_->None);proj=(fun(Dal_attestationDal_attestation_repr.{attestor;attestation;level})->(attestor,attestation,level));inj=(fun(attestor,attestation,level)->Dal_attestationDal_attestation_repr.{attestor;attestation;level});}letseed_nonce_revelation_case=Case{tag=1;name="seed_nonce_revelation";encoding=obj2(req"level"Raw_level_repr.encoding)(req"nonce"Seed_repr.nonce_encoding);select=(function|Contents(Seed_nonce_revelation_asop)->Someop|_->None);proj=(fun(Seed_nonce_revelation{level;nonce})->(level,nonce));inj=(fun(level,nonce)->Seed_nonce_revelation{level;nonce});}letvdf_revelation_case=Case{tag=8;name="vdf_revelation";encoding=obj1(req"solution"Seed_repr.vdf_solution_encoding);select=(functionContents(Vdf_revelation_asop)->Someop|_->None);proj=(functionVdf_revelation{solution}->solution);inj=(funsolution->Vdf_revelation{solution});}letdouble_preendorsement_evidence_case:Kind.double_preattestation_evidencecase=Case{tag=7;name="double_preendorsement_evidence";encoding=obj2(req"op1"(dynamic_sizepreendorsement_encoding))(req"op2"(dynamic_sizepreendorsement_encoding));select=(function|Contents(Double_preattestation_evidence_asop)->Someop|_->None);proj=(fun(Double_preattestation_evidence{op1;op2})->(op1,op2));inj=(fun(op1,op2)->Double_preattestation_evidence{op1;op2});}letdouble_preattestation_evidence_case:Kind.double_preattestation_evidencecase=Case{tag=7;name="double_preattestation_evidence";encoding=obj2(req"op1"(dynamic_sizepreattestation_encoding))(req"op2"(dynamic_sizepreattestation_encoding));select=(function|Contents(Double_preattestation_evidence_asop)->Someop|_->None);proj=(fun(Double_preattestation_evidence{op1;op2})->(op1,op2));inj=(fun(op1,op2)->Double_preattestation_evidence{op1;op2});}letdouble_endorsement_evidence_case:Kind.double_attestation_evidencecase=Case{tag=2;name="double_endorsement_evidence";encoding=obj2(req"op1"(dynamic_sizeendorsement_encoding))(req"op2"(dynamic_sizeendorsement_encoding));select=(function|Contents(Double_attestation_evidence_asop)->Someop|_->None);proj=(fun(Double_attestation_evidence{op1;op2})->(op1,op2));inj=(fun(op1,op2)->Double_attestation_evidence{op1;op2});}letdouble_attestation_evidence_case:Kind.double_attestation_evidencecase=Case{tag=2;name="double_attestation_evidence";encoding=obj2(req"op1"(dynamic_sizeattestation_encoding))(req"op2"(dynamic_sizeattestation_encoding));select=(function|Contents(Double_attestation_evidence_asop)->Someop|_->None);proj=(fun(Double_attestation_evidence{op1;op2})->(op1,op2));inj=(fun(op1,op2)->Double_attestation_evidence{op1;op2});}letdouble_baking_evidence_case=Case{tag=3;name="double_baking_evidence";encoding=obj2(req"bh1"(dynamic_sizeBlock_header_repr.encoding))(req"bh2"(dynamic_sizeBlock_header_repr.encoding));select=(function|Contents(Double_baking_evidence_asop)->Someop|_->None);proj=(fun(Double_baking_evidence{bh1;bh2})->(bh1,bh2));inj=(fun(bh1,bh2)->Double_baking_evidence{bh1;bh2});}letactivate_account_case=Case{tag=4;name="activate_account";encoding=obj2(req"pkh"Ed25519.Public_key_hash.encoding)(req"secret"Blinded_public_key_hash.activation_code_encoding);select=(function|Contents(Activate_account_asop)->Someop|_->None);proj=(fun(Activate_account{id;activation_code})->(id,activation_code));inj=(fun(id,activation_code)->Activate_account{id;activation_code});}letproposals_case=Case{tag=5;name="proposals";encoding=obj3(req"source"Signature.Public_key_hash.encoding)(req"period"int32)(req"proposals"(list~max_length:Constants_repr.max_proposals_per_delegateProtocol_hash.encoding));select=(functionContents(Proposals_asop)->Someop|_->None);proj=(fun(Proposals{source;period;proposals})->(source,period,proposals));inj=(fun(source,period,proposals)->Proposals{source;period;proposals});}letballot_case=Case{tag=6;name="ballot";encoding=obj4(req"source"Signature.Public_key_hash.encoding)(req"period"int32)(req"proposal"Protocol_hash.encoding)(req"ballot"Vote_repr.ballot_encoding);select=(functionContents(Ballot_asop)->Someop|_->None);proj=(function|Ballot{source;period;proposal;ballot}->(source,period,proposal,ballot));inj=(fun(source,period,proposal,ballot)->Ballot{source;period;proposal;ballot});}letdrain_delegate_case=Case{tag=9;name="drain_delegate";encoding=obj3(req"consensus_key"Signature.Public_key_hash.encoding)(req"delegate"Signature.Public_key_hash.encoding)(req"destination"Signature.Public_key_hash.encoding);select=(functionContents(Drain_delegate_asop)->Someop|_->None);proj=(function|Drain_delegate{consensus_key;delegate;destination}->(consensus_key,delegate,destination));inj=(fun(consensus_key,delegate,destination)->Drain_delegate{consensus_key;delegate;destination});}letfailing_noop_case=Case{tag=17;name="failing_noop";encoding=obj1(req"arbitrary"(stringHex));select=(functionContents(Failing_noop_asop)->Someop|_->None);proj=(functionFailing_noopmessage->message);inj=(functionmessage->Failing_noopmessage);}letmanager_encoding=obj5(req"source"Signature.Public_key_hash.encoding)(req"fee"Tez_repr.encoding)(req"counter"Manager_counter_repr.encoding_for_operation)(req"gas_limit"(check_size10Gas_limit_repr.Arith.n_integral_encoding))(req"storage_limit"(check_size10n))letextract:typekind.kindKind.managercontents->_=function|Manager_operation{source;fee;counter;gas_limit;storage_limit;operation=_}->(source,fee,counter,gas_limit,storage_limit)letrebuild(source,fee,counter,gas_limit,storage_limit)operation=Manager_operation{source;fee;counter;gas_limit;storage_limit;operation}letmake_manager_casetag(typekind)(Manager_operations.MCasemcase:kindManager_operations.case)=Case{tag;name=mcase.name;encoding=merge_objsmanager_encodingmcase.encoding;select=(function|Contents(Manager_operation({operation;_}asop))->(matchmcase.select(Manageroperation)with|None->None|Someoperation->Some(Manager_operation{opwithoperation}))|_->None);proj=(function|Manager_operation{operation;_}asop->(extractop,mcase.projoperation));inj=(fun(op,contents)->rebuildop(mcase.injcontents));}letreveal_case=make_manager_case107Manager_operations.reveal_caselettransaction_case=make_manager_case108Manager_operations.transaction_caseletorigination_case=make_manager_case109Manager_operations.origination_caseletdelegation_case=make_manager_case110Manager_operations.delegation_caseletregister_global_constant_case=make_manager_case111Manager_operations.register_global_constant_case(* 112 was for Set_deposits_limit. *)letincrease_paid_storage_case=make_manager_case113Manager_operations.increase_paid_storage_caseletupdate_consensus_key_case=make_manager_case114Manager_operations.update_consensus_key_caselettransfer_ticket_case=make_manager_casetransfer_ticket_tagManager_operations.transfer_ticket_caseletdal_publish_slot_header_case=make_manager_casedal_publish_slot_header_tagManager_operations.dal_publish_slot_header_caseletsc_rollup_originate_case=make_manager_casesc_rollup_operation_origination_tagManager_operations.sc_rollup_originate_caseletsc_rollup_add_messages_case=make_manager_casesc_rollup_operation_add_message_tagManager_operations.sc_rollup_add_messages_caseletsc_rollup_cement_case=make_manager_casesc_rollup_operation_cement_tagManager_operations.sc_rollup_cement_caseletsc_rollup_publish_case=make_manager_casesc_rollup_operation_publish_tagManager_operations.sc_rollup_publish_caseletsc_rollup_refute_case=make_manager_casesc_rollup_operation_refute_tagManager_operations.sc_rollup_refute_caseletsc_rollup_timeout_case=make_manager_casesc_rollup_operation_timeout_tagManager_operations.sc_rollup_timeout_caseletsc_rollup_execute_outbox_message_case=make_manager_casesc_rollup_execute_outbox_message_tagManager_operations.sc_rollup_execute_outbox_message_caseletsc_rollup_recover_bond_case=make_manager_casesc_rollup_operation_recover_bond_tagManager_operations.sc_rollup_recover_bond_caseletzk_rollup_origination_case=make_manager_casezk_rollup_operation_create_tagManager_operations.zk_rollup_origination_caseletzk_rollup_publish_case=make_manager_casezk_rollup_operation_publish_tagManager_operations.zk_rollup_publish_caseletzk_rollup_update_case=make_manager_casezk_rollup_operation_update_tagManager_operations.zk_rollup_update_casetypepacked_case=PCase:'bcase->packed_caseletcommon_cases=[PCasedal_attestation_case;PCaseseed_nonce_revelation_case;PCasevdf_revelation_case;PCasedouble_baking_evidence_case;PCaseactivate_account_case;PCaseproposals_case;PCaseballot_case;PCasereveal_case;PCasetransaction_case;PCaseorigination_case;PCasedelegation_case;PCaseincrease_paid_storage_case;PCaseupdate_consensus_key_case;PCasedrain_delegate_case;PCasefailing_noop_case;PCaseregister_global_constant_case;PCasetransfer_ticket_case;PCasedal_publish_slot_header_case;PCasesc_rollup_originate_case;PCasesc_rollup_add_messages_case;PCasesc_rollup_cement_case;PCasesc_rollup_publish_case;PCasesc_rollup_refute_case;PCasesc_rollup_timeout_case;PCasesc_rollup_execute_outbox_message_case;PCasesc_rollup_recover_bond_case;PCasezk_rollup_origination_case;PCasezk_rollup_publish_case;PCasezk_rollup_update_case;]letcontents_cases=PCasepreattestation_case::PCaseattestation_case::PCasedouble_preattestation_evidence_case::PCasedouble_attestation_evidence_case::common_casesletcontents_cases_with_legacy_attestation_name=PCasepreendorsement_case::PCaseendorsement_case::PCasedouble_preendorsement_evidence_case::PCasedouble_endorsement_evidence_case::common_casesletcontents_encoding=letmake(PCase(Case{tag;name;encoding;select;proj;inj}))=assert(not@@reserved_tagtag);case(Tagtag)nameencoding(funo->matchselectowithNone->None|Someo->Some(projo))(funx->Contents(injx))indef"operation.alpha.contents"@@union(List.mapmakecontents_cases)letcontents_encoding_with_legacy_attestation_name=letmake(PCase(Case{tag;name;encoding;select;proj;inj}))=assert(not@@reserved_tagtag);case(Tagtag)nameencoding(funo->matchselectowithNone->None|Someo->Some(projo))(funx->Contents(injx))indef"operation_with_legacy_attestation_name.alpha.contents"@@union(List.mapmakecontents_cases_with_legacy_attestation_name)letcontents_list_encoding=conv_with_guardto_listof_list_internal(Variable.listcontents_encoding)letcontents_list_encoding_with_legacy_attestation_name=conv_with_guardto_listof_list_internal(Variable.listcontents_encoding_with_legacy_attestation_name)letprotocol_data_json_encoding=conv(fun(Operation_data{contents;signature})->(Contents_listcontents,signature))(fun(Contents_listcontents,signature)->Operation_data{contents;signature})(obj2(req"contents"(dynamic_sizecontents_list_encoding))(opt"signature"Signature.encoding))letprotocol_data_json_encoding_with_legacy_attestation_name=conv(fun(Operation_data{contents;signature})->(Contents_listcontents,signature))(fun(Contents_listcontents,signature)->Operation_data{contents;signature})(obj2(req"contents"(dynamic_sizecontents_list_encoding_with_legacy_attestation_name))(opt"signature"Signature.encoding))typecontents_or_signature_prefix=|Actual_contentsofpacked_contents|Signature_prefixofSignature.prefixletcontents_or_signature_prefix_encoding=letmake_contents(PCase(Case{tag;name;encoding;select;proj;inj}))=assert(not@@reserved_tagtag);case(Tagtag)nameencoding(function|Actual_contentso->(matchselectowithNone->None|Someo->Some(projo))|_->None)(funx->Actual_contents(Contents(injx)))indef"operation.alpha.contents_or_signature_prefix"@@union@@case(Tagsignature_prefix_tag)"signature_prefix"(obj1(req"signature_prefix"Signature.prefix_encoding))(functionSignature_prefixprefix->Someprefix|_->None)(funprefix->Signature_prefixprefix)(* The case signature_prefix is added to the operation's contents so that
we can store the prefix of BLS signatures without breaking the
encoding of operations. *)::List.mapmake_contentscontents_casesletof_contents_and_signature_prefixcontents_and_prefix=letopenResult_syntaxinletrecloopacc=function|[]->Okacc|Signature_prefix_::_->Error"Signature prefix must appear last"|Actual_contents(Contentso)::os->(match(o,acc)with|(Manager_operation_,Contents_list(Single(Manager_operation_)asrest))->(loop[@tailcall])(Contents_list(Cons(o,rest)))os|Manager_operation_,Contents_list(Cons_asrest)->(loop[@tailcall])(Contents_list(Cons(o,rest)))os|_->Error"Operation list of length > 1 should only contain manager \
operations.")inletrev_contents,prefix=matchList.revcontents_and_prefixwith|Signature_prefixprefix::rev_contents->(rev_contents,Someprefix)|rev_contents->(rev_contents,None)inlet+packed_contents=matchrev_contentswith|[]->Error"Operation lists should not be empty."|Signature_prefix_::_->Error"Signature prefix must appear last"|Actual_contents(Contentso)::os->loop(Contents_list(Singleo))osin(packed_contents,prefix)letprotocol_data_binary_encoding=conv_with_guard(fun(Operation_data{contents;signature})->letcontents_list=List.map(func->Actual_contentsc)@@to_list(Contents_listcontents)inletcontents_and_signature_prefix,sig_suffix=matchsignaturewith|None->(contents_list,Signature.(to_byteszero))|Somesignature->(let{Signature.prefix;suffix}=Signature.split_signaturesignatureinmatchprefixwith|None->(contents_list,suffix)|Someprefix->(contents_list@[Signature_prefixprefix],suffix))in(contents_and_signature_prefix,sig_suffix))(fun(contents_and_signature_prefix,suffix)->letopenResult_syntaxinlet*Contents_listcontents,prefix=of_contents_and_signature_prefixcontents_and_signature_prefixinlet+signature=Result.of_option~error:"Invalid signature"@@Signature.of_splitted{Signature.prefix;suffix}inletsignature=matchprefixwith|None->ifSignature.(signature=zero)thenNoneelseSomesignature|Some_->SomesignatureinOperation_data{contents;signature})(obj2(req"contents_and_signature_prefix"(Variable.listcontents_or_signature_prefix_encoding))(req"signature_suffix"(Fixed.bytesHex64)))(* The binary and JSON encodings are different for protocol data, because we
have to fit BLS signatures (which are 96 bytes long) in a backward
compatible manner with fixed size signatures of 64 bytes.
The JSON encoding is the same as in the previous protocols.
To support BLS signatures, we extract the prefix of the signature and fit
it inside the field [contents] while keeping the 64 bytes suffix in the
same place as the other signature kinds (i.e. at the end).
For instance the binary protocol data for a transfer operation signed by a
Ed25519 key would look like:
+----------------+------------+
| Transaction | signature |
+----+------+----+------------+
| 6C | ... | 00 | (64 bytes) |
+----+------+----+------------+
The same transfer signed by a BLS key would be instead:
+----------------+----------------------------+-------------------+
| Transaction | signature prefix | signature suffix |
+----+------+----+----+----+------------------+-------------------+
| 6C | ... | 00 | ff | 03 | (first 32 bytes) | (last 64 bytes) |
+----+------+----+----+----+------------------+-------------------+
Which can also be viewed with an equivalent schema:
+----------------+----+---------------+--------------------------+
| Transaction | ff | signature tag | signature |
+----+------+----+----+---------------+--------------------------+
| 6C | ... | 00 | ff | 03 (BLS) | (96 bytes BLS signature) |
+----+------+----+----+---------------+--------------------------+
NOTE: BLS only supports the tagged format and Ed25519, Secp256k1 and P256
signatures only support the untagged one. The latter restriction is only
here to guarantee unicity of the binary representation for signatures.
*)letprotocol_data_encoding=def"operation.alpha.contents_and_signature"@@splitted~json:protocol_data_json_encoding~binary:protocol_data_binary_encodingletprotocol_data_encoding_with_legacy_attestation_name=def"operation_with_legacy_attestation_name.alpha.contents_and_signature"@@splitted~json:protocol_data_json_encoding_with_legacy_attestation_name~binary:protocol_data_binary_encodingletoperation_encoding=conv(fun{shell;protocol_data}->(shell,protocol_data))(fun(shell,protocol_data)->{shell;protocol_data})(merge_objsOperation.shell_header_encodingprotocol_data_encoding)letoperation_encoding_with_legacy_attestation_name=conv(fun{shell;protocol_data}->(shell,protocol_data))(fun(shell,protocol_data)->{shell;protocol_data})(merge_objsOperation.shell_header_encodingprotocol_data_encoding_with_legacy_attestation_name)letunsigned_operation_encoding=def"operation.alpha.unsigned_operation"@@merge_objsOperation.shell_header_encoding(obj1(req"contents"contents_list_encoding))letunsigned_operation_encoding_with_legacy_attestation_name=def"operation_with_legacy_attestation_name.alpha.unsigned_operation"@@merge_objsOperation.shell_header_encoding(obj1(req"contents"contents_list_encoding_with_legacy_attestation_name))endletencoding=Encoding.operation_encodingletencoding_with_legacy_attestation_name=Encoding.operation_encoding_with_legacy_attestation_nameletcontents_encoding=Encoding.contents_encodingletcontents_encoding_with_legacy_attestation_name=Encoding.contents_encoding_with_legacy_attestation_nameletcontents_list_encoding=Encoding.contents_list_encodingletcontents_list_encoding_with_legacy_attestation_name=Encoding.contents_list_encoding_with_legacy_attestation_nameletprotocol_data_encoding=Encoding.protocol_data_encodingletprotocol_data_encoding_with_legacy_attestation_name=Encoding.protocol_data_encoding_with_legacy_attestation_nameletunsigned_operation_encoding=Encoding.unsigned_operation_encodingletunsigned_operation_encoding_with_legacy_attestation_name=Encoding.unsigned_operation_encoding_with_legacy_attestation_nameletraw({shell;protocol_data}:_operation)=letproto=Data_encoding.Binary.to_bytes_exnprotocol_data_encoding(Operation_dataprotocol_data)in{Operation.shell;proto}(** Each operation belongs to a validation pass that is an integer
abstracting its priority in a block. Except Failing_noop. *)letconsensus_pass=0letvoting_pass=1letanonymous_pass=2letmanager_pass=3(** [acceptable_pass op] returns either the validation_pass of [op]
when defines and None when [op] is [Failing_noop]. *)letacceptable_pass(op:packed_operation)=let(Operation_dataprotocol_data)=op.protocol_datainmatchprotocol_data.contentswith|Single(Failing_noop_)->None|Single(Preattestation_)->Someconsensus_pass|Single(Attestation_)->Someconsensus_pass|Single(Dal_attestation_)->Someconsensus_pass|Single(Proposals_)->Somevoting_pass|Single(Ballot_)->Somevoting_pass|Single(Seed_nonce_revelation_)->Someanonymous_pass|Single(Vdf_revelation_)->Someanonymous_pass|Single(Double_attestation_evidence_)->Someanonymous_pass|Single(Double_preattestation_evidence_)->Someanonymous_pass|Single(Double_baking_evidence_)->Someanonymous_pass|Single(Activate_account_)->Someanonymous_pass|Single(Drain_delegate_)->Someanonymous_pass|Single(Manager_operation_)->Somemanager_pass|Cons(Manager_operation_,_ops)->Somemanager_pass(** [compare_by_passes] orders two operations in the reverse order of
their acceptable passes. *)letcompare_by_passesop1op2=match(acceptable_passop1,acceptable_passop2)with|Someop1_pass,Someop2_pass->Compare.Int.compareop2_passop1_pass|None,Some_->-1|Some_,None->1|None,None->0typeerror+=Invalid_signature(* `Permanent *)typeerror+=Missing_signature(* `Permanent *)let()=register_error_kind`Permanent~id:"operation.invalid_signature"~title:"Invalid operation signature"~description:"The operation signature is ill-formed or has been made with the wrong \
public key"~pp:(funppf()->Format.fprintfppf"The operation signature is invalid")Data_encoding.unit(functionInvalid_signature->Some()|_->None)(fun()->Invalid_signature);register_error_kind`Permanent~id:"operation.missing_signature"~title:"Missing operation signature"~description:"The operation is of a kind that must be signed, but the signature is \
missing"~pp:(funppf()->Format.fprintfppf"The operation requires a signature")Data_encoding.unit(functionMissing_signature->Some()|_->None)(fun()->Missing_signature);register_error_kind`Permanent~id:"operation.contents_list_error"~title:"Invalid list of operation contents."~description:"An operation contents list has an unexpected shape; it should be either \
a single operation or a non-empty list of manager operations"~pp:(funppfs->Format.fprintfppf"An operation contents list has an unexpected shape: %s"s)Data_encoding.(obj1(req"message"(stringHex)))(functionContents_list_errors->Somes|_->None)(funs->Contents_list_errors)letserialize_unsigned_operation(typekind)({shell;protocol_data}:kindoperation):bytes=Data_encoding.Binary.to_bytes_exnunsigned_operation_encoding(shell,Contents_listprotocol_data.contents)letunsigned_operation_length(typekind)({shell;protocol_data}:kindoperation):int=Data_encoding.Binary.lengthunsigned_operation_encoding(shell,Contents_listprotocol_data.contents)letcheck_signature(typekind)keychain_id(op:kindoperation)=letserialized_operation=serialize_unsigned_operationopinletcheck~watermarksignature=ifSignature.check~watermarkkeysignatureserialized_operationthenOk()elseerrorInvalid_signatureinmatchop.protocol_data.signaturewith|None->errorMissing_signature|Somesignature->letwatermark=matchop.protocol_data.contentswith|Single(Preattestation_)->to_watermark(Preattestationchain_id)|Single(Attestation_)->to_watermark(Attestationchain_id)|Single(Dal_attestation_)->to_watermark(Dal_attestationchain_id)|Single(Failing_noop_|Proposals_|Ballot_|Seed_nonce_revelation_|Vdf_revelation_|Double_attestation_evidence_|Double_preattestation_evidence_|Double_baking_evidence_|Activate_account_|Drain_delegate_|Manager_operation_)->Generic_operation|Cons(Manager_operation_,_ops)->Generic_operationincheck~watermarksignaturelethash_raw=Operation.hashlethash(o:_operation)=letproto=Data_encoding.Binary.to_bytes_exnprotocol_data_encoding(Operation_datao.protocol_data)inOperation.hash{shell=o.shell;proto}lethash_packed(o:packed_operation)=letproto=Data_encoding.Binary.to_bytes_exnprotocol_data_encodingo.protocol_datainOperation.hash{shell=o.shell;proto}type('a,'b)eq=Eq:('a,'a)eqletequal_manager_operation_kind:typeab.amanager_operation->bmanager_operation->(a,b)eqoption=funop1op2->match(op1,op2)with|Reveal_,Reveal_->SomeEq|Reveal_,_->None|Transaction_,Transaction_->SomeEq|Transaction_,_->None|Origination_,Origination_->SomeEq|Origination_,_->None|Delegation_,Delegation_->SomeEq|Delegation_,_->None|Register_global_constant_,Register_global_constant_->SomeEq|Register_global_constant_,_->None|Increase_paid_storage_,Increase_paid_storage_->SomeEq|Increase_paid_storage_,_->None|Update_consensus_key_,Update_consensus_key_->SomeEq|Update_consensus_key_,_->None|Transfer_ticket_,Transfer_ticket_->SomeEq|Transfer_ticket_,_->None|Dal_publish_slot_header_,Dal_publish_slot_header_->SomeEq|Dal_publish_slot_header_,_->None|Sc_rollup_originate_,Sc_rollup_originate_->SomeEq|Sc_rollup_originate_,_->None|Sc_rollup_add_messages_,Sc_rollup_add_messages_->SomeEq|Sc_rollup_add_messages_,_->None|Sc_rollup_cement_,Sc_rollup_cement_->SomeEq|Sc_rollup_cement_,_->None|Sc_rollup_publish_,Sc_rollup_publish_->SomeEq|Sc_rollup_publish_,_->None|Sc_rollup_refute_,Sc_rollup_refute_->SomeEq|Sc_rollup_refute_,_->None|Sc_rollup_timeout_,Sc_rollup_timeout_->SomeEq|Sc_rollup_timeout_,_->None|Sc_rollup_execute_outbox_message_,Sc_rollup_execute_outbox_message_->SomeEq|Sc_rollup_execute_outbox_message_,_->None|Sc_rollup_recover_bond_,Sc_rollup_recover_bond_->SomeEq|Sc_rollup_recover_bond_,_->None|Zk_rollup_origination_,Zk_rollup_origination_->SomeEq|Zk_rollup_origination_,_->None|Zk_rollup_publish_,Zk_rollup_publish_->SomeEq|Zk_rollup_publish_,_->None|Zk_rollup_update_,Zk_rollup_update_->SomeEq|Zk_rollup_update_,_->Noneletequal_contents_kind:typeab.acontents->bcontents->(a,b)eqoption=funop1op2->match(op1,op2)with|Preattestation_,Preattestation_->SomeEq|Preattestation_,_->None|Attestation_,Attestation_->SomeEq|Attestation_,_->None|Dal_attestation_,Dal_attestation_->SomeEq|Dal_attestation_,_->None|Seed_nonce_revelation_,Seed_nonce_revelation_->SomeEq|Seed_nonce_revelation_,_->None|Vdf_revelation_,Vdf_revelation_->SomeEq|Vdf_revelation_,_->None|Double_attestation_evidence_,Double_attestation_evidence_->SomeEq|Double_attestation_evidence_,_->None|Double_preattestation_evidence_,Double_preattestation_evidence_->SomeEq|Double_preattestation_evidence_,_->None|Double_baking_evidence_,Double_baking_evidence_->SomeEq|Double_baking_evidence_,_->None|Activate_account_,Activate_account_->SomeEq|Activate_account_,_->None|Proposals_,Proposals_->SomeEq|Proposals_,_->None|Ballot_,Ballot_->SomeEq|Ballot_,_->None|Drain_delegate_,Drain_delegate_->SomeEq|Drain_delegate_,_->None|Failing_noop_,Failing_noop_->SomeEq|Failing_noop_,_->None|Manager_operationop1,Manager_operationop2->(matchequal_manager_operation_kindop1.operationop2.operationwith|None->None|SomeEq->SomeEq)|Manager_operation_,_->Noneletrecequal_contents_kind_list:typeab.acontents_list->bcontents_list->(a,b)eqoption=funop1op2->match(op1,op2)with|Singleop1,Singleop2->equal_contents_kindop1op2|Single_,Cons_->None|Cons_,Single_->None|Cons(op1,ops1),Cons(op2,ops2)->(matchequal_contents_kindop1op2with|None->None|SomeEq->(matchequal_contents_kind_listops1ops2with|None->None|SomeEq->SomeEq))letequal:typeab.aoperation->boperation->(a,b)eqoption=funop1op2->ifnot(Operation_hash.equal(hashop1)(hashop2))thenNoneelseequal_contents_kind_listop1.protocol_data.contentsop2.protocol_data.contents(** {2 Comparing operations} *)(** Precondition: both operations are [valid]. Hence, it is possible
to compare them without any state representation. *)(** {3 Operation passes} *)typeconsensus_pass_typetypevoting_pass_typetypeanonymous_pass_typetypemanager_pass_typetypenoop_pass_typetype_pass=|Consensus:consensus_pass_typepass|Voting:voting_pass_typepass|Anonymous:anonymous_pass_typepass|Manager:manager_pass_typepass|Noop:noop_pass_typepass(** Pass comparison. *)letcompare_inner_pass:typeab.apass->bpass->int=funpass1pass2->match(pass1,pass2)with|Consensus,(Voting|Anonymous|Manager|Noop)->1|(Voting|Anonymous|Manager|Noop),Consensus->-1|Voting,(Anonymous|Manager|Noop)->1|(Anonymous|Manager|Noop),Voting->-1|Anonymous,(Manager|Noop)->1|(Manager|Noop),Anonymous->-1|Manager,Noop->1|Noop,Manager->-1|Consensus,Consensus|Voting,Voting|Anonymous,Anonymous|Manager,Manager|Noop,Noop->0(** {3 Operation weights} *)(** [round_infos] is the pair of a [level] convert into {!int32} and
[round] convert into an {!int}.
By convention, if the [round] is from an operation round that
failed to convert in a {!int}, the value of [round] is (-1). *)typeround_infos={level:int32;round:int}(** [attestation_infos] is the pair of a {!round_infos} and a [slot]
convert into an {!int}. *)typeattestation_infos={round:round_infos;slot:int}(** [double_baking_infos] is the pair of a {!round_infos} and a
{!block_header} hash. *)typedouble_baking_infos={round:round_infos;bh_hash:Block_hash.t}(** Compute a {!round_infos} from a {consensus_content} of a valid
operation. Hence, the [round] must convert in {!int}.
Precondition: [c] comes from a valid operation. The [round] from a
valid operation should succeed to convert in {!int}. Hence, for the
unreachable path where the convertion failed, we put (-1) as
[round] value. *)letround_infos_from_consensus_content(c:consensus_content)=letlevel=Raw_level_repr.to_int32c.levelinmatchRound_repr.to_intc.roundwith|Okround->{level;round}|Error_->{level;round=-1}(** Compute a {!attestation_infos} from a {!consensus_content}. It is
used to compute the weight of {!Attestation} and {!Preattestation}.
Precondition: [c] comes from a valid operation. The {!Attestation}
or {!Preattestation} is valid, so its [round] must succeed to
convert into an {!int}. Hence, for the unreachable path where the
convertion fails, we put (-1) as [round] value (see
{!round_infos_from_consensus_content}). *)letattestation_infos_from_consensus_content(c:consensus_content)=letslot=Slot_repr.to_intc.slotinletround=round_infos_from_consensus_contentcin{round;slot}(** Compute a {!double_baking_infos} and a {!Block_header_repr.hash}
from a {!Block_header_repr.t}. It is used to compute the weight of
a {!Double_baking_evidence}.
Precondition: [bh] comes from a valid operation. The
{!Double_baking_envidence} is valid, so its fitness from its first
denounced block header must succeed, and the round from this
fitness must convert in a {!int}. Hence, for the unreachable paths
where either the convertion fails or the fitness is not
retrievable, we put (-1) as [round] value. *)letconsensus_infos_and_hash_from_block_header(bh:Block_header_repr.t)=letlevel=bh.shell.levelinletbh_hash=Block_header_repr.hashbhinletround=matchFitness_repr.from_rawbh.shell.fitnesswith|Okbh_fitness->(matchRound_repr.to_int(Fitness_repr.roundbh_fitness)with|Okround->{level;round}|Error_->{level;round=-1})|Error_->{level;round=-1}in{round;bh_hash}(** The weight of an operation.
Given an operation, its [weight] carries on static information that
is used to compare it to an operation of the same pass.
Operation weight are defined by validation pass.
The [weight] of an {!Attestation} or {!Preattestation} depends on
its {!attestation_infos}.
The [weight] of a {!Dal_attestation} depends on the pair of
the size of its bitset, {!Dal_attestation_repr.t}, and the
signature of its attestor {! Signature.Public_key_hash.t}.
The [weight] of a voting operation depends on the pair of its
[period] and [source].
The [weight] of a {!Vdf_revelation} depends on its [solution].
The [weight] of a {!Seed_nonce_revelation} depends on its [level]
converted in {!int32}.
The [weight] of a {!Double_preattestation} or
{!Double_attestation} depends on the [level] and [round] of their
first denounciated operations. The [level] and [round] are wrapped
in a {!round_infos}.
The [weight] of a {!Double_baking} depends on the [level], [round]
and [hash] of its first denounciated block_header. the [level] and
[round] are wrapped in a {!double_baking_infos}.
The [weight] of an {!Activate_account} depends on its public key
hash.
The [weight] of an {!Drain_delegate} depends on the public key
hash of the delegate.
The [weight] of {!Manager_operation} depends on its [fee] and
[gas_limit] ratio expressed in {!Q.t}. *)type_weight=|Weight_attestation:attestation_infos->consensus_pass_typeweight|Weight_preattestation:attestation_infos->consensus_pass_typeweight|Weight_dal_attestation:(* attestor * num_attestations * level *)(Signature.Public_key_hash.t*int*int32)->consensus_pass_typeweight|Weight_proposals:int32*Signature.Public_key_hash.t->voting_pass_typeweight|Weight_ballot:int32*Signature.Public_key_hash.t->voting_pass_typeweight|Weight_seed_nonce_revelation:int32->anonymous_pass_typeweight|Weight_vdf_revelation:Seed_repr.vdf_solution->anonymous_pass_typeweight|Weight_double_preattestation:round_infos->anonymous_pass_typeweight|Weight_double_attestation:round_infos->anonymous_pass_typeweight|Weight_double_baking:double_baking_infos->anonymous_pass_typeweight|Weight_activate_account:Ed25519.Public_key_hash.t->anonymous_pass_typeweight|Weight_drain_delegate:Signature.Public_key_hash.t->anonymous_pass_typeweight|Weight_manager:Q.t*Signature.public_key_hash->manager_pass_typeweight|Weight_noop:noop_pass_typeweight(** The weight of an operation is the pair of its pass and weight. *)typeoperation_weight=W:'passpass*'passweight->operation_weight(** The {!weight} of a batch of {!Manager_operation} depends on the
sum of all [fee] and the sum of all [gas_limit].
Precondition: [op] is a valid manager operation: its sum
of accumulated [fee] must succeed. Hence, in the unreachable path where
the [fee] sum fails, we put [Tez_repr.zero] as its value. *)letcumulate_fee_and_gas_of_manager:typekind.kindKind.managercontents_list->Tez_repr.t*Gas_limit_repr.Arith.integral=funop->letadd_without_erroraccy=matchTez_repr.(acc+?y)with|Okv->v|Error_->(* This cannot happen *)accinletrecloop:typekind.'a->'b->kindKind.managercontents_list->'a*'b=funfees_accgas_limit_acc->function|Single(Manager_operation{fee;gas_limit;_})->lettotal_fees=add_without_errorfees_accfeeinlettotal_gas_limit=Gas_limit_repr.Arith.addgas_limit_accgas_limitin(total_fees,total_gas_limit)|Cons(Manager_operation{fee;gas_limit;_},manops)->letfees_acc=add_without_errorfees_accfeeinletgas_limit_acc=Gas_limit_repr.Arith.addgas_limitgas_limit_accinloopfees_accgas_limit_accmanopsinloopTez_repr.zeroGas_limit_repr.Arith.zeroop(** The {!weight} of a {!Manager_operation} as well as a batch of
operations is the ratio in {!int64} between its [fee] and
[gas_limit] as computed by
{!cumulate_fee_and_gas_of_manager} converted in {!Q.t}.
We assume that the manager operation valid, thus its gas limit can
never be zero. We treat this case the same as gas_limit = 1 for the
sake of simplicity.
*)letweight_manager:typekind.kindKind.managercontents_list->Q.t*Signature.public_key_hash=funop->letfee,glimit=cumulate_fee_and_gas_of_manageropinletsource=matchopwith|Cons(Manager_operation{source;_},_)->source|Single(Manager_operation{source;_})->sourceinletfee_f=Q.of_int64(Tez_repr.to_mutezfee)inifGas_limit_repr.Arith.(glimit=Gas_limit_repr.Arith.zero)then(fee_f,source)elseletgas_f=Q.of_bigint(Gas_limit_repr.Arith.integral_to_zglimit)in(Q.(fee_f/gas_f),source)(** Computing the {!operation_weight} of an operation. [weight_of
(Failing_noop _)] is unreachable, for completness we define a
Weight_noop which carrries no information. *)letweight_of:packed_operation->operation_weight=funop->let(Operation_dataprotocol_data)=op.protocol_datainmatchprotocol_data.contentswith|Single(Failing_noop_)->W(Noop,Weight_noop)|Single(Preattestationconsensus_content)->W(Consensus,Weight_preattestation(attestation_infos_from_consensus_contentconsensus_content))|Single(Attestationconsensus_content)->W(Consensus,Weight_attestation(attestation_infos_from_consensus_contentconsensus_content))|Single(Dal_attestationDal_attestation_repr.{attestor;attestation;level})->W(Consensus,Weight_dal_attestation(attestor,Dal_attestation_repr.occupied_size_in_bitsattestation,Raw_level_repr.to_int32level))|Single(Proposals{period;source;_})->W(Voting,Weight_proposals(period,source))|Single(Ballot{period;source;_})->W(Voting,Weight_ballot(period,source))|Single(Seed_nonce_revelation{level;_})->W(Anonymous,Weight_seed_nonce_revelation(Raw_level_repr.to_int32level))|Single(Vdf_revelation{solution})->W(Anonymous,Weight_vdf_revelationsolution)|Single(Double_attestation_evidence{op1;_})->(matchop1.protocol_data.contentswith|Single(Attestationconsensus_content)->W(Anonymous,Weight_double_attestation(round_infos_from_consensus_contentconsensus_content)))|Single(Double_preattestation_evidence{op1;_})->(matchop1.protocol_data.contentswith|Single(Preattestationconsensus_content)->W(Anonymous,Weight_double_preattestation(round_infos_from_consensus_contentconsensus_content)))|Single(Double_baking_evidence{bh1;_})->letdouble_baking_infos=consensus_infos_and_hash_from_block_headerbh1inW(Anonymous,Weight_double_bakingdouble_baking_infos)|Single(Activate_account{id;_})->W(Anonymous,Weight_activate_accountid)|Single(Drain_delegate{delegate;_})->W(Anonymous,Weight_drain_delegatedelegate)|Single(Manager_operation_)asops->letmanweight,src=weight_manageropsinW(Manager,Weight_manager(manweight,src))|Cons(Manager_operation_,_)asops->letmanweight,src=weight_manageropsinW(Manager,Weight_manager(manweight,src))(** {3 Comparisons of operations {!weight}} *)(** {4 Helpers} *)(** compare a pair of elements in lexicographic order. *)letcompare_pair_in_lexico_order~cmp_fst~cmp_snd(a1,b1)(a2,b2)=letresa=cmp_fsta1a2inifCompare.Int.(resa<>0)thenresaelsecmp_sndb1b2(** compare in reverse order. *)letcompare_reverse(cmp:'a->'a->int)ab=cmpba(** {4 Comparison of {!consensus_infos}} *)(** Two {!round_infos} compares as the pair of [level, round] in
lexicographic order: the one with the greater [level] being the
greater [round_infos]. When levels are the same, the one with the
greater [round] being the better.
The greater {!round_infos} is the farther to the current state
when part of the weight of a valid consensus operation.
The best {!round_infos} is the nearer to the current state when
part of the weight of a valid denunciation.
In both case, that is the greater according to the lexicographic
order.
Precondition: the {!round_infos} are from valid operation. They
have been computed by either {!round_infos_from_consensus_content}
or {!consensus_infos_and_hash_from_block_header}. Both input
parameter from valid operations and put (-1) to the [round] in the
unreachable path where the original round fails to convert in
{!int}. *)letcompare_round_infosinfos1infos2=compare_pair_in_lexico_order~cmp_fst:Compare.Int32.compare~cmp_snd:Compare.Int.compare(infos1.level,infos1.round)(infos2.level,infos2.round)(** When comparing {!Attestation} to {!Preattestation} or
{!Double_attestation_evidence} to {!Double_preattestation}, in case
of {!round_infos} equality, the position is relevant to compute the
order. *)typeprioritized_position=Nopos|Fstpos|Sndpos(** Comparison of two {!round_infos} with priority in case of
{!round_infos} equality. *)letcompare_round_infos_with_prioritized_position~prioritized_positioninfos1infos2=letcmp=compare_round_infosinfos1infos2inifCompare.Int.(cmp<>0)thencmpelsematchprioritized_positionwithFstpos->1|Sndpos->-1|Nopos->0(** When comparing consensus operation with {!attestation_infos}, in
case of equality of their {!round_infos}, either they are of the
same kind and their [slot] have to be compared in the reverse
order, otherwise the {!Attestation} is better and
[prioritized_position] gives its position. *)letcompare_prioritized_position_or_slot~prioritized_position=matchprioritized_positionwith|Nopos->compare_reverseCompare.Int.compare|Fstpos->fun__->1|Sndpos->fun__->-1(** Two {!attestation_infos} are compared by their {!round_infos}.
When their {!round_infos} are equal, they are compared according to
their priority or their [slot], see
{!compare_prioritized_position_or_slot} for more details. *)letcompare_attestation_infos~prioritized_position(infos1:attestation_infos)(infos2:attestation_infos)=compare_pair_in_lexico_order~cmp_fst:compare_round_infos~cmp_snd:(compare_prioritized_position_or_slot~prioritized_position)(infos1.round,infos1.slot)(infos2.round,infos2.slot)(** Two {!double_baking_infos} are compared as their {!round_infos}.
When their {!round_infos} are equal, they are compared as the
hashes of their first denounced block header. *)letcompare_baking_infosinfos1infos2=compare_pair_in_lexico_order~cmp_fst:compare_round_infos~cmp_snd:Block_hash.compare(infos1.round,infos1.bh_hash)(infos2.round,infos2.bh_hash)(** Two valid {!Dal_attestation} are compared in the
lexicographic order of their pairs of bitsets size and attestor
hash. *)letcompare_dal_attestation(attestor1,attestations1,level1)(attestor2,attestations2,level2)=compare_pair_in_lexico_order~cmp_fst:(compare_pair_in_lexico_order~cmp_fst:Compare.Int32.compare~cmp_snd:Compare.Int.compare)~cmp_snd:Signature.Public_key_hash.compare((level1,attestations1),attestor1)((level2,attestations2),attestor2)(** {4 Comparison of valid operations of the same validation pass} *)(** {5 Comparison of valid consensus operations} *)(** Comparing consensus operations by their [weight] uses the
comparison on {!attestation_infos} for {!Attestation} and
{!Preattestation}: see {!attestation_infos} for more details.
{!Dal_attestation} is smaller than the other kinds of
consensus operations. Two valid {!Dal_attestation} are
compared by {!compare_dal_attestation}. *)letcompare_consensus_weightw1w2=match(w1,w2)with|Weight_attestationinfos1,Weight_attestationinfos2->compare_attestation_infos~prioritized_position:Noposinfos1infos2|Weight_preattestationinfos1,Weight_preattestationinfos2->compare_attestation_infos~prioritized_position:Noposinfos1infos2|Weight_attestationinfos1,Weight_preattestationinfos2->compare_attestation_infos~prioritized_position:Fstposinfos1infos2|Weight_preattestationinfos1,Weight_attestationinfos2->compare_attestation_infos~prioritized_position:Sndposinfos1infos2|(Weight_dal_attestation(attestor1,size1,lvl1),Weight_dal_attestation(attestor2,size2,lvl2))->compare_dal_attestation(attestor1,size1,lvl1)(attestor2,size2,lvl2)|Weight_dal_attestation_,(Weight_attestation_|Weight_preattestation_)->-1|(Weight_attestation_|Weight_preattestation_),Weight_dal_attestation_->1(** {5 Comparison of valid voting operations} *)(** Two valid voting operations of the same kind are compared in the
lexicographic order of their pair of [period] and [source]. When
compared to each other, the {!Proposals} is better. *)letcompare_vote_weightw1w2=letcmpi1source1i2source2=compare_pair_in_lexico_order(i1,source1)(i2,source2)~cmp_fst:Compare.Int32.compare~cmp_snd:Signature.Public_key_hash.compareinmatch(w1,w2)with|Weight_proposals(i1,source1),Weight_proposals(i2,source2)->cmpi1source1i2source2|Weight_ballot(i1,source1),Weight_ballot(i2,source2)->cmpi1source1i2source2|Weight_ballot_,Weight_proposals_->-1|Weight_proposals_,Weight_ballot_->1(** {5 Comparison of valid anonymous operations} *)(** Comparing two {!Double_attestation_evidence}, or two
{!Double_preattestation_evidence}, or comparing them to each other
is comparing their {!round_infos}, see {!compare_round_infos} for
more details.
Comparing two {!Double_baking_evidence} is comparing as their
{!double_baking_infos}, see {!compare_double_baking_infos} for more
details.
Two {!Seed_nonce_revelation} are compared by their [level].
Two {!Vdf_revelation} are compared by their [solution].
Two {!Activate_account} are compared as their [id].
When comparing different kind of anonymous operations, the order is
as follows: {!Double_preattestation_evidence} >
{!Double_attestation_evidence} > {!Double_baking_evidence} >
{!Vdf_revelation} > {!Seed_nonce_revelation} > {!Activate_account}.
*)letcompare_anonymous_weightw1w2=match(w1,w2)with|Weight_double_preattestationinfos1,Weight_double_preattestationinfos2->compare_round_infosinfos1infos2|Weight_double_preattestationinfos1,Weight_double_attestationinfos2->compare_round_infos_with_prioritized_position~prioritized_position:Fstposinfos1infos2|Weight_double_attestationinfos1,Weight_double_preattestationinfos2->compare_round_infos_with_prioritized_position~prioritized_position:Sndposinfos1infos2|Weight_double_attestationinfos1,Weight_double_attestationinfos2->compare_round_infosinfos1infos2|((Weight_double_baking_|Weight_seed_nonce_revelation_|Weight_vdf_revelation_|Weight_activate_account_|Weight_drain_delegate_),(Weight_double_preattestation_|Weight_double_attestation_))->-1|((Weight_double_preattestation_|Weight_double_attestation_),(Weight_double_baking_|Weight_seed_nonce_revelation_|Weight_vdf_revelation_|Weight_activate_account_|Weight_drain_delegate_))->1|Weight_double_bakinginfos1,Weight_double_bakinginfos2->compare_baking_infosinfos1infos2|((Weight_seed_nonce_revelation_|Weight_vdf_revelation_|Weight_activate_account_|Weight_drain_delegate_),Weight_double_baking_)->-1|(Weight_double_baking_,(Weight_seed_nonce_revelation_|Weight_vdf_revelation_|Weight_activate_account_|Weight_drain_delegate_))->1|Weight_vdf_revelationsolution1,Weight_vdf_revelationsolution2->Seed_repr.compare_vdf_solutionsolution1solution2|((Weight_seed_nonce_revelation_|Weight_activate_account_|Weight_drain_delegate_),Weight_vdf_revelation_)->-1|(Weight_vdf_revelation_,(Weight_seed_nonce_revelation_|Weight_activate_account_|Weight_drain_delegate_))->1|Weight_seed_nonce_revelationl1,Weight_seed_nonce_revelationl2->Compare.Int32.comparel1l2|((Weight_activate_account_|Weight_drain_delegate_),Weight_seed_nonce_revelation_)->-1|(Weight_seed_nonce_revelation_,(Weight_activate_account_|Weight_drain_delegate_))->1|Weight_activate_accountpkh1,Weight_activate_accountpkh2->Ed25519.Public_key_hash.comparepkh1pkh2|Weight_drain_delegate_,Weight_activate_account_->-1|Weight_activate_account_,Weight_drain_delegate_->1|Weight_drain_delegatepkh1,Weight_drain_delegatepkh2->Signature.Public_key_hash.comparepkh1pkh2(** {5 Comparison of valid {!Manager_operation}} *)(** Two {!Manager_operation} are compared in the lexicographic order
of their pair of their [fee]/[gas] ratio -- as computed by
{!weight_manager} -- and their [source]. *)letcompare_manager_weightweight1weight2=match(weight1,weight2)with|Weight_manager(manweight1,source1),Weight_manager(manweight2,source2)->compare_pair_in_lexico_order(manweight1,source1)(manweight2,source2)~cmp_fst:Compare.Q.compare~cmp_snd:Signature.Public_key_hash.compare(** Two {!operation_weight} are compared by their [pass], see
{!compare_inner_pass} for more details. When they have the same
[pass], they are compared by their [weight]. *)letcompare_operation_weightw1w2=match(w1,w2)with|W(Consensus,w1),W(Consensus,w2)->compare_consensus_weightw1w2|W(Voting,w1),W(Voting,w2)->compare_vote_weightw1w2|W(Anonymous,w1),W(Anonymous,w2)->compare_anonymous_weightw1w2|W(Manager,w1),W(Manager,w2)->compare_manager_weightw1w2|W(pass1,_),W(pass2,_)->compare_inner_passpass1pass2(** {3 Compare two valid operations} *)(** Two valid operations are compared as their {!operation_weight},
see {!compare_operation_weight} for more details.
When they are equal according to their {!operation_weight} comparison, they
compare as their hash.
Hence, [compare] returns [0] only when the hashes of both operations are
equal.
Preconditions: [oph1] is the hash of [op1]; [oph2] the one of [op2]; and
[op1] and [op2] are both valid. *)letcompare(oph1,op1)(oph2,op2)=letcmp_h=Operation_hash.(compareoph1oph2)inifCompare.Int.(cmp_h=0)then0elseletcmp=compare_operation_weight(weight_ofop1)(weight_ofop2)inifCompare.Int.(cmp=0)thencmp_helsecmpmoduleInternal_for_benchmarking=structletserialize_unsigned_operation=serialize_unsigned_operationend