From f1e5a7af80abc0faa3e6901fc9e7b7661c387551 Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Thu, 24 Feb 2022 11:15:36 +0100 Subject: [PATCH 1/4] Proto: add add_cycle_era to Level_repr --- src/proto_alpha/lib_protocol/level_repr.ml | 2 ++ src/proto_alpha/lib_protocol/level_repr.mli | 3 +++ 2 files changed, 5 insertions(+) diff --git a/src/proto_alpha/lib_protocol/level_repr.ml b/src/proto_alpha/lib_protocol/level_repr.ml index 0b5926f387f5..3e69c5dfd134 100644 --- a/src/proto_alpha/lib_protocol/level_repr.ml +++ b/src/proto_alpha/lib_protocol/level_repr.ml @@ -147,6 +147,8 @@ let create_cycle_eras cycle_eras = in aux newest_era older_eras >>? fun () -> ok cycle_eras +let add_cycle_era new_era cycle_eras = create_cycle_eras (new_era :: cycle_eras) + let cycle_era_encoding = let open Data_encoding in conv diff --git a/src/proto_alpha/lib_protocol/level_repr.mli b/src/proto_alpha/lib_protocol/level_repr.mli index b595ce324e69..7e98b9653037 100644 --- a/src/proto_alpha/lib_protocol/level_repr.mli +++ b/src/proto_alpha/lib_protocol/level_repr.mli @@ -85,6 +85,9 @@ val cycle_eras_encoding : cycle_eras Data_encoding.t *) val create_cycle_eras : cycle_era list -> cycle_eras tzresult +(** Add a new cycle era *) +val add_cycle_era : cycle_era -> cycle_eras -> cycle_eras tzresult + (** Returns the current era *) val current_era : cycle_eras -> cycle_era -- GitLab From acbef9d7529660cc63f0a160777c8e86cdbb7651 Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Thu, 24 Feb 2022 14:09:49 +0100 Subject: [PATCH 2/4] Proto/Test: check for cycle bounds on seed availability Also take the opportunity to extend Assert.proto_error_with_info such that one can also match on other error information (like error id) besides error title. --- .../lib_protocol/test/helpers/assert.ml | 21 ++++- .../lib_protocol/test/helpers/context.ml | 6 +- .../lib_protocol/test/helpers/context.mli | 1 + .../test/integration/consensus/test_seed.ml | 80 +++++++++++++++++++ 4 files changed, 101 insertions(+), 7 deletions(-) diff --git a/src/proto_alpha/lib_protocol/test/helpers/assert.ml b/src/proto_alpha/lib_protocol/test/helpers/assert.ml index e4739337d3af..49b4e62d7998 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/assert.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/assert.ml @@ -45,10 +45,23 @@ let proto_error ~loc v f = f err | _ -> false) -let proto_error_with_info ~loc res error_title = - proto_error ~loc res (function err -> - error_title - = (Error_monad.find_info_of_error (Environment.wrap_tzerror err)).title) +let proto_error_with_info ?(error_info_field = `Title) ~loc v + expected_error_info = + let info err = + let i = Error_monad.find_info_of_error (Environment.wrap_tzerror err) in + match error_info_field with + | `Title -> i.title + | `Id -> i.id + | `Description -> i.description + | `Message -> Format.asprintf "%a" Environment.Error_monad.pp err + in + proto_error ~loc v (function err -> + Format.printf + "@[THE ERROR IS: %s@,EXPECTED: %s@]@." + (info err) + expected_error_info ; + let info = info err in + String.equal info expected_error_info) let equal ~loc (cmp : 'a -> 'a -> bool) msg pp a b = if not (cmp a b) then diff --git a/src/proto_alpha/lib_protocol/test/helpers/context.ml b/src/proto_alpha/lib_protocol/test/helpers/context.ml index 5625dc5b6021..53959305ccef 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/context.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/context.ml @@ -153,9 +153,9 @@ let get_voting_power = Delegate_services.voting_power rpc_ctxt let get_total_voting_power = Alpha_services.Voting.total_voting_power rpc_ctxt -let get_bakers ?(filter = fun _x -> true) ctxt = - Plugin.RPC.Baking_rights.get rpc_ctxt ctxt >|=? fun bakers -> - List.filter filter bakers +let get_bakers ?filter ?cycle ctxt = + Plugin.RPC.Baking_rights.get rpc_ctxt ?cycle ctxt >|=? fun bakers -> + (match filter with None -> bakers | Some f -> List.filter f bakers) |> List.map (fun p -> p.Plugin.RPC.Baking_rights.delegate) let get_baker ctxt ~round = diff --git a/src/proto_alpha/lib_protocol/test/helpers/context.mli b/src/proto_alpha/lib_protocol/test/helpers/context.mli index 5c9f5c4c5378..07536aa7bfe5 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/context.mli +++ b/src/proto_alpha/lib_protocol/test/helpers/context.mli @@ -58,6 +58,7 @@ val get_total_voting_power : val get_bakers : ?filter:(Plugin.RPC.Baking_rights.t -> bool) -> + ?cycle:Cycle.t -> t -> public_key_hash list tzresult Lwt.t diff --git a/src/proto_alpha/lib_protocol/test/integration/consensus/test_seed.ml b/src/proto_alpha/lib_protocol/test/integration/consensus/test_seed.ml index 0f7d505e66f6..a463afc6be59 100644 --- a/src/proto_alpha/lib_protocol/test/integration/consensus/test_seed.ml +++ b/src/proto_alpha/lib_protocol/test/integration/consensus/test_seed.ml @@ -543,6 +543,85 @@ let test_early_incorrect_unverified_correct_already_vdf () = assert (Bytes.(equal vdf_expected_seed vdf_stored_seed)) ; return_unit) +(* We check that bounds used in [Seed_storage.for_cycle] are as expected. *) +let test_cycle_bounds () = + Context.init1 ~consensus_threshold:0 () >>=? fun (b, _accounts) -> + Context.get_constants (B b) >>=? fun csts -> + let past_offset = csts.parametric.max_slashing_period - 1 in + let future_offset = csts.parametric.preserved_cycles in + let open Alpha_context.Cycle in + let expected_error_message direction current_cycle = + match direction with + | `Past -> + let oldest_cycle = Stdlib.Option.get (sub current_cycle past_offset) in + let older_cycle = Stdlib.Option.get (sub oldest_cycle 1) in + Format.asprintf + "The seed for cycle %a has been cleared from the context (oldest \ + known seed is for cycle %a)" + pp + older_cycle + pp + oldest_cycle + | `Future -> + let latest_cycle = add current_cycle future_offset in + let later_cycle = add latest_cycle 1 in + Format.asprintf + "The seed for cycle %a has not been computed yet (latest known seed \ + is for cycle %a)" + pp + later_cycle + pp + latest_cycle + | `Missing_sampler_state cycle -> + Format.asprintf + "Storage error:\n Missing key 'cycle/%a/delegate_sampler_state'." + pp + cycle + in + let cycle = root in + Context.get_bakers ~cycle:(add cycle future_offset) (B b) >>=? fun _ -> + let future_cycle = add cycle (future_offset + 1) in + Context.get_bakers ~cycle:future_cycle (B b) >>= fun res -> + (* the first cycle is special *) + Assert.proto_error_with_info + ~loc:__LOC__ + ~error_info_field:`Message + res + (expected_error_message (`Missing_sampler_state future_cycle) cycle) + >>=? fun () -> + Block.bake_until_cycle_end b >>=? fun b -> + let cycle = add cycle 1 in + Context.get_bakers ~cycle:root (B b) >>=? fun _ -> + Context.get_bakers ~cycle:(add cycle future_offset) (B b) >>=? fun _ -> + Context.get_bakers ~cycle:(add cycle (future_offset + 1)) (B b) >>= fun res -> + Assert.proto_error_with_info + ~loc:__LOC__ + res + ~error_info_field:`Message + (expected_error_message `Future cycle) + >>=? fun () -> + Block.bake_until_n_cycle_end past_offset b >>=? fun b -> + let cycle = add cycle past_offset in + Context.get_bakers ~cycle:(Stdlib.Option.get (sub cycle past_offset)) (B b) + >>=? fun _ -> + Context.get_bakers + ~cycle:(Stdlib.Option.get (sub cycle (past_offset + 1))) + (B b) + >>= fun res -> + Assert.proto_error_with_info + ~loc:__LOC__ + res + ~error_info_field:`Message + (expected_error_message `Past cycle) + >>=? fun () -> + Context.get_bakers ~cycle:(add cycle future_offset) (B b) >>=? fun _ -> + Context.get_bakers ~cycle:(add cycle (future_offset + 1)) (B b) >>= fun res -> + Assert.proto_error_with_info + ~loc:__LOC__ + res + ~error_info_field:`Message + (expected_error_message `Future cycle) + let tests = [ Tztest.tztest @@ -564,4 +643,5 @@ let tests = `Quick test_early_incorrect_unverified_correct_already_vdf; Tztest.tztest "test VDF status" `Quick test_vdf_status; + Tztest.tztest "for_cycle cycle bounds" `Quick test_cycle_bounds; ] -- GitLab From 32b08840134ffd1785aa5c84980244e681125a20 Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Wed, 16 Feb 2022 21:45:08 +0100 Subject: [PATCH 3/4] Proto: oldest known seed is at the previous cycle TODO: Also, the first cycle is not a corner case anymore! --- src/proto_alpha/lib_protocol/seed_storage.ml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/proto_alpha/lib_protocol/seed_storage.ml b/src/proto_alpha/lib_protocol/seed_storage.ml index 79c789c1abdb..b3c28135fb3e 100644 --- a/src/proto_alpha/lib_protocol/seed_storage.ml +++ b/src/proto_alpha/lib_protocol/seed_storage.ml @@ -215,6 +215,7 @@ let update_seed ctxt vdf_solution = let for_cycle ctxt cycle = let preserved = Constants_storage.preserved_cycles ctxt in + let max_slashing_period = Constants_storage.max_slashing_period ctxt in let current_cycle = (Level_storage.current ctxt).cycle in let latest = if Cycle_repr.(current_cycle = root) then @@ -222,7 +223,7 @@ let for_cycle ctxt cycle = else Cycle_repr.add current_cycle preserved in let oldest = - match Cycle_repr.sub current_cycle preserved with + match Cycle_repr.sub current_cycle (max_slashing_period - 1) with | None -> Cycle_repr.root | Some oldest -> oldest in -- GitLab From 09542d53a656728fe8dbae7b9cbe34216491999d Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Wed, 13 Jul 2022 15:48:01 +0200 Subject: [PATCH 4/4] Proto: access Storage.Seed.For_cycle through Seed_storage --- src/proto_alpha/lib_protocol/delegate_storage.ml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/proto_alpha/lib_protocol/delegate_storage.ml b/src/proto_alpha/lib_protocol/delegate_storage.ml index f479bf7bf124..ade867a88a3f 100644 --- a/src/proto_alpha/lib_protocol/delegate_storage.ml +++ b/src/proto_alpha/lib_protocol/delegate_storage.ml @@ -628,7 +628,7 @@ let compute_snapshot_index_for_seed ~max_snapshot_index seed = |> fst |> Int32.to_int |> return let compute_snapshot_index ctxt cycle ~max_snapshot_index = - Storage.Seed.For_cycle.get ctxt cycle >>=? fun seed -> + Seed_storage.for_cycle ctxt cycle >>=? fun seed -> compute_snapshot_index_for_seed ~max_snapshot_index seed let select_distribution_for_cycle ctxt cycle = @@ -770,7 +770,7 @@ module Random = struct [Raw_context.set_sampler_for_cycle]. *) let sampler_for_cycle ctxt cycle = let read ctxt = - Storage.Seed.For_cycle.get ctxt cycle >>=? fun seed -> + Seed_storage.for_cycle ctxt cycle >>=? fun seed -> Delegate_sampler_state.get ctxt cycle >>=? fun state -> return (seed, state) in -- GitLab