Source file seed_storage.ml
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
type error +=
| Unknown of {
oldest : Cycle_repr.t;
cycle : Cycle_repr.t;
latest : Cycle_repr.t;
}
let () =
register_error_kind
`Permanent
~id:"seed.unknown_seed"
~title:"Unknown seed"
~description:"The requested seed is not available"
~pp:(fun ppf (oldest, cycle, latest) ->
if Cycle_repr.(cycle < oldest) then
Format.fprintf
ppf
"The seed for cycle %a has been cleared from the context (oldest \
known seed is for cycle %a)"
Cycle_repr.pp
cycle
Cycle_repr.pp
oldest
else
Format.fprintf
ppf
"The seed for cycle %a has not been computed yet (latest known seed \
is for cycle %a)"
Cycle_repr.pp
cycle
Cycle_repr.pp
latest)
Data_encoding.(
obj3
(req "oldest" Cycle_repr.encoding)
(req "requested" Cycle_repr.encoding)
(req "latest" Cycle_repr.encoding))
(function
| Unknown {oldest; cycle; latest} -> Some (oldest, cycle, latest)
| _ -> None)
(fun (oldest, cycle, latest) -> Unknown {oldest; cycle; latest})
let compute_for_cycle c ~revealed cycle =
match Cycle_repr.pred cycle with
| None -> assert false
| Some previous_cycle ->
let levels = Level_storage.levels_with_commitments_in_cycle c revealed in
let combine (c, random_seed, unrevealed) level =
Storage.Seed.Nonce.get c level >>=? function
| Revealed nonce ->
Storage.Seed.Nonce.remove_existing c level >|=? fun c ->
(c, Seed_repr.nonce random_seed nonce, unrevealed)
| Unrevealed u ->
Storage.Seed.Nonce.remove_existing c level >|=? fun c ->
(c, random_seed, u :: unrevealed)
in
Storage.Seed.For_cycle.get c previous_cycle >>=? fun prev_seed ->
let seed = Seed_repr.deterministic_seed prev_seed in
List.fold_left_es combine (c, seed, []) levels
>>=? fun (c, seed, unrevealed) ->
Storage.Seed.For_cycle.init c cycle seed >|=? fun c -> (c, unrevealed)
let for_cycle ctxt cycle =
let preserved = Constants_storage.preserved_cycles ctxt in
let current_level = Level_storage.current ctxt in
let current_cycle = current_level.cycle in
let latest =
if Cycle_repr.(current_cycle = root) then
Cycle_repr.add current_cycle (preserved + 1)
else Cycle_repr.add current_cycle preserved
in
let oldest =
match Cycle_repr.sub current_cycle preserved with
| None -> Cycle_repr.root
| Some oldest -> oldest
in
error_unless
Cycle_repr.(oldest <= cycle && cycle <= latest)
(Unknown {oldest; cycle; latest})
>>?= fun () -> Storage.Seed.For_cycle.get ctxt cycle
let clear_cycle c cycle = Storage.Seed.For_cycle.remove_existing c cycle
let init ctxt =
let preserved = Constants_storage.preserved_cycles ctxt in
List.fold_left_es
(fun (c, ctxt) seed ->
let cycle = Cycle_repr.of_int32_exn (Int32.of_int c) in
Storage.Seed.For_cycle.init ctxt cycle seed >|=? fun ctxt -> (c + 1, ctxt))
(0, ctxt)
(Seed_repr.initial_seeds (preserved + 2))
>|=? snd
let cycle_end ctxt last_cycle =
let preserved = Constants_storage.preserved_cycles ctxt in
(match Cycle_repr.sub last_cycle preserved with
| None -> return ctxt
| Some cleared_cycle -> clear_cycle ctxt cleared_cycle)
>>=? fun ctxt ->
match Cycle_repr.pred last_cycle with
| None -> return (ctxt, [])
| Some revealed ->
let inited_seed_cycle = Cycle_repr.add last_cycle (preserved + 1) in
compute_for_cycle ctxt ~revealed inited_seed_cycle