123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686(*****************************************************************************)(* *)(* Open Source License *)(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)(* Copyright (c) 2020 Metastate AG <hello@metastate.dev> *)(* *)(* 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. *)(* *)(*****************************************************************************)moduleToken=structtype'tokent=|Tez:Tez_repr.tt|Staking_pseudotoken:Staking_pseudotoken_repr.ttleteq:typetoken1token2.token1t->token2t->(token1,token2)Equality_witness.eqoption=funt1t2->match(t1,t2)with|Tez,Tez->SomeRefl|Tez,_|_,Tez->None|Staking_pseudotoken,Staking_pseudotoken->SomeReflletequal:typetoken.tokent->token->token->bool=function|Tez->Tez_repr.(=)|Staking_pseudotoken->Staking_pseudotoken_repr.(=)letis_zero:typetoken.tokent->token->bool=funtokent->matchtokenwith|Tez->Tez_repr.(t=zero)|Staking_pseudotoken->Staking_pseudotoken_repr.(t=zero)letle:typetoken.tokent->token->token->bool=function|Tez->Tez_repr.(<=)|Staking_pseudotoken->Staking_pseudotoken_repr.(<=)letadd:typetoken.tokent->token->token->tokentzresult=function|Tez->Tez_repr.(+?)|Staking_pseudotoken->Staking_pseudotoken_repr.(+?)letsub:typetoken.tokent->token->token->tokentzresult=function|Tez->Tez_repr.(-?)|Staking_pseudotoken->Staking_pseudotoken_repr.(-?)letpp_tez=lettez_sym="\xEA\x9C\xA9"infunppftez->Format.fprintfppf"%s%a"tez_symTez_repr.pptezletpp:typetoken.tokent->Format.formatter->token->unit=function|Tez->pp_tez|Staking_pseudotoken->Staking_pseudotoken_repr.ppendtype'tokenbalance=|Contract:Contract_repr.t->Tez_repr.tbalance|Block_fees:Tez_repr.tbalance|Deposits:Frozen_staker_repr.t->Tez_repr.tbalance|Unstaked_deposits:Unstaked_frozen_staker_repr.t*Cycle_repr.t->Tez_repr.tbalance|Nonce_revelation_rewards:Tez_repr.tbalance|Attesting_rewards:Tez_repr.tbalance|Baking_rewards:Tez_repr.tbalance|Baking_bonuses:Tez_repr.tbalance|Storage_fees:Tez_repr.tbalance|Double_signing_punishments:Tez_repr.tbalance|Lost_attesting_rewards:Signature.Public_key_hash.t*bool*bool->Tez_repr.tbalance|Liquidity_baking_subsidies:Tez_repr.tbalance|Burned:Tez_repr.tbalance|Commitments:Blinded_public_key_hash.t->Tez_repr.tbalance|Bootstrap:Tez_repr.tbalance|Invoice:Tez_repr.tbalance|Initial_commitments:Tez_repr.tbalance|Minted:Tez_repr.tbalance|Frozen_bonds:Contract_repr.t*Bond_id_repr.t->Tez_repr.tbalance|Sc_rollup_refutation_punishments:Tez_repr.tbalance|Sc_rollup_refutation_rewards:Tez_repr.tbalance|Staking_delegator_numerator:{delegator:Contract_repr.t;}->Staking_pseudotoken_repr.tbalance|Staking_delegate_denominator:{delegate:Signature.public_key_hash;}->Staking_pseudotoken_repr.tbalancelettoken_of_balance:typetoken.tokenbalance->tokenToken.t=function|Contract_->Token.Tez|Block_fees->Token.Tez|Deposits_->Token.Tez|Unstaked_deposits_->Token.Tez|Nonce_revelation_rewards->Token.Tez|Attesting_rewards->Token.Tez|Baking_rewards->Token.Tez|Baking_bonuses->Token.Tez|Storage_fees->Token.Tez|Double_signing_punishments->Token.Tez|Lost_attesting_rewards_->Token.Tez|Liquidity_baking_subsidies->Token.Tez|Burned->Token.Tez|Commitments_->Token.Tez|Bootstrap->Token.Tez|Invoice->Token.Tez|Initial_commitments->Token.Tez|Minted->Token.Tez|Frozen_bonds_->Token.Tez|Sc_rollup_refutation_punishments->Token.Tez|Sc_rollup_refutation_rewards->Token.Tez|Staking_delegator_numerator_->Token.Staking_pseudotoken|Staking_delegate_denominator_->Token.Staking_pseudotokenletis_not_zeroc=not(Compare.Int.equalc0)letcompare_balance:typetoken1token2.token1balance->token2balance->int=funbabb->match(ba,bb)with|Contractca,Contractcb->Contract_repr.comparecacb|Depositssa,Depositssb->Frozen_staker_repr.comparesasb|Unstaked_deposits(sa,ca),Unstaked_deposits(sb,cb)->Compare.or_else(Unstaked_frozen_staker_repr.comparesasb)(fun()->Cycle_repr.comparecacb)|Lost_attesting_rewards(pkha,pa,ra),Lost_attesting_rewards(pkhb,pb,rb)->letc=Signature.Public_key_hash.comparepkhapkhbinifis_not_zerocthencelseletc=Compare.Bool.comparepapbinifis_not_zerocthencelseCompare.Bool.comparerarb|Commitmentsbpkha,Commitmentsbpkhb->Blinded_public_key_hash.comparebpkhabpkhb|Frozen_bonds(ca,ra),Frozen_bonds(cb,rb)->letc=Contract_repr.comparecacbinifis_not_zerocthencelseBond_id_repr.comparerarb|(Staking_delegator_numerator{delegator=ca},Staking_delegator_numerator{delegator=cb})->Contract_repr.comparecacb|(Staking_delegate_denominator{delegate=pkha},Staking_delegate_denominator{delegate=pkhb})->Signature.Public_key_hash.comparepkhapkhb|_,_->letindex:typetoken.tokenbalance->int=function|Contract_->0|Block_fees->1|Deposits_->2|Unstaked_deposits_->3|Nonce_revelation_rewards->4|Attesting_rewards->5|Baking_rewards->6|Baking_bonuses->7|Storage_fees->8|Double_signing_punishments->9|Lost_attesting_rewards_->10|Liquidity_baking_subsidies->11|Burned->12|Commitments_->13|Bootstrap->14|Invoice->15|Initial_commitments->16|Minted->17|Frozen_bonds_->18|Sc_rollup_refutation_punishments->19|Sc_rollup_refutation_rewards->20|Staking_delegator_numerator_->21|Staking_delegate_denominator_->22(* don't forget to add parameterized cases in the first part of the function *)inCompare.Int.compare(indexba)(indexbb)type'tokenbalance_update=Debitedof'token|Creditedof'tokentypebalance_and_update=|Ex_token:'tokenbalance*'tokenbalance_update->balance_and_updateletis_zero_update:typetoken.tokenToken.t->tokenbalance_update->bool=funtoken->functionDebitedt|Creditedt->Token.is_zerotokentletconv_balance_updateencoding=Data_encoding.conv(functionCreditedv->`Creditedv|Debitedv->`Debitedv)(function`Creditedv->Creditedv|`Debitedv->Debitedv)encodinglettez_balance_update_encoding=letopenData_encodingindef"operation_metadata.alpha.tez_balance_update"@@obj1(req"change"(conv_balance_updateTez_repr.balance_update_encoding))letstaking_pseudotoken_balance_update_encoding=letopenData_encodingindef"operation_metadata.alpha.staking_abstract_quantity"@@obj1(req"change"(conv_balance_updateStaking_pseudotoken_repr.balance_update_encoding))letbalance_and_update_encoding~use_legacy_attestation_name=letopenData_encodinginletcase=function|Tagtag->(* The tag was used by old variant. It have been removed in
protocol proposal O, it can be unblocked in the future. *)lettx_rollup_reserved_tag=[22;23]inassert(not@@List.exists(Compare.Int.equaltag)tx_rollup_reserved_tag);case(Tagtag)|_asc->casecinlettez_case~titletagenc(proj:Tez_repr.tbalance->_option)inj=case~titletag(merge_objsenctez_balance_update_encoding)(fun(Ex_token(balance,update))->matchtoken_of_balancebalancewith|Tez->projbalance|>Option.map(funx->(x,update))|_->None)(fun(x,update)->Ex_token(injx,update))inletstaking_pseudotoken_case~titletagenc(proj:Staking_pseudotoken_repr.tbalance->_option)inj=case~titletag(merge_objsencstaking_pseudotoken_balance_update_encoding)(fun(Ex_token(balance,update))->matchtoken_of_balancebalancewith|Staking_pseudotoken->projbalance|>Option.map(funx->(x,update))|_->None)(fun(x,update)->Ex_token(injx,update))indef(ifuse_legacy_attestation_namethen"operation_metadata_with_legacy_attestation_name.alpha.balance_and_update"else"operation_metadata.alpha.balance_and_update")@@union[tez_case(Tag0)~title:"Contract"(obj2(req"kind"(constant"contract"))(req"contract"Contract_repr.encoding))(functionContractc->Some((),c)|_->None)(fun((),c)->Contractc);tez_case(Tag2)~title:"Block_fees"(obj2(req"kind"(constant"accumulator"))(req"category"(constant"block fees")))(functionBlock_fees->Some((),())|_->None)(fun((),())->Block_fees);tez_case(Tag4)~title:"Deposits"(obj3(req"kind"(constant"freezer"))(req"category"(constant"deposits"))(req"staker"Frozen_staker_repr.encoding))(functionDepositsstaker->Some((),(),staker)|_->None)(fun((),(),staker)->Depositsstaker);tez_case(Tag5)~title:"Nonce_revelation_rewards"(obj2(req"kind"(constant"minted"))(req"category"(constant"nonce revelation rewards")))(functionNonce_revelation_rewards->Some((),())|_->None)(fun((),())->Nonce_revelation_rewards);(* 6 was for Double_signing_evidence_rewards that has been removed.
https://gitlab.com/tezos/tezos/-/merge_requests/7758 *)tez_case(Tag7)~title:(ifuse_legacy_attestation_namethen"Endorsing_rewards"else"Attesting_rewards")(obj2(req"kind"(constant"minted"))(req"category"(constant(ifuse_legacy_attestation_namethen"endorsing rewards"else"attesting rewards"))))(functionAttesting_rewards->Some((),())|_->None)(fun((),())->Attesting_rewards);tez_case(Tag8)~title:"Baking_rewards"(obj2(req"kind"(constant"minted"))(req"category"(constant"baking rewards")))(functionBaking_rewards->Some((),())|_->None)(fun((),())->Baking_rewards);tez_case(Tag9)~title:"Baking_bonuses"(obj2(req"kind"(constant"minted"))(req"category"(constant"baking bonuses")))(functionBaking_bonuses->Some((),())|_->None)(fun((),())->Baking_bonuses);tez_case(Tag11)~title:"Storage_fees"(obj2(req"kind"(constant"burned"))(req"category"(constant"storage fees")))(functionStorage_fees->Some((),())|_->None)(fun((),())->Storage_fees);tez_case(Tag12)~title:"Double_signing_punishments"(obj2(req"kind"(constant"burned"))(req"category"(constant"punishments")))(functionDouble_signing_punishments->Some((),())|_->None)(fun((),())->Double_signing_punishments);tez_case(Tag13)~title:(ifuse_legacy_attestation_namethen"Lost_endorsing_rewards"else"Lost_attesting_rewards")(obj5(req"kind"(constant"burned"))(req"category"(constant(ifuse_legacy_attestation_namethen"lost endorsing rewards"else"lost attesting rewards")))(req"delegate"Signature.Public_key_hash.encoding)(req"participation"Data_encoding.bool)(req"revelation"Data_encoding.bool))(function|Lost_attesting_rewards(d,p,r)->Some((),(),d,p,r)|_->None)(fun((),(),d,p,r)->Lost_attesting_rewards(d,p,r));tez_case(Tag14)~title:"Liquidity_baking_subsidies"(obj2(req"kind"(constant"minted"))(req"category"(constant"subsidy")))(functionLiquidity_baking_subsidies->Some((),())|_->None)(fun((),())->Liquidity_baking_subsidies);tez_case(Tag15)~title:"Burned"(obj2(req"kind"(constant"burned"))(req"category"(constant"burned")))(functionBurned->Some((),())|_->None)(fun((),())->Burned);tez_case(Tag16)~title:"Commitments"(obj3(req"kind"(constant"commitment"))(req"category"(constant"commitment"))(req"committer"Blinded_public_key_hash.encoding))(functionCommitmentsbpkh->Some((),(),bpkh)|_->None)(fun((),(),bpkh)->Commitmentsbpkh);tez_case(Tag17)~title:"Bootstrap"(obj2(req"kind"(constant"minted"))(req"category"(constant"bootstrap")))(functionBootstrap->Some((),())|_->None)(fun((),())->Bootstrap);tez_case(Tag18)~title:"Invoice"(obj2(req"kind"(constant"minted"))(req"category"(constant"invoice")))(functionInvoice->Some((),())|_->None)(fun((),())->Invoice);tez_case(Tag19)~title:"Initial_commitments"(obj2(req"kind"(constant"minted"))(req"category"(constant"commitment")))(functionInitial_commitments->Some((),())|_->None)(fun((),())->Initial_commitments);tez_case(Tag20)~title:"Minted"(obj2(req"kind"(constant"minted"))(req"category"(constant"minted")))(functionMinted->Some((),())|_->None)(fun((),())->Minted);tez_case(Tag21)~title:"Frozen_bonds"(obj4(req"kind"(constant"freezer"))(req"category"(constant"bonds"))(req"contract"Contract_repr.encoding)(req"bond_id"Bond_id_repr.encoding))(functionFrozen_bonds(c,r)->Some((),(),c,r)|_->None)(fun((),(),c,r)->Frozen_bonds(c,r));tez_case(Tag24)~title:"Smart_rollup_refutation_punishments"(obj2(req"kind"(constant"burned"))(req"category"(constant"smart_rollup_refutation_punishments")))(function|Sc_rollup_refutation_punishments->Some((),())|_->None)(fun((),())->Sc_rollup_refutation_punishments);tez_case(Tag25)~title:"Smart_rollup_refutation_rewards"(obj2(req"kind"(constant"minted"))(req"category"(constant"smart_rollup_refutation_rewards")))(function|Sc_rollup_refutation_rewards->Some((),())|_->None)(fun((),())->Sc_rollup_refutation_rewards);tez_case(Tag26)~title:"Unstaked_deposits"(obj4(req"kind"(constant"freezer"))(req"category"(constant"unstaked_deposits"))(req"staker"Unstaked_frozen_staker_repr.encoding)(req"cycle"Cycle_repr.encoding))(function|Unstaked_deposits(staker,cycle)->Some((),(),staker,cycle)|_->None)(fun((),(),staker,cycle)->Unstaked_deposits(staker,cycle));staking_pseudotoken_case(Tag27)~title:"Staking_delegator_numerator"(obj3(req"kind"(constant"staking"))(req"category"(constant"delegator_numerator"))(req"delegator"Contract_repr.encoding))(function|Staking_delegator_numerator{delegator}->Some((),(),delegator)|_->None)(fun((),(),delegator)->Staking_delegator_numerator{delegator});staking_pseudotoken_case(Tag28)~title:"Staking_delegate_denominator"(obj3(req"kind"(constant"staking"))(req"category"(constant"delegate_denominator"))(req"delegate"Signature.Public_key_hash.encoding))(function|Staking_delegate_denominator{delegate}->Some((),(),delegate)|_->None)(fun((),(),delegate)->Staking_delegate_denominator{delegate});]letbalance_and_update_encoding_with_legacy_attestation_name=balance_and_update_encoding~use_legacy_attestation_name:trueletbalance_and_update_encoding=balance_and_update_encoding~use_legacy_attestation_name:falsetypeupdate_origin=|Block_application|Protocol_migration|Subsidy|Simulation|Delayed_operationof{operation_hash:Operation_hash.t}letcompare_update_originoaob=match(oa,ob)with|(Delayed_operation{operation_hash=oha},Delayed_operation{operation_hash=ohb})->Operation_hash.compareohaohb|_,_->letindexo=matchowith|Block_application->0|Protocol_migration->1|Subsidy->2|Simulation->3|Delayed_operation_->4(* don't forget to add parameterized cases in the first part of the function *)inCompare.Int.compare(indexoa)(indexob)letupdate_origin_encoding=letopenData_encodingindef"operation_metadata.alpha.update_origin"@@union[case(Tag0)~title:"Block_application"(obj1(req"origin"(constant"block")))(functionBlock_application->Some()|_->None)(fun()->Block_application);case(Tag1)~title:"Protocol_migration"(obj1(req"origin"(constant"migration")))(functionProtocol_migration->Some()|_->None)(fun()->Protocol_migration);case(Tag2)~title:"Subsidy"(obj1(req"origin"(constant"subsidy")))(functionSubsidy->Some()|_->None)(fun()->Subsidy);case(Tag3)~title:"Simulation"(obj1(req"origin"(constant"simulation")))(functionSimulation->Some()|_->None)(fun()->Simulation);case(Tag4)~title:"Delayed_operation"(obj2(req"origin"(constant"delayed_operation"))(req"delayed_operation_hash"Operation_hash.encoding))(function|Delayed_operation{operation_hash}->Some((),operation_hash)|_->None)(fun((),operation_hash)->Delayed_operation{operation_hash});]typebalance_update_item=|Balance_update_item:'tokenbalance*'tokenbalance_update*update_origin->balance_update_itemletitembalancebalance_updateupdate_origin=Balance_update_item(balance,balance_update,update_origin)letitem_encoding_with_legacy_attestation_name=letopenData_encodinginconv(function|Balance_update_item(balance,balance_update,update_origin)->(Ex_token(balance,balance_update),update_origin))(fun(Ex_token(balance,balance_update),update_origin)->Balance_update_item(balance,balance_update,update_origin))(merge_objsbalance_and_update_encoding_with_legacy_attestation_nameupdate_origin_encoding)letitem_encoding=letopenData_encodinginconv(function|Balance_update_item(balance,balance_update,update_origin)->(Ex_token(balance,balance_update),update_origin))(fun(Ex_token(balance,balance_update),update_origin)->Balance_update_item(balance,balance_update,update_origin))(merge_objsbalance_and_update_encodingupdate_origin_encoding)typebalance_updates=balance_update_itemlistletbalance_updates_encoding_with_legacy_attestation_name=letopenData_encodingindef"operation_metadata_with_legacy_attestation_name.alpha.balance_updates"@@listitem_encoding_with_legacy_attestation_nameletbalance_updates_encoding=letopenData_encodingindef"operation_metadata.alpha.balance_updates"@@listitem_encodingmoduleMakeBalanceMap(T:sigtypetokenend)=structincludeMap.Make(structtypet=T.tokenbalance*update_originletcompare(ba,ua)(bb,ub)=letc=compare_balancebabbinifis_not_zerocthencelsecompare_update_originuaubend)letupdate_rkey(f:'aoption->'boptiontzresult)map=letopenResult_syntaxinlet*v_opt=f(findkeymap)inmatchv_optwith|Somev->return(addkeyvmap)|None->return(removekeymap)endmoduleTezBalanceMap=MakeBalanceMap(structtypetoken=Tez_repr.tend)moduleStakingPseudotokenMap=MakeBalanceMap(structtypetoken=Staking_pseudotoken_repr.tend)type'abalance_maps={tez:Tez_repr.tbalance_updateTezBalanceMap.t;staking_pt:Staking_pseudotoken_repr.tbalance_updateStakingPseudotokenMap.t;}letgroup_balance_updatesbalance_updates=letopenResult_syntaxinletupdate_maptokenupdate_rkeyupdatemap=update_rkey(function|None->return_someupdate|Somebalance->(match(balance,update)with|Crediteda,Debitedb|Debitedb,Crediteda->(* Remove the binding since it just fell down to zero *)ifToken.equaltokenabthenreturn_noneelseifToken.letokenbathenlet*update=Token.subtokenabinreturn_some(Creditedupdate)elselet*update=Token.subtokenbainreturn_some(Debitedupdate)|Crediteda,Creditedb->let*update=Token.addtokenabinreturn_some(Creditedupdate)|Debiteda,Debitedb->let*update=Token.addtokenabinreturn_some(Debitedupdate)))mapinlet*{tez;staking_pt}=List.fold_left_e(funacc(Balance_update_item(b,update,o))->(* Do not do anything if the update is zero *)lettoken=token_of_balancebinifis_zero_updatetokenupdatethenreturnaccelsematchtokenwith|Tez->let+tez=update_maptokenTezBalanceMap.update_r(b,o)updateacc.tezin{accwithtez}|Staking_pseudotoken->let+staking_pt=update_maptokenStakingPseudotokenMap.update_r(b,o)updateacc.staking_ptin{accwithstaking_pt}){tez=TezBalanceMap.empty;staking_pt=StakingPseudotokenMap.empty}balance_updatesinreturn(StakingPseudotokenMap.fold(fun(b,o)uacc->Balance_update_item(b,u,o)::acc)staking_pt(TezBalanceMap.fold(fun(b,o)uacc->Balance_update_item(b,u,o)::acc)tez[]))