1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
open Alpha_context
open Misc
type error +=
|
Insufficient_endorsing_power of {
endorsing_power : int;
consensus_threshold : int;
}
let () =
register_error_kind
`Permanent
~id:"baking.insufficient_endorsing_power"
~title:"Insufficient endorsing power"
~description:
"The endorsing power is insufficient to satisfy the consensus threshold."
~pp:(fun ppf (endorsing_power, consensus_threshold) ->
Format.fprintf
ppf
"The endorsing power (%d) is insufficient to satisfy the consensus \
threshold (%d)."
endorsing_power
consensus_threshold)
Data_encoding.(
obj2 (req "endorsing_power" int31) (req "consensus_threshold" int31))
(function
| Insufficient_endorsing_power {endorsing_power; consensus_threshold} ->
Some (endorsing_power, consensus_threshold)
| _ -> None)
(fun (endorsing_power, consensus_threshold) ->
Insufficient_endorsing_power {endorsing_power; consensus_threshold})
let bonus_baking_reward ctxt ~endorsing_power =
let consensus_threshold = Constants.consensus_threshold ctxt in
let baking_reward_bonus_per_slot =
Constants.baking_reward_bonus_per_slot ctxt
in
let = endorsing_power - consensus_threshold in
error_when
Compare.Int.(extra_endorsing_power < 0)
(Insufficient_endorsing_power {endorsing_power; consensus_threshold})
>>? fun () ->
Tez.(baking_reward_bonus_per_slot *? Int64.of_int extra_endorsing_power)
let baking_rights c level =
let rec f c round =
Stake_distribution.baking_rights_owner c level ~round
>>=? fun (c, _slot, consensus_pk) ->
return
(LCons (Consensus_key.pkh consensus_pk, fun () -> f c (Round.succ round)))
in
f c Round.zero
type ordered_slots = {
delegate : Signature.public_key_hash;
consensus_key : Signature.public_key_hash;
slots : Slot.t list;
}
let endorsing_rights (ctxt : t) level =
let consensus_committee_size = Constants.consensus_committee_size ctxt in
Slot.Range.create ~min:0 ~count:consensus_committee_size >>?= fun slots ->
Slot.Range.rev_fold_es
(fun (ctxt, map) slot ->
Stake_distribution.slot_owner ctxt level slot
>>=? fun (ctxt, consensus_pk) ->
let map =
Signature.Public_key_hash.Map.update
consensus_pk.delegate
(function
| None ->
Some
{
delegate = consensus_pk.delegate;
consensus_key = consensus_pk.consensus_pkh;
slots = [slot];
}
| Some slots -> Some {slots with slots = slot :: slots.slots})
map
in
return (ctxt, map))
(ctxt, Signature.Public_key_hash.Map.empty)
slots
let endorsing_rights_by_first_slot ctxt level =
Slot.Range.create ~min:0 ~count:(Constants.consensus_committee_size ctxt)
>>?= fun slots ->
Slot.Range.fold_es
(fun (ctxt, (delegates_map, slots_map)) slot ->
Stake_distribution.slot_owner ctxt level slot
>|=? fun (ctxt, consensus_pk) ->
let initial_slot, delegates_map =
match
Signature.Public_key_hash.Map.find consensus_pk.delegate delegates_map
with
| None ->
( slot,
Signature.Public_key_hash.Map.add
consensus_pk.delegate
slot
delegates_map )
| Some initial_slot -> (initial_slot, delegates_map)
in
let slots_map =
Slot.Map.update
initial_slot
(function
| None -> Some (consensus_pk, 1)
| Some (consensus_pk, count) -> Some (consensus_pk, count + 1))
slots_map
in
(ctxt, (delegates_map, slots_map)))
(ctxt, (Signature.Public_key_hash.Map.empty, Slot.Map.empty))
slots
>>=? fun (ctxt, (_, slots_map)) -> return (ctxt, slots_map)