123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149(*****************************************************************************)(* *)(* Open Source License *)(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)(* *)(* Permission is hereby granted, free of charge, to any person obtaining a *)(* copy of this software and associated documentation files (the "Software"),*)(* to deal in the Software without restriction, including without limitation *)(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *)(* and/or sell copies of the Software, and to permit persons to whom the *)(* Software is furnished to do so, subject to the following conditions: *)(* *)(* The above copyright notice and this permission notice shall be included *)(* in all copies or substantial portions of the Software. *)(* *)(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *)(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *)(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *)(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *)(* DEALINGS IN THE SOFTWARE. *)(* *)(*****************************************************************************)(* Tezos Protocol Implementation - Low level Repr. of Operations *)moduleKind=structtypepreendorsement_consensus_kind=Preendorsement_consensus_kindtypeendorsement_consensus_kind=Endorsement_consensus_kindtype'aconsensus=|Preendorsement_kind:preendorsement_consensus_kindconsensus|Endorsement_kind:endorsement_consensus_kindconsensustypepreendorsement=preendorsement_consensus_kindconsensustypeendorsement=endorsement_consensus_kindconsensustypeseed_nonce_revelation=Seed_nonce_revelation_kindtype'adouble_consensus_operation_evidence=|Double_consensus_operation_evidencetypedouble_endorsement_evidence=endorsement_consensus_kinddouble_consensus_operation_evidencetypedouble_preendorsement_evidence=preendorsement_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_kindtypeset_deposits_limit=Set_deposits_limit_kindtypefailing_noop=Failing_noop_kindtyperegister_global_constant=Register_global_constant_kindtype'amanager=|Reveal_manager_kind:revealmanager|Transaction_manager_kind:transactionmanager|Origination_manager_kind:originationmanager|Delegation_manager_kind:delegationmanager|Register_global_constant_manager_kind:register_global_constantmanager|Set_deposits_limit_manager_kind:set_deposits_limitmanagerendtype'aconsensus_operation_type=|Endorsement:Kind.endorsementconsensus_operation_type|Preendorsement:Kind.preendorsementconsensus_operation_typeletpp_operation_kind(typekind)ppf(operation_kind:kindconsensus_operation_type)=matchoperation_kindwith|Endorsement->Format.fprintfppf"Endorsement"|Preendorsement->Format.fprintfppf"Preendorsement"typeconsensus_content={slot:Slot_repr.t;level:Raw_level_repr.t;(* The level is not required to validate an endorsement when it corresponds
to the current payload, but if we want to filter endorsements, 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=|EndorsementofChain_id.t|PreendorsementofChain_id.tletbytes_of_consensus_watermark=function|Preendorsementchain_id->Bytes.cat(Bytes.of_string"\x12")(Chain_id.to_byteschain_id)|Endorsementchain_id->Bytes.cat(Bytes.of_string"\x13")(Chain_id.to_byteschain_id)letto_watermarkw=Signature.Custom(bytes_of_consensus_watermarkw)letof_watermark=function|Signature.Customb->ifCompare.Int.(Bytes.lengthb>0)thenmatchBytes.getb0with|'\x12'->Option.map(funchain_id->Endorsementchain_id)(Chain_id.of_bytes_opt(Bytes.subb1(Bytes.lengthb-1)))|'\x13'->Option.map(funchain_id->Preendorsementchain_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=|Preendorsement:consensus_content->Kind.preendorsementcontents|Endorsement:consensus_content->Kind.endorsementcontents|Seed_nonce_revelation:{level:Raw_level_repr.t;nonce:Seed_repr.nonce;}->Kind.seed_nonce_revelationcontents|Double_preendorsement_evidence:{op1:Kind.preendorsementoperation;op2:Kind.preendorsementoperation;}->Kind.double_preendorsement_evidencecontents|Double_endorsement_evidence:{op1:Kind.endorsementoperation;op2:Kind.endorsementoperation;}->Kind.double_endorsement_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|Failing_noop:string->Kind.failing_noopcontents|Manager_operation:{source:Signature.public_key_hash;fee:Tez_repr.tez;counter:counter;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:string;destination:Contract_repr.contract;}->Kind.transactionmanager_operation|Origination:{delegate:Signature.Public_key_hash.toption;script:Script_repr.t;credit:Tez_repr.tez;preorigination:Contract_repr.toption;}->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|Set_deposits_limit:Tez_repr.toption->Kind.set_deposits_limitmanager_operationandcounter=Z.tletmanager_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|Set_deposits_limit_->Kind.Set_deposits_limit_manager_kindtype'kindinternal_operation={source:Contract_repr.contract;operation:'kindmanager_operation;nonce:int;}typepacked_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}typepacked_internal_operation=|Internal_operation:'kindinternal_operation->packed_internal_operationletrecto_list=function|Contents_list(Singleo)->[Contentso]|Contents_list(Cons(o,os))->Contentso::to_list(Contents_listos)(* 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. *)letrecof_list_internal=function|[]->Error"Operation lists should not be empty."|[Contentso]->Ok(Contents_list(Singleo))|Contentso::os->(of_list_internalos>>?fun(Contents_listos)->match(o,os)with|(Manager_operation_,Single(Manager_operation_))->Ok(Contents_list(Cons(o,os)))|(Manager_operation_,Cons_)->Ok(Contents_list(Cons(o,os)))|_->Error"Operation list of length > 1 should only contains manager \
operations.")typeerror+=Contents_list_errorofstring(* `Permanent *)letof_listl=matchof_list_internallwith|Okcontents->Okcontents|Errors->error@@Contents_list_errorsmoduleEncoding=structopenData_encodingletcasetagnameargsprojinj=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;}->'kindcase[@@coq_force_gadt]let[@coq_axiom_with_reason"gadt"]reveal_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);}letentrypoint_encoding=def~title:"entrypoint"~description:"Named entrypoint to a Michelson smart contract""entrypoint"@@letbuiltin_casetagname=Data_encoding.case(Tagtag)~title:name(constantname)(funn->ifCompare.String.(n=name)thenSome()elseNone)(fun()->name)inunion[builtin_case0"default";builtin_case1"root";builtin_case2"do";builtin_case3"set_delegate";builtin_case4"remove_delegate";Data_encoding.case(Tag255)~title:"named"(Bounded.string31)(funs->Somes)(funs->s);]let[@coq_axiom_with_reason"gadt"]transaction_case=MCase{tag=1;name="transaction";encoding=obj3(req"amount"Tez_repr.encoding)(req"destination"Contract_repr.encoding)(opt"parameters"(obj2(req"entrypoint"entrypoint_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&&Compare.String.(entrypoint="default")thenNoneelseSome(entrypoint,parameters)in(amount,destination,parameters));inj=(fun(amount,destination,parameters)->let(entrypoint,parameters)=matchparameterswith|None->("default",Script_repr.unit_parameter)|Some(entrypoint,value)->(entrypoint,value)inTransaction{amount;destination;parameters;entrypoint});}let[@coq_axiom_with_reason"gadt"]origination_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;preorigination=_(* the hash is only used internally
when originating from smart
contracts, don't serialize it *);}->(credit,delegate,script));inj=(fun(credit,delegate,script)->Origination{credit;delegate;script;preorigination=None});}let[@coq_axiom_with_reason"gadt"]delegation_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);}let[@coq_axiom_with_reason"gadt"]register_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});}let[@coq_axiom_with_reason"gadt"]set_deposits_limit_case=MCase{tag=5;name="set_deposits_limit";encoding=obj1(opt"limit"Tez_repr.encoding);select=(function|Manager(Set_deposits_limit_asop)->Someop|_->None);proj=(functionSet_deposits_limitkey->key);inj=(funkey->Set_deposits_limitkey);}letencoding=letmake(MCase{tag;name;encoding;select;proj;inj})=case(Tagtag)nameencoding(funo->matchselectowithNone->None|Someo->Some(projo))(funx->Manager(injx))inunion~tag_size:`Uint8[makereveal_case;maketransaction_case;makeorigination_case;makedelegation_case;makeregister_global_constant_case;makeset_deposits_limit_case;]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;(* Preendorsement where added after *)name="preendorsement";encoding=consensus_content_encoding;select=(functionContents(Preendorsement_asop)->Someop|_->None);proj=(fun(Preendorsementpreendorsement)->preendorsement);inj=(funpreendorsement->Preendorsementpreendorsement);}(* Defined before endorsement encoding because this is used there *)letpreendorsement_encoding=letmake(Case{tag;name;encoding;select=_;proj;inj})=case(Tagtag)nameencoding(funo->Some(projo))(funx->injx)inletto_list:Kind.preendorsementcontents_list->_=function|Singleo->oinletof_list:Kind.preendorsementcontents->_=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)))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(Endorsement_asop)->Someop|_->None);proj=(fun[@coq_match_with_default](Endorsementconsensus_content)->(consensus_content.slot,consensus_content.level,consensus_content.round,consensus_content.block_payload_hash));inj=(fun(slot,level,round,block_payload_hash)->Endorsement{slot;level;round;block_payload_hash});}let[@coq_axiom_with_reason"gadt"]endorsement_encoding=letmake(Case{tag;name;encoding;select=_;proj;inj})=case(Tagtag)nameencoding(funo->Some(projo))(funx->injx)inletto_list:Kind.endorsementcontents_list->_=fun(Singleo)->oinletof_list:Kind.endorsementcontents->_=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)))let[@coq_axiom_with_reason"gadt"]seed_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});}let[@coq_axiom_with_reason"gadt"]double_preendorsement_evidence_case:Kind.double_preendorsement_evidencecase=Case{tag=7;name="double_preendorsement_evidence";encoding=obj2(req"op1"(dynamic_sizepreendorsement_encoding))(req"op2"(dynamic_sizepreendorsement_encoding));select=(function|Contents(Double_preendorsement_evidence_asop)->Someop|_->None);proj=(fun(Double_preendorsement_evidence{op1;op2})->(op1,op2));inj=(fun(op1,op2)->Double_preendorsement_evidence{op1;op2});}let[@coq_axiom_with_reason"gadt"]double_endorsement_evidence_case:Kind.double_endorsement_evidencecase=Case{tag=2;name="double_endorsement_evidence";encoding=obj2(req"op1"(dynamic_sizeendorsement_encoding))(req"op2"(dynamic_sizeendorsement_encoding));select=(function|Contents(Double_endorsement_evidence_asop)->Someop|_->None);proj=(fun(Double_endorsement_evidence{op1;op2})->(op1,op2));inj=(fun(op1,op2)->Double_endorsement_evidence{op1;op2});}let[@coq_axiom_with_reason"gadt"]double_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});}let[@coq_axiom_with_reason"gadt"]activate_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});}let[@coq_axiom_with_reason"gadt"]proposals_case=Case{tag=5;name="proposals";encoding=obj3(req"source"Signature.Public_key_hash.encoding)(req"period"int32)(req"proposals"(listProtocol_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});}let[@coq_axiom_with_reason"gadt"]ballot_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});}letfailing_noop_case=Case{tag=17;name="failing_noop";encoding=obj1(req"arbitrary"Data_encoding.string);select=(functionContents(Failing_noop_asop)->Someop|_->None);proj=(function[@coq_match_with_default]Failing_noopmessage->message);inj=(functionmessage->Failing_noopmessage);}letmanager_encoding=obj5(req"source"Signature.Public_key_hash.encoding)(req"fee"Tez_repr.encoding)(req"counter"(check_size10n))(req"gas_limit"(check_size10Gas_limit_repr.Arith.n_integral_encoding))(req"storage_limit"(check_size10n))letextract:typekind.kindKind.managercontents->_=function[@coq_match_with_default]|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}let[@coq_axiom_with_reason"gadt"]make_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_caseletset_deposits_limit_case=make_manager_case112Manager_operations.set_deposits_limit_caseletcontents_encoding=letmake(Case{tag;name;encoding;select;proj;inj})=case(Tagtag)nameencoding(funo->matchselectowithNone->None|Someo->Some(projo))(funx->Contents(injx))indef"operation.alpha.contents"@@union[makeendorsement_case;makepreendorsement_case;makeseed_nonce_revelation_case;makedouble_endorsement_evidence_case;makedouble_preendorsement_evidence_case;makedouble_baking_evidence_case;makeactivate_account_case;makeproposals_case;makeballot_case;makereveal_case;maketransaction_case;makeorigination_case;makedelegation_case;makeset_deposits_limit_case;makefailing_noop_case;makeregister_global_constant_case;]letcontents_list_encoding=conv_with_guardto_listof_list_internal(Variable.listcontents_encoding)letoptional_signature_encoding=conv(functionSomes->s|None->Signature.zero)(funs->ifSignature.equalsSignature.zerothenNoneelseSomes)Signature.encodingletprotocol_data_encoding=def"operation.alpha.contents_and_signature"@@conv(fun(Operation_data{contents;signature})->(Contents_listcontents,signature))(fun(Contents_listcontents,signature)->Operation_data{contents;signature})(obj2(req"contents"contents_list_encoding)(req"signature"optional_signature_encoding))letoperation_encoding=conv(fun{shell;protocol_data}->(shell,protocol_data))(fun(shell,protocol_data)->{shell;protocol_data})(merge_objsOperation.shell_header_encodingprotocol_data_encoding)letunsigned_operation_encoding=def"operation.alpha.unsigned_operation"@@merge_objsOperation.shell_header_encoding(obj1(req"contents"contents_list_encoding))letinternal_operation_encoding=def"operation.alpha.internal_operation"@@conv(fun(Internal_operation{source;operation;nonce})->((source,nonce),Manageroperation))(fun((source,nonce),Manageroperation)->Internal_operation{source;operation;nonce})(merge_objs(obj2(req"source"Contract_repr.encoding)(req"nonce"uint16))Manager_operations.encoding)endletencoding=Encoding.operation_encodingletcontents_encoding=Encoding.contents_encodingletcontents_list_encoding=Encoding.contents_list_encodingletprotocol_data_encoding=Encoding.protocol_data_encodingletunsigned_operation_encoding=Encoding.unsigned_operation_encodingletinternal_operation_encoding=Encoding.internal_operation_encodingletraw({shell;protocol_data}:_operation)=letproto=Data_encoding.Binary.to_bytes_exnprotocol_data_encoding(Operation_dataprotocol_data)in{Operation.shell;proto}letacceptable_passes(op:packed_operation)=let(Operation_dataprotocol_data)=op.protocol_datainmatchprotocol_data.contentswith|Single(Failing_noop_)->[]|Single(Preendorsement_)->[0]|Single(Endorsement_)->[0]|Single(Proposals_)->[1]|Single(Ballot_)->[1]|Single(Seed_nonce_revelation_)->[2]|Single(Double_endorsement_evidence_)->[2]|Single(Double_preendorsement_evidence_)->[2]|Single(Double_baking_evidence_)->[2]|Single(Activate_account_)->[2]|Single(Manager_operation_)->[3]|Cons(Manager_operation_,_ops)->[3]typeerror+=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"string))(functionContents_list_errors->Somes|_->None)(funs->Contents_list_errors)letcheck_signature(typekind)keychain_id({shell;protocol_data}:kindoperation)=letcheck~watermarkcontentssignature=letunsigned_operation=Data_encoding.Binary.to_bytes_exnunsigned_operation_encoding(shell,contents)inifSignature.check~watermarkkeysignatureunsigned_operationthenOk()elseerrorInvalid_signatureinmatchprotocol_data.signaturewith|None->errorMissing_signature|Somesignature->(matchprotocol_data.contentswith|Single(Preendorsement_)ascontents->check~watermark:(to_watermark(Preendorsementchain_id))(Contents_listcontents)signature|Single(Endorsement_)ascontents->check~watermark:(to_watermark(Endorsementchain_id))(Contents_listcontents)signature|Single(Failing_noop_|Proposals_|Ballot_|Seed_nonce_revelation_|Double_endorsement_evidence_|Double_preendorsement_evidence_|Double_baking_evidence_|Activate_account_|Manager_operation_)->check~watermark:Generic_operation(Contents_listprotocol_data.contents)signature|Cons(Manager_operation_,_ops)->check~watermark:Generic_operation(Contents_listprotocol_data.contents)signature)lethash_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)eq[@@coq_force_gadt]letequal_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|(Set_deposits_limit_,Set_deposits_limit_)->SomeEq|(Set_deposits_limit_,_)->Noneletequal_contents_kind:typeab.acontents->bcontents->(a,b)eqoption=funop1op2->match(op1,op2)with|(Preendorsement_,Preendorsement_)->SomeEq|(Preendorsement_,_)->None|(Endorsement_,Endorsement_)->SomeEq|(Endorsement_,_)->None|(Seed_nonce_revelation_,Seed_nonce_revelation_)->SomeEq|(Seed_nonce_revelation_,_)->None|(Double_endorsement_evidence_,Double_endorsement_evidence_)->SomeEq|(Double_endorsement_evidence_,_)->None|(Double_preendorsement_evidence_,Double_preendorsement_evidence_)->SomeEq|(Double_preendorsement_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|(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.contentsopenCache_memory_helpersletscript_lazy_expr_size(expr:Script_repr.lazy_expr)=letfun_valueexpr=ret_adding(expr_sizeexpr)word_sizeinletfun_bytesbytes=(Nodes.zero,word_size+!bytes_sizebytes)inletfun_combineexpr_sizebytes_size=expr_size++bytes_sizeinret_adding(Data_encoding.apply_lazy~fun_value~fun_bytes~fun_combineexpr)header_sizeletscript_repr_size({code;storage}:Script_repr.t)=ret_adding(script_lazy_expr_sizecode++script_lazy_expr_sizestorage)h2wletinternal_manager_operation_size(typea)(op:amanager_operation)=matchopwith|Transaction{amount=_;parameters;entrypoint;destination}->ret_adding(script_lazy_expr_sizeparameters)(h4w+!int64_size+!string_size_gen(String.lengthentrypoint)+!Contract_repr.in_memory_sizedestination)|Origination{delegate;script;credit=_;preorigination}->ret_adding(script_repr_sizescript)(h4w+!option_size(fun_->Contract_repr.public_key_hash_in_memory_size)delegate+!int64_size+!option_sizeContract_repr.in_memory_sizepreorigination)|Delegationpkh_opt->(Nodes.zero,h1w+!option_size(fun_->Contract_repr.public_key_hash_in_memory_size)pkh_opt)|Reveal_->(* Reveals can't occur as internal operations *)assertfalse|Register_global_constant_->(* Global constant registrations can't occur as internal operations *)assertfalse|Set_deposits_limit_->(* Set_deposits_limit can't occur as internal operations *)assertfalseletpacked_internal_operation_in_memory_size:packed_internal_operation->nodes_and_size=function|Internal_operationiop->let{source;operation;nonce=_}=iopinletsource_size=Contract_repr.in_memory_sizesourceinletnonce_size=word_sizeinret_adding(internal_manager_operation_sizeoperation)(h2w+!source_size+!nonce_size)