Alpha: randomly select a roll snapshot for each cycle

This commit is contained in:
Grégoire Henry 2018-03-13 15:26:03 +01:00 committed by Benjamin Canou
parent b4dad92a7d
commit e2af8dbee9
5 changed files with 69 additions and 8 deletions

View File

@ -731,6 +731,7 @@ module Roll : sig
val value: context -> Tez.t
val snapshot_rolls: context -> context tzresult Lwt.t
val cycle_end: context -> Cycle.t -> context tzresult Lwt.t
val baking_rights_owner:

View File

@ -329,6 +329,18 @@ let apply_operation
return (ctxt, Contract.originated_contracts origination_nonce, err,
Ok fees, Ok rewards)
let may_snapshot_roll ctxt =
let level = Alpha_context.Level.current ctxt in
let block_per_roll_snapshot = Constants.block_per_roll_snapshot ctxt in
if Compare.Int32.equal
(Int32.rem level.cycle_position block_per_roll_snapshot)
(Int32.pred block_per_roll_snapshot)
then
Alpha_context.Roll.snapshot_rolls ctxt >>=? fun ctxt ->
return ctxt
else
return ctxt
let may_start_new_cycle ctxt =
Baking.dawn_of_a_new_cycle ctxt >>=? function
| None -> return ctxt
@ -387,6 +399,7 @@ let finalize_application ctxt protocol_data delegate bond fees rewards =
{ nonce_hash ; delegate ; bond ; rewards ; fees }
end >>=? fun ctxt ->
(* end of cycle *)
may_snapshot_roll ctxt >>=? fun ctxt ->
may_start_new_cycle ctxt >>=? fun ctxt ->
Amendment.may_start_new_voting_cycle ctxt >>=? fun ctxt ->
return ctxt

View File

@ -61,12 +61,34 @@ let fold ctxt ~f init =
loop ctxt (Roll_repr.succ roll) (f roll delegate acc) in
loop ctxt Roll_repr.first (return init)
let freeze_rolls_for_cycle ctxt cycle =
let index = 0 in
let snapshot_rolls_for_cycle ctxt cycle =
Storage.Roll.Snapshot_for_cycle.get ctxt cycle >>=? fun index ->
Storage.Roll.Snapshot_for_cycle.set ctxt cycle (index + 1) >>=? fun ctxt ->
Storage.Roll.Owner.snapshot ctxt (cycle, index) >>=? fun ctxt ->
Storage.Roll.Next.get ctxt >>=? fun last ->
Storage.Roll.Snapshot_for_cycle.init ctxt cycle index >>=? fun ctxt ->
Storage.Roll.Last_for_snapshot.init (ctxt, cycle) index last
Storage.Roll.Last_for_snapshot.init (ctxt, cycle) index last >>=? fun ctxt ->
return ctxt
let freeze_rolls_for_cycle ctxt cycle =
Storage.Roll.Snapshot_for_cycle.get ctxt cycle >>=? fun max_index ->
Storage.Seed.For_cycle.get ctxt cycle >>=? fun seed ->
let rd = Seed_repr.initialize_new seed [MBytes.of_string "roll_snapshot"] in
let seq = Seed_repr.sequence rd 0l in
let selected_index =
Seed_repr.take_int32 seq (Int32.of_int max_index) |> fst |> Int32.to_int in
Storage.Roll.Snapshot_for_cycle.set ctxt cycle selected_index >>=? fun ctxt ->
fold_left_s
(fun ctxt index ->
if Compare.Int.(index = selected_index) then
return ctxt
else
Storage.Roll.Owner.delete_snapshot ctxt (cycle, index) >>= fun ctxt ->
Storage.Roll.Last_for_snapshot.delete (ctxt, cycle) index >>=? fun ctxt ->
return ctxt
)
ctxt
Misc.(0 --> (max_index - 1)) >>=? fun ctxt ->
return ctxt
(* Roll selection *)
@ -252,14 +274,30 @@ let init ctxt =
let init_first_cycles ctxt =
let preserved = Constants_storage.preserved_cycles ctxt in
(* Precompute rolls for cycle (0 --> preserved_cycles) *)
List.fold_left
(fun ctxt c ->
ctxt >>=? fun ctxt ->
let cycle = Cycle_repr.of_int32_exn (Int32.of_int c) in
Storage.Roll.Snapshot_for_cycle.init ctxt cycle 0 >>=? fun ctxt ->
snapshot_rolls_for_cycle ctxt cycle >>=? fun ctxt ->
freeze_rolls_for_cycle ctxt cycle)
(return ctxt) (0 --> (preserved + 1)) >>=? fun ctxt ->
(return ctxt) (0 --> preserved) >>=? fun ctxt ->
let cycle = Cycle_repr.of_int32_exn (Int32.of_int (preserved + 1)) in
(* Precomputed a snapshot for cycle (preserved_cycles + 1) *)
Storage.Roll.Snapshot_for_cycle.init ctxt cycle 0 >>=? fun ctxt ->
snapshot_rolls_for_cycle ctxt cycle >>=? fun ctxt ->
(* Prepare storage for storing snapshots for cycle (preserved_cycles+2) *)
let cycle = Cycle_repr.of_int32_exn (Int32.of_int (preserved + 2)) in
Storage.Roll.Snapshot_for_cycle.init ctxt cycle 0 >>=? fun ctxt ->
return ctxt
let snapshot_rolls ctxt =
let current_level = Raw_context.current_level ctxt in
let preserved = Constants_storage.preserved_cycles ctxt in
let cycle = Cycle_repr.add current_level.cycle (preserved+2) in
snapshot_rolls_for_cycle ctxt cycle
let cycle_end ctxt last_cycle =
let preserved = Constants_storage.preserved_cycles ctxt in
begin
@ -268,5 +306,8 @@ let cycle_end ctxt last_cycle =
| Some cleared_cycle ->
clear_cycle ctxt cleared_cycle
end >>=? fun ctxt ->
let frozen_roll_cycle = Cycle_repr.add last_cycle (preserved+2) in
freeze_rolls_for_cycle ctxt frozen_roll_cycle
let frozen_roll_cycle = Cycle_repr.add last_cycle (preserved+1) in
freeze_rolls_for_cycle ctxt frozen_roll_cycle >>=? fun ctxt ->
Storage.Roll.Snapshot_for_cycle.init
ctxt (Cycle_repr.succ (Cycle_repr.succ frozen_roll_cycle)) 0 >>=? fun ctxt ->
return ctxt

View File

@ -26,6 +26,8 @@ val init : Raw_context.t -> Raw_context.t tzresult Lwt.t
val init_first_cycles : Raw_context.t -> Raw_context.t tzresult Lwt.t
val cycle_end : Raw_context.t -> Cycle_repr.t -> Raw_context.t tzresult Lwt.t
val snapshot_rolls : Raw_context.t -> Raw_context.t tzresult Lwt.t
val fold :
Raw_context.t ->

View File

@ -65,7 +65,11 @@ 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 = Cycle_repr.add current_cycle preserved 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