123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549(*****************************************************************************)(* *)(* 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)typeinfo={full_balance:Tez.t;current_frozen_deposits:Tez.t;frozen_deposits:Tez.t;staking_balance:Tez.t;frozen_deposits_limit:Tez.toption;delegated_contracts:Contract.tlist;delegated_balance:Tez.t;deactivated:bool;grace_period:Cycle.t;voting_info:Vote.delegate_info;active_consensus_key:Signature.Public_key_hash.t;pending_consensus_keys:(Cycle.t*Signature.Public_key_hash.t)list;}letinfo_encoding=letopenData_encodinginconv(fun{full_balance;current_frozen_deposits;frozen_deposits;staking_balance;frozen_deposits_limit;delegated_contracts;delegated_balance;deactivated;grace_period;voting_info;active_consensus_key;pending_consensus_keys;}->((full_balance,current_frozen_deposits,frozen_deposits,staking_balance,frozen_deposits_limit,delegated_contracts,delegated_balance,deactivated,grace_period),(voting_info,(active_consensus_key,pending_consensus_keys))))(fun((full_balance,current_frozen_deposits,frozen_deposits,staking_balance,frozen_deposits_limit,delegated_contracts,delegated_balance,deactivated,grace_period),(voting_info,(active_consensus_key,pending_consensus_keys)))->{full_balance;current_frozen_deposits;frozen_deposits;staking_balance;frozen_deposits_limit;delegated_contracts;delegated_balance;deactivated;grace_period;voting_info;active_consensus_key;pending_consensus_keys;})(merge_objs(obj9(req"full_balance"Tez.encoding)(req"current_frozen_deposits"Tez.encoding)(req"frozen_deposits"Tez.encoding)(req"staking_balance"Tez.encoding)(opt"frozen_deposits_limit"Tez.encoding)(req"delegated_contracts"(listContract.encoding))(req"delegated_balance"Tez.encoding)(req"deactivated"bool)(req"grace_period"Cycle.encoding))(merge_objsVote.delegate_info_encoding(obj2(req"active_consensus_key"Signature.Public_key_hash.encoding)(dft"pending_consensus_keys"(list(obj2(req"cycle"Cycle.encoding)(req"pkh"Signature.Public_key_hash.encoding)))[]))))letparticipation_info_encoding=letopenData_encodinginconv(fun{Delegate.expected_cycle_activity;minimal_cycle_activity;missed_slots;missed_levels;remaining_allowed_missed_slots;expected_endorsing_rewards;}->(expected_cycle_activity,minimal_cycle_activity,missed_slots,missed_levels,remaining_allowed_missed_slots,expected_endorsing_rewards))(fun(expected_cycle_activity,minimal_cycle_activity,missed_slots,missed_levels,remaining_allowed_missed_slots,expected_endorsing_rewards)->{expected_cycle_activity;minimal_cycle_activity;missed_slots;missed_levels;remaining_allowed_missed_slots;expected_endorsing_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_endorsing_rewards"Tez.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)letinfo=RPC_service.get_service~description:"Everything about a delegate."~query:RPC_query.empty~output:info_encodingpathletfull_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)."~query:RPC_query.empty~output:Tez.encodingRPC_path.(path/"current_frozen_deposits")letfrozen_deposits=RPC_service.get_service~description:"Returns the initial amount (that is, at the beginning of a cycle) of \
the frozen deposits (in mutez). This amount is the same as the \
current amount of the frozen deposits, unless the delegate has been \
punished."~query:RPC_query.empty~output:Tez.encodingRPC_path.(path/"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")letdelegated_balance=RPC_service.get_service~description:"Returns the sum (in mutez) of all balances of all the contracts that \
delegate to a given delegate. This excludes the delegate's own \
balance, its frozen deposits and its frozen bonds."~query:RPC_query.empty~output:Tez.encodingRPC_path.(path/"delegated_balance")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")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")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:Data_encoding.(obj2(req"active"Signature.Public_key_hash.encoding)(dft"pendings"(list(obj2(req"cycle"Cycle.encoding)(req"pkh"Signature.Public_key_hash.encoding)))[]))RPC_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 endorsing slots in the cycle required to get endorsing \
rewards. It is computed based on 'expected_cycle_activity. The fields \
'missed_slots' and 'missed_levels' indicate the number of missed \
endorsing slots and missed levels (for endorsing) in the cycle so \
far. 'missed_slots' indicates the number of missed endorsing slots in \
the cycle so far. The field 'remaining_allowed_missed_slots' \
indicates the remaining amount of endorsing slots that can be missed \
in the cycle before forfeiting the rewards. Finally, \
'expected_endorsing_rewards' indicates the endorsing 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")endletcheck_delegate_registeredctxtpkh=Delegate.registeredctxtpkh>>=function|true->return_unit|false->tzfail(Not_registeredpkh)letregister()=letopenServices_registrationinregister0~chunked:trueS.list_delegate(functxtq()->Delegate.listctxt>>=fundelegates->(matchqwith|{active=true;inactive=false;_}->List.filter_es(funpkh->Delegate.deactivatedctxtpkh>|=?not)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;_}->returndelegates)>>=?fundelegates->letminimal_stake=Constants.minimal_stakectxtinmatchqwith|{with_minimal_stake=true;without_minimal_stake=false;_}->List.filter_es(funpkh->Delegate.staking_balancectxtpkh>|=?funstaking_balance->Tez.(staking_balance>=minimal_stake))delegates|{with_minimal_stake=false;without_minimal_stake=true;_}->List.filter_es(funpkh->Delegate.staking_balancectxtpkh>|=?funstaking_balance->Tez.(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.info(functxtpkh()()->check_delegate_registeredctxtpkh>>=?fun()->Delegate.full_balancectxtpkh>>=?funfull_balance->Delegate.frozen_depositsctxtpkh>>=?funfrozen_deposits->Delegate.staking_balancectxtpkh>>=?funstaking_balance->Delegate.frozen_deposits_limitctxtpkh>>=?funfrozen_deposits_limit->Delegate.delegated_contractsctxtpkh>>=fundelegated_contracts->Delegate.delegated_balancectxtpkh>>=?fundelegated_balance->Delegate.deactivatedctxtpkh>>=?fundeactivated->Delegate.last_cycle_before_deactivationctxtpkh>>=?fungrace_period->Vote.get_delegate_infoctxtpkh>>=?funvoting_info->Delegate.Consensus_key.active_pubkeyctxtpkh>>=?funconsensus_key->Delegate.Consensus_key.pending_updatesctxtpkh>|=?funpendings->{full_balance;current_frozen_deposits=frozen_deposits.current_amount;frozen_deposits=frozen_deposits.initial_amount;staking_balance;frozen_deposits_limit;delegated_contracts;delegated_balance;deactivated;grace_period;voting_info;active_consensus_key=consensus_key.consensus_pkh;pending_consensus_keys=pendings;});register1~chunked:falseS.full_balance(functxtpkh()()->trace(Balance_rpc_non_delegatepkh)(check_delegate_registeredctxtpkh)>>=?fun()->Delegate.full_balancectxtpkh);register1~chunked:falseS.current_frozen_deposits(functxtpkh()()->check_delegate_registeredctxtpkh>>=?fun()->Delegate.frozen_depositsctxtpkh>>=?fundeposits->returndeposits.current_amount);register1~chunked:falseS.frozen_deposits(functxtpkh()()->check_delegate_registeredctxtpkh>>=?fun()->Delegate.frozen_depositsctxtpkh>>=?fundeposits->returndeposits.initial_amount);register1~chunked:falseS.staking_balance(functxtpkh()()->check_delegate_registeredctxtpkh>>=?fun()->Delegate.staking_balancectxtpkh);register1~chunked:falseS.frozen_deposits_limit(functxtpkh()()->check_delegate_registeredctxtpkh>>=?fun()->Delegate.frozen_deposits_limitctxtpkh);register1~chunked:trueS.delegated_contracts(functxtpkh()()->check_delegate_registeredctxtpkh>>=?fun()->Delegate.delegated_contractsctxtpkh>|=ok);register1~chunked:falseS.delegated_balance(functxtpkh()()->check_delegate_registeredctxtpkh>>=?fun()->Delegate.delegated_balancectxtpkh);register1~chunked:falseS.deactivated(functxtpkh()()->check_delegate_registeredctxtpkh>>=?fun()->Delegate.deactivatedctxtpkh);register1~chunked:falseS.grace_period(functxtpkh()()->check_delegate_registeredctxtpkh>>=?fun()->Delegate.last_cycle_before_deactivationctxtpkh);register1~chunked:falseS.voting_power(functxtpkh()()->check_delegate_registeredctxtpkh>>=?fun()->Vote.get_voting_power_freectxtpkh);register1~chunked:falseS.voting_info(functxtpkh()()->check_delegate_registeredctxtpkh>>=?fun()->Vote.get_delegate_infoctxtpkh);register1~chunked:falseS.consensus_key(functxtpkh()()->Delegate.Consensus_key.active_pubkeyctxtpkh>>=?funpk->Delegate.Consensus_key.pending_updatesctxtpkh>>=?funpendings->return(pk.consensus_pkh,pendings));register1~chunked:falseS.participation(functxtpkh()()->check_delegate_registeredctxtpkh>>=?fun()->Delegate.participation_infoctxtpkh)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}()letinfoctxtblockpkh=RPC_context.make_call1S.infoctxtblockpkh()()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()()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()()letdelegated_balancectxtblockpkh=RPC_context.make_call1S.delegated_balancectxtblockpkh()()letdeactivatedctxtblockpkh=RPC_context.make_call1S.deactivatedctxtblockpkh()()letgrace_periodctxtblockpkh=RPC_context.make_call1S.grace_periodctxtblockpkh()()letvoting_powerctxtblockpkh=RPC_context.make_call1S.voting_powerctxtblockpkh()()letvoting_infoctxtblockpkh=RPC_context.make_call1S.voting_infoctxtblockpkh()()letconsensus_keyctxtblockpkh=RPC_context.make_call1S.consensus_keyctxtblockpkh()()letparticipationctxtblockpkh=RPC_context.make_call1S.participationctxtblockpkh()()