Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file delegate_services.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648(*****************************************************************************)(* *)(* Open Source License *)(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)(* Copyright (c) 2020 Metastate AG <hello@metastate.dev> *)(* Copyright (c) 2021 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. *)(* *)(*****************************************************************************)openAlpha_contexttypeerror+=Balance_rpc_non_delegateofpublic_key_hashtypeerror+=(* `Temporary *)Not_registeredofSignature.Public_key_hash.tlet()=register_error_kind`Temporary~id:"delegate.not_registered"~title:"Not a registered delegate"~description:"The provided public key hash is not the address of a registered \
delegate."~pp:(funppfpkh->Format.fprintfppf"The provided public key hash (%a) is not the address of a registered \
delegate. If you own this account and want to register it as a \
delegate, use a delegation operation to delegate the account to \
itself."Signature.Public_key_hash.pppkh)Data_encoding.(obj1(req"pkh"Signature.Public_key_hash.encoding))(functionNot_registeredpkh->Somepkh|_->None)(funpkh->Not_registeredpkh)let()=register_error_kind`Temporary~id:"delegate_service.balance_rpc_on_non_delegate"~title:"Balance request for an unregistered delegate"~description:"The account whose balance was requested is not a delegate."~pp:(funppfpkh->Format.fprintfppf"The implicit account (%a) whose balance was requested is not a \
registered delegate. To get the balance of this account you can use \
the ../context/contracts/%a/balance RPC."Signature.Public_key_hash.pppkhSignature.Public_key_hash.pppkh)Data_encoding.(obj1(req"pkh"Signature.Public_key_hash.encoding))(functionBalance_rpc_non_delegatepkh->Somepkh|_->None)(funpkh->Balance_rpc_non_delegatepkh)typeconsensus_key={consensus_key_pkh:Signature.Public_key_hash.t;consensus_key_pk:Signature.Public_key.t;}letconsensus_key_encoding=letopenData_encodinginconv(fun{consensus_key_pkh;consensus_key_pk}->(consensus_key_pkh,consensus_key_pk))(fun(consensus_key_pkh,consensus_key_pk)->{consensus_key_pkh;consensus_key_pk})(obj2(req"pkh"Signature.Public_key_hash.encoding)(req"pk"Signature.Public_key.encoding))typeconsensus_keys_info={active:consensus_key;pendings:(Cycle.t*consensus_key)list;}letconsensus_key_info_encoding=letopenData_encodinginconv(fun{active;pendings}->(active,pendings))(fun(active,pendings)->{active;pendings})(obj2(req"active"consensus_key_encoding)(dft"pendings"(list(merge_objs(obj1(req"cycle"Cycle.encoding))consensus_key_encoding))[]))letparticipation_info_encoding=letopenData_encodinginconv(funDelegate.For_RPC.{expected_cycle_activity;minimal_cycle_activity;missed_slots;missed_levels;remaining_allowed_missed_slots;expected_attesting_rewards;}->(expected_cycle_activity,minimal_cycle_activity,missed_slots,missed_levels,remaining_allowed_missed_slots,expected_attesting_rewards))(fun(expected_cycle_activity,minimal_cycle_activity,missed_slots,missed_levels,remaining_allowed_missed_slots,expected_attesting_rewards)->{expected_cycle_activity;minimal_cycle_activity;missed_slots;missed_levels;remaining_allowed_missed_slots;expected_attesting_rewards;})(obj6(req"expected_cycle_activity"int31)(req"minimal_cycle_activity"int31)(req"missed_slots"int31)(req"missed_levels"int31)(req"remaining_allowed_missed_slots"int31)(req"expected_attesting_rewards"Tez.encoding))typedeposit_per_cycle={cycle:Cycle.t;deposit:Tez.t}letdeposit_per_cycle_encoding:deposit_per_cycleData_encoding.t=letopenData_encodinginconv(fun{cycle;deposit}->(cycle,deposit))(fun(cycle,deposit)->{cycle;deposit})(obj2(req"cycle"Cycle.encoding)(req"deposit"Tez.encoding))typepending_staking_parameters=Cycle.t*Staking_parameters_repr.tletpending_staking_parameters_encoding:pending_staking_parametersData_encoding.t=letopenData_encodinginobj2(req"cycle"Cycle.encoding)(req"parameters"Staking_parameters_repr.encoding)moduleS=structletraw_path=RPC_path.(open_root/"context"/"delegates")openData_encodingtypelist_query={active:bool;inactive:bool;with_minimal_stake:bool;without_minimal_stake:bool;}letlist_query:list_queryRPC_query.t=letopenRPC_queryinquery(funactiveinactivewith_minimal_stakewithout_minimal_stake->{active;inactive;with_minimal_stake;without_minimal_stake})|+flag"active"(funt->t.active)|+flag"inactive"(funt->t.inactive)|+flag"with_minimal_stake"(funt->t.with_minimal_stake)|+flag"without_minimal_stake"(funt->t.without_minimal_stake)|>sealletlist_delegate=RPC_service.get_service~description:"Lists all registered delegates by default. The arguments `active`, \
`inactive`, `with_minimal_stake`, and `without_minimal_stake` allow \
to enumerate only the delegates that are active, inactive, have at \
least a minimal stake to participate in consensus and in governance, \
or do not have such a minimal stake, respectively. Note, setting \
these arguments to false has no effect."~query:list_query~output:(listSignature.Public_key_hash.encoding)raw_pathletpath=RPC_path.(raw_path/:Signature.Public_key_hash.rpc_arg)letfull_balance=RPC_service.get_service~description:"Returns the full balance (in mutez) of a given delegate, including \
the frozen deposits and the frozen bonds. It does not include its \
delegated balance."~query:RPC_query.empty~output:Tez.encodingRPC_path.(path/"full_balance")letcurrent_frozen_deposits=RPC_service.get_service~description:"Returns the current amount of the frozen deposits (in mutez). That is \
the frozen deposits at beginning of cycle plus rewards minus unstaked \
and slashing. It doesn't count unstaked frozen deposits."~query:RPC_query.empty~output:Tez.encodingRPC_path.(path/"current_frozen_deposits")letfrozen_deposits=RPC_service.get_service~description:"Returns the amount (in mutez) frozen as a deposit at the time the \
staking rights for the current cycle were computed."~query:RPC_query.empty~output:Tez.encodingRPC_path.(path/"frozen_deposits")letunstaked_frozen_deposits=RPC_service.get_service~description:"Returns, for each cycle, the sum of unstaked-but-frozen deposits for \
this cycle. Cycles go from the last unslashable cycle to the current \
cycle."~query:RPC_query.empty~output:(Data_encoding.listdeposit_per_cycle_encoding)RPC_path.(path/"unstaked_frozen_deposits")letstaking_balance=RPC_service.get_service~description:"Returns the total amount of tokens (in mutez) delegated to a given \
delegate. This includes the balances of all the contracts that \
delegate to it, but also the balance of the delegate itself, its \
frozen deposits, and its frozen bonds."~query:RPC_query.empty~output:Tez.encodingRPC_path.(path/"staking_balance")letfrozen_deposits_limit=RPC_service.get_service~description:"Returns the frozen deposits limit for the given delegate or none if \
no limit is set."~query:RPC_query.empty~output:(Data_encoding.optionTez.encoding)RPC_path.(path/"frozen_deposits_limit")letdelegated_contracts=RPC_service.get_service~description:"Returns the list of contracts that delegate to a given delegate."~query:RPC_query.empty~output:(listContract.encoding)RPC_path.(path/"delegated_contracts")lettotal_delegated_stake=RPC_service.get_service~description:"Returns the sum (in mutez) of all tokens staked by the delegators of \
a given delegate. This excludes the delegate's own staked tokens."~query:RPC_query.empty~output:Tez.encodingRPC_path.(path/"total_delegated_stake")letstaking_denominator=RPC_service.get_service~description:"Returns an abstract representation of the total delegated stake."~query:RPC_query.empty~output:Staking_pseudotoken.For_RPC.encodingRPC_path.(path/"staking_denominator")letdeactivated=RPC_service.get_service~description:"Tells whether the delegate is currently tagged as deactivated or not."~query:RPC_query.empty~output:boolRPC_path.(path/"deactivated")letgrace_period=RPC_service.get_service~description:"Returns the cycle by the end of which the delegate might be \
deactivated if she fails to execute any delegate action. A \
deactivated delegate might be reactivated (without loosing any stake) \
by simply re-registering as a delegate. For deactivated delegates, \
this value contains the cycle at which they were deactivated."~query:RPC_query.empty~output:Cycle.encodingRPC_path.(path/"grace_period")letcurrent_voting_power=RPC_service.get_service~description:"The voting power of a given delegate, as computed from its current \
stake."~query:RPC_query.empty~output:Data_encoding.int64RPC_path.(path/"current_voting_power")letvoting_power=RPC_service.get_service~description:"The voting power in the vote listings for a given delegate."~query:RPC_query.empty~output:Data_encoding.int64RPC_path.(path/"voting_power")letcurrent_baking_power=RPC_service.get_service~description:"The baking power of a delegate, as computed from its current stake. \
This value is not used for computing baking rights but only reflects \
the baking power that the delegate would have if the cycle ended at \
the current block."~query:RPC_query.empty~output:Data_encoding.int64RPC_path.(path/"current_baking_power")letvoting_info=RPC_service.get_service~description:"Returns the delegate info (e.g. voting power) found in the listings \
of the current voting period."~query:RPC_query.empty~output:Vote.delegate_info_encodingRPC_path.(path/"voting_info")letconsensus_key=RPC_service.get_service~description:"The active consensus key for a given delegate and the pending \
consensus keys."~query:RPC_query.empty~output:consensus_key_info_encodingRPC_path.(path/"consensus_key")letparticipation=RPC_service.get_service~description:"Returns cycle and level participation information. In particular this \
indicates, in the field 'expected_cycle_activity', the number of \
slots the delegate is expected to have in the cycle based on its \
active stake. The field 'minimal_cycle_activity' indicates the \
minimal attesting slots in the cycle required to get attesting \
rewards. It is computed based on 'expected_cycle_activity. The fields \
'missed_slots' and 'missed_levels' indicate the number of missed \
attesting slots and missed levels (for attesting) in the cycle so \
far. 'missed_slots' indicates the number of missed attesting slots in \
the cycle so far. The field 'remaining_allowed_missed_slots' \
indicates the remaining amount of attesting slots that can be missed \
in the cycle before forfeiting the rewards. Finally, \
'expected_attesting_rewards' indicates the attesting rewards that \
will be distributed at the end of the cycle if activity at that point \
will be greater than the minimal required; if the activity is already \
known to be below the required minimum, then the rewards are zero."~query:RPC_query.empty~output:participation_info_encodingRPC_path.(path/"participation")letactive_staking_parameters=RPC_service.get_service~description:"Returns the currently active staking parameters for the given \
delegate."~query:RPC_query.empty~output:Staking_parameters_repr.encodingRPC_path.(path/"active_staking_parameters")letpending_staking_parameters=RPC_service.get_service~description:"Returns the pending values for the given delegate's staking \
parameters."~query:RPC_query.empty~output:(listpending_staking_parameters_encoding)RPC_path.(path/"pending_staking_parameters")letpending_denunciations=RPC_service.get_service~description:"Returns the pending denunciations for the given delegate."~query:RPC_query.empty~output:(listDenunciations_repr.item_encoding)RPC_path.(path/"denunciations")letestimated_shared_pending_slashed_amount=RPC_service.get_service~description:"Returns the estimated shared pending slashed amount (in mutez) of a \
given delegate."~query:RPC_query.empty~output:Tez.encodingRPC_path.(path/"estimated_shared_pending_slashed_amount")endletcheck_delegate_registeredctxtpkh=letopenLwt_result_syntaxinlet*!is_registered=Delegate.registeredctxtpkhinmatchis_registeredwith|true->return_unit|false->tzfail(Not_registeredpkh)letregister()=letopenServices_registrationinletopenLwt_result_syntaxinregister0~chunked:trueS.list_delegate(functxtq()->let*!delegates=Delegate.listctxtinlet*delegates=matchqwith|{active=true;inactive=false;_}->List.filter_es(funpkh->let+deactivated=Delegate.deactivatedctxtpkhinnotdeactivated)delegates|{active=false;inactive=true;_}->List.filter_es(funpkh->Delegate.deactivatedctxtpkh)delegates|{active=false;inactive=false;_}(* This case is counter-intuitive, but it represents the default behavior, when no arguments are given *)|{active=true;inactive=true;_}->returndelegatesinletminimal_stake=Constants.minimal_stakectxtinmatchqwith|{with_minimal_stake=true;without_minimal_stake=false;_}->List.filter_es(funpkh->let+staking_balance=Delegate.For_RPC.staking_balancectxtpkhinTez.(staking_balance>=minimal_stake))delegates|{with_minimal_stake=false;without_minimal_stake=true;_}->List.filter_es(funpkh->let+staking_balance=Delegate.For_RPC.staking_balancectxtpkhinTez.(staking_balance<minimal_stake))delegates|{with_minimal_stake=true;without_minimal_stake=true;_}|{with_minimal_stake=false;without_minimal_stake=false;_}->returndelegates);register1~chunked:falseS.full_balance(functxtpkh()()->let*()=trace(Balance_rpc_non_delegatepkh)(check_delegate_registeredctxtpkh)inDelegate.For_RPC.full_balancectxtpkh);register1~chunked:falseS.current_frozen_deposits(functxtpkh()()->let*()=check_delegate_registeredctxtpkhinDelegate.current_frozen_depositsctxtpkh);register1~chunked:falseS.frozen_deposits(functxtpkh()()->let*()=check_delegate_registeredctxtpkhinDelegate.initial_frozen_depositsctxtpkh);register1~chunked:falseS.unstaked_frozen_deposits(functxtpkh()()->let*()=check_delegate_registeredctxtpkhinletctxt_cycle=(Alpha_context.Level.currentctxt).cycleinletlast_unslashable_cycle=Option.value~default:Cycle.root@@Cycle.subctxt_cycle(Constants.slashable_deposits_periodctxt+Constants_repr.max_slashing_period)inletcycles=Cycle.(last_unslashable_cycle--->ctxt_cycle)inlet*requests=List.map_es(funcycle->let*deposit=Unstaked_frozen_deposits.balancectxtpkhcycleinreturn(cycle,deposit))cyclesinlet*slashed_requests=Alpha_context.Unstake_requests.For_RPC.apply_slash_to_unstaked_unfinalizablectxt~delegate:pkh~requestsinList.map_es(fun(cycle,deposit)->return{cycle;deposit})slashed_requests);register1~chunked:falseS.staking_balance(functxtpkh()()->let*()=check_delegate_registeredctxtpkhinDelegate.For_RPC.staking_balancectxtpkh);register1~chunked:falseS.frozen_deposits_limit(functxtpkh()()->let*()=check_delegate_registeredctxtpkhinDelegate.frozen_deposits_limitctxtpkh);register1~chunked:trueS.delegated_contracts(functxtpkh()()->let*()=check_delegate_registeredctxtpkhinlet*!contracts=Delegate.delegated_contractsctxtpkhinreturncontracts);register1~chunked:falseS.total_delegated_stake(functxtpkh()()->let*()=check_delegate_registeredctxtpkhinStaking_pseudotokens.For_RPC.get_frozen_deposits_staked_tezctxt~delegate:pkh);register1~chunked:falseS.staking_denominator(functxtpkh()()->let*()=check_delegate_registeredctxtpkhinStaking_pseudotokens.For_RPC.get_frozen_deposits_pseudotokensctxt~delegate:pkh);register1~chunked:falseS.deactivated(functxtpkh()()->let*()=check_delegate_registeredctxtpkhinDelegate.deactivatedctxtpkh);register1~chunked:falseS.grace_period(functxtpkh()()->let*()=check_delegate_registeredctxtpkhinDelegate.last_cycle_before_deactivationctxtpkh);register1~chunked:falseS.current_voting_power(functxtpkh()()->let*()=check_delegate_registeredctxtpkhinVote.get_current_voting_power_freectxtpkh);register1~chunked:falseS.voting_power(functxtpkh()()->let*()=check_delegate_registeredctxtpkhinVote.get_voting_power_freectxtpkh);register1~chunked:falseS.current_baking_power(functxtpkh()()->let*()=check_delegate_registeredctxtpkhinStake_distribution.For_RPC.delegate_current_baking_powerctxtpkh);register1~chunked:falseS.voting_info(functxtpkh()()->let*()=check_delegate_registeredctxtpkhinVote.get_delegate_infoctxtpkh);register1~chunked:falseS.consensus_key(functxtpkh()()->let*{consensus_pk=consensus_key_pk;consensus_pkh=consensus_key_pkh;_;}=Delegate.Consensus_key.active_pubkeyctxtpkhinlet*pendings=Delegate.Consensus_key.pending_updatesctxtpkhinletpendings=List.map(fun(cycle,consensus_key_pkh,consensus_key_pk)->(cycle,{consensus_key_pk;consensus_key_pkh}))pendingsinreturn{active={consensus_key_pk;consensus_key_pkh};pendings});register1~chunked:falseS.participation(functxtpkh()()->let*()=check_delegate_registeredctxtpkhinDelegate.For_RPC.participation_infoctxtpkh);register1~chunked:falseS.active_staking_parameters(functxtpkh()()->Delegate.Staking_parameters.of_delegatectxtpkh);register1~chunked:falseS.pending_staking_parameters(functxtpkh()()->Delegate.Staking_parameters.pending_updatesctxtpkh);register1~chunked:falseS.pending_denunciations(functxtpkh()()->Delegate.For_RPC.pending_denunciationsctxtpkh);register1~chunked:falseS.estimated_shared_pending_slashed_amount(functxtdelegate()()->let*()=check_delegate_registeredctxtdelegateinDelegate.For_RPC.get_estimated_shared_pending_slashed_amountctxtdelegate)letlistctxtblock?(active=true)?(inactive=false)?(with_minimal_stake=true)?(without_minimal_stake=false)()=RPC_context.make_call0S.list_delegatectxtblock{active;inactive;with_minimal_stake;without_minimal_stake}()letfull_balancectxtblockpkh=RPC_context.make_call1S.full_balancectxtblockpkh()()letcurrent_frozen_depositsctxtblockpkh=RPC_context.make_call1S.current_frozen_depositsctxtblockpkh()()letfrozen_depositsctxtblockpkh=RPC_context.make_call1S.frozen_depositsctxtblockpkh()()letunstaked_frozen_depositsctxtblockpkh=RPC_context.make_call1S.unstaked_frozen_depositsctxtblockpkh()()letstaking_balancectxtblockpkh=RPC_context.make_call1S.staking_balancectxtblockpkh()()letfrozen_deposits_limitctxtblockpkh=RPC_context.make_call1S.frozen_deposits_limitctxtblockpkh()()letdelegated_contractsctxtblockpkh=RPC_context.make_call1S.delegated_contractsctxtblockpkh()()lettotal_delegated_stakectxtblockpkh=RPC_context.make_call1S.total_delegated_stakectxtblockpkh()()letstaking_denominatorctxtblockpkh=RPC_context.make_call1S.staking_denominatorctxtblockpkh()()letdeactivatedctxtblockpkh=RPC_context.make_call1S.deactivatedctxtblockpkh()()letgrace_periodctxtblockpkh=RPC_context.make_call1S.grace_periodctxtblockpkh()()letvoting_powerctxtblockpkh=RPC_context.make_call1S.voting_powerctxtblockpkh()()letcurrent_voting_powerctxtblockpkh=RPC_context.make_call1S.current_voting_powerctxtblockpkh()()letcurrent_baking_powerctxtblockpkh=RPC_context.make_call1S.current_baking_powerctxtblockpkh()()letvoting_infoctxtblockpkh=RPC_context.make_call1S.voting_infoctxtblockpkh()()letconsensus_keyctxtblockpkh=RPC_context.make_call1S.consensus_keyctxtblockpkh()()letparticipationctxtblockpkh=RPC_context.make_call1S.participationctxtblockpkh()()letactive_staking_parametersctxtblockpkh=RPC_context.make_call1S.active_staking_parametersctxtblockpkh()()letpending_staking_parametersctxtblockpkh=RPC_context.make_call1S.pending_staking_parametersctxtblockpkh()()letpending_denunciationsctxtblockpkh=RPC_context.make_call1S.pending_denunciationsctxtblockpkh()()letestimated_shared_pending_slashed_amountctxtblockpkh=RPC_context.make_call1S.estimated_shared_pending_slashed_amountctxtblockpkh()()