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
147
148
149
150
151
152
open Alpha_context
type error +=
|
Insufficient_attestation_power of {
attestation_power : int;
consensus_threshold : int;
}
let () =
register_error_kind
`Permanent
~id:"baking.insufficient_attestation_power"
~title:"Insufficient attestation power"
~description:
"The attestation power is insufficient to satisfy the consensus \
threshold."
~pp:(fun ppf (attestation_power, consensus_threshold) ->
Format.fprintf
ppf
"The attestation power (%d) is insufficient to satisfy the consensus \
threshold (%d)."
attestation_power
consensus_threshold)
Data_encoding.(
obj2 (req "attestation_power" int31) (req "consensus_threshold" int31))
(function
| Insufficient_attestation_power {attestation_power; consensus_threshold}
->
Some (attestation_power, consensus_threshold)
| _ -> None)
(fun (attestation_power, consensus_threshold) ->
Insufficient_attestation_power {attestation_power; consensus_threshold})
let bonus_baking_reward ctxt ~attestation_power =
let open Result_syntax in
let consensus_threshold = Constants.consensus_threshold ctxt in
let* baking_reward_bonus_per_slot =
Delegate.Rewards.baking_reward_bonus_per_slot ctxt
in
let = attestation_power - consensus_threshold in
let* () =
error_when
Compare.Int.(extra_attestation_power < 0)
(Insufficient_attestation_power {attestation_power; consensus_threshold})
in
Tez.(baking_reward_bonus_per_slot *? Int64.of_int extra_attestation_power)
type ordered_slots = {
delegate : Signature.public_key_hash;
consensus_key : Signature.public_key_hash;
slots : Slot.t list;
}
let attesting_rights (ctxt : t) level =
let consensus_committee_size = Constants.consensus_committee_size ctxt in
let open Lwt_result_syntax in
let*? slots = Slot.Range.create ~min:0 ~count:consensus_committee_size in
Slot.Range.rev_fold_es
(fun (ctxt, map) slot ->
let* ctxt, consensus_pk = Stake_distribution.slot_owner ctxt level slot in
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 attesting_rights_by_first_slot ctxt level =
let open Lwt_result_syntax in
let*? slots =
Slot.Range.create ~min:0 ~count:(Constants.consensus_committee_size ctxt)
in
let number_of_shards = Dal.number_of_shards ctxt in
let* ctxt, (_, slots_map) =
Slot.Range.fold_es
(fun (ctxt, (delegates_map, slots_map)) slot ->
let+ ctxt, consensus_pk =
Stake_distribution.slot_owner ctxt level slot
in
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 in_dal_committee =
if Compare.Int.(Slot.to_int slot < number_of_shards) then 1 else 0
in
let slots_map =
Slot.Map.update
initial_slot
(function
| None -> Some (consensus_pk, 1, in_dal_committee)
| Some (consensus_pk, count, dal_count) ->
Some (consensus_pk, count + 1, dal_count + in_dal_committee))
slots_map
in
(ctxt, (delegates_map, slots_map)))
(ctxt, (Signature.Public_key_hash.Map.empty, Slot.Map.empty))
slots
in
return (ctxt, slots_map)