diff --git a/src/lib_dal_node/amplificator.ml b/src/lib_dal_node/amplificator.ml index 3d86f6ebb0ff6cb065014e5c89b136af0988e81c..f478c8925e2801213506427d6bc40adf0daa42a9 100644 --- a/src/lib_dal_node/amplificator.ml +++ b/src/lib_dal_node/amplificator.ml @@ -28,6 +28,14 @@ type t = { query_pipe : query_msg Lwt_pipe.Unbounded.t; mutable query_id : int; query_store : (int, query) Query_store.t; + amplification_random_delay_min : float; + amplification_random_delay_max : float; + (* When receiving shards from the network, the DAL node does not + perform the amplification as soon as it has enough shards to do + the reconstruction but waits a bit in case the missing shards are + received from the network. The duration of the delay is picked at + random between [amplification_random_delay_min] and + [amplification_random_delay_max]. *) } type error += @@ -331,8 +339,33 @@ let reply_receiver_job {process; query_store; _} node_context = let err = [error_of_exn exn] in Lwt.return (Error err)) +let determine_amplification_delays node_ctxt = + let open Result_syntax in + let+ parameters = + Node_context.get_proto_parameters ~level:`Last_proto node_ctxt + in + (* The propagation window is the attestation lag minus 4 levels, because: + - the daemon waits 2 levels for the head to be finalized + - attestation operations are included in the block at the next level + - the baker asks attestation information one level in advance *) + let propagation_period = + (parameters.attestation_lag - 4) + * Int64.to_int parameters.minimal_block_delay + in + (* We split this window in 3: one third for the normal propagation round, one + third for amplification; one third for the second propagation round. Note, + currently for Mainnet: 4 * 8s = 32s, so roughly 10s; for Ghostnet: 16s, so + roughly 5s. We round to the lowest integer. *) + let amplification_period = float_of_int (propagation_period / 3) in + let amplification_random_delay_min = amplification_period in + let amplification_random_delay_max = 2. *. amplification_period in + (amplification_random_delay_min, amplification_random_delay_max) + let start_amplificator node_ctxt = let open Lwt_result_syntax in + let*? amplification_random_delay_min, amplification_random_delay_max = + determine_amplification_delays node_ctxt + in let cryptobox = Node_context.get_cryptobox node_ctxt in let shards_proofs_precomputation = Node_context.get_shards_proofs_precomputation node_ctxt @@ -353,7 +386,15 @@ let start_amplificator node_ctxt = let queue_length = Query_store.length query_store in let () = Dal_metrics.update_amplification_queue_length queue_length in let amplificator = - {node_ctxt; process; query_pipe; query_store; query_id = 0} + { + node_ctxt; + process; + query_pipe; + query_store; + query_id = 0; + amplification_random_delay_min; + amplification_random_delay_max; + } in let (_ : Lwt_exit.clean_up_callback_id) = Lwt_exit.register_clean_up_callback ~loc:__LOC__ (fun _exit_code -> @@ -510,10 +551,10 @@ let try_amplification commitment slot_metrics slot_id amplificator = all the shards so that the reconstruction is not needed, and also avoids having multiple nodes reconstruct at once. *) let random_delay = - Constants.( - amplification_random_delay_min - +. Random.float - (amplification_random_delay_max -. amplification_random_delay_min)) + amplificator.amplification_random_delay_min + +. Random.float + (amplificator.amplification_random_delay_max + -. amplificator.amplification_random_delay_min) in let*! () = Event.emit_reconstruct_starting_in diff --git a/src/lib_dal_node/constants.ml b/src/lib_dal_node/constants.ml index 6a293185b95bc2cab6242b4585a38a82766c5cb0..005911cc4ed3063b06813f9631e470b83202afa3 100644 --- a/src/lib_dal_node/constants.ml +++ b/src/lib_dal_node/constants.ml @@ -59,10 +59,6 @@ let slot_id_cache_size = 100 let shards_verification_sampling_frequency = 100 -let amplification_random_delay_min = 10.0 - -let amplification_random_delay_max = 20.0 - let amplification_timeout = 120. (* Initial reconnection delay to L1 node from the DAL crawler in seconds. See diff --git a/src/lib_dal_node/constants.mli b/src/lib_dal_node/constants.mli index 961b57277f818d21e58a974be21ace41e1cba700..014c228644bb05534a08914135f7a86d09abe7aa 100644 --- a/src/lib_dal_node/constants.mli +++ b/src/lib_dal_node/constants.mli @@ -47,18 +47,7 @@ val slot_id_cache_size : int verification. *) val shards_verification_sampling_frequency : int -(** When receiving shards from the network, the DAL node does not - perform the amplification as soon as it has enough shards to do - the reconstruction but waits a bit in case the missing shards are - received from the network. The duration of the delay is picked at - random between [amplification_random_delay_min] and - [amplification_random_delay_max]. *) - -val amplification_random_delay_min : float - -val amplification_random_delay_max : float - -(* During amplification, if the forked process takes more time than +(** During amplification, if the forked process takes more time than this timeout to send the proved shards, then amplification attempt is aborted to avoid keeping a pending promise forever. *) val amplification_timeout : float diff --git a/src/lib_dal_node_services/types.ml b/src/lib_dal_node_services/types.ml index 6920a5e66304cf7d549ce0b94848194dcbbdee66..4a44bb40734d1543f760fa38913f5e4ff954c06a 100644 --- a/src/lib_dal_node_services/types.ml +++ b/src/lib_dal_node_services/types.ml @@ -361,6 +361,7 @@ type proto_parameters = { commitment_period_in_blocks : int; dal_attested_slots_validity_lag : int; blocks_per_cycle : int32; + minimal_block_delay : int64; } type trap = { @@ -504,6 +505,7 @@ let proto_parameters_encoding : proto_parameters Data_encoding.t = commitment_period_in_blocks; dal_attested_slots_validity_lag; blocks_per_cycle; + minimal_block_delay; } -> ( ( feature_enable, incentives_enable, @@ -515,7 +517,8 @@ let proto_parameters_encoding : proto_parameters Data_encoding.t = sc_rollup_challenge_window_in_blocks, commitment_period_in_blocks, dal_attested_slots_validity_lag, - blocks_per_cycle ) )) + blocks_per_cycle, + minimal_block_delay ) )) (fun ( ( feature_enable, incentives_enable, number_of_slots, @@ -526,7 +529,8 @@ let proto_parameters_encoding : proto_parameters Data_encoding.t = sc_rollup_challenge_window_in_blocks, commitment_period_in_blocks, dal_attested_slots_validity_lag, - blocks_per_cycle ) ) -> + blocks_per_cycle, + minimal_block_delay ) ) -> { feature_enable; incentives_enable; @@ -539,6 +543,7 @@ let proto_parameters_encoding : proto_parameters Data_encoding.t = commitment_period_in_blocks; dal_attested_slots_validity_lag; blocks_per_cycle; + minimal_block_delay; }) (merge_objs (obj6 @@ -548,12 +553,13 @@ let proto_parameters_encoding : proto_parameters Data_encoding.t = (req "attestation_lag" int31) (req "attestation_threshold" int31) (req "traps_fraction" q_encoding)) - (obj5 + (obj6 (req "cryptobox_parameters" Cryptobox.Verifier.parameters_encoding) (req "sc_rollup_challenge_window_in_blocks" int31) (req "commitment_period_in_blocks" int31) (req "dal_attested_slots_validity_lag" int31) - (req "blocks_per_cycle" int32))) + (req "blocks_per_cycle" int32) + (req "minimal_block_delay" int64))) let trap_encoding = Data_encoding.( diff --git a/src/lib_dal_node_services/types.mli b/src/lib_dal_node_services/types.mli index 3316487e46a8d63bae970af4110b447f43b0a3fe..e2f3249afb29a7fc125125140d838dff0aef1ac4 100644 --- a/src/lib_dal_node_services/types.mli +++ b/src/lib_dal_node_services/types.mli @@ -274,6 +274,7 @@ type proto_parameters = { commitment_period_in_blocks : int; dal_attested_slots_validity_lag : int; blocks_per_cycle : int32; + minimal_block_delay : int64; } (** The type contains all elements required to construct a trap accusation. diff --git a/src/proto_021_PsQuebec/lib_dal/dal_plugin_registration.ml b/src/proto_021_PsQuebec/lib_dal/dal_plugin_registration.ml index 79de163f2bc99b27ea2dc89c988ce264ae46416e..525dc1a8675a544840a6aeafcecbafa5462ddbae 100644 --- a/src/proto_021_PsQuebec/lib_dal/dal_plugin_registration.ml +++ b/src/proto_021_PsQuebec/lib_dal/dal_plugin_registration.ml @@ -74,6 +74,7 @@ module Plugin = struct parametric.sc_rollup.reveal_activation_level .dal_attested_slots_validity_lag; blocks_per_cycle = parametric.blocks_per_cycle; + minimal_block_delay = Period.to_seconds parametric.minimal_block_delay; } type error += DAL_accusation_not_available diff --git a/src/proto_022_PsRiotum/lib_dal/dal_plugin_registration.ml b/src/proto_022_PsRiotum/lib_dal/dal_plugin_registration.ml index 818d80be104fe9023f0d2b8f93e3ed1b6ddcae8c..443bbab5b73e001ceadb50ae42058bf682cd0813 100644 --- a/src/proto_022_PsRiotum/lib_dal/dal_plugin_registration.ml +++ b/src/proto_022_PsRiotum/lib_dal/dal_plugin_registration.ml @@ -76,6 +76,7 @@ module Plugin = struct parametric.sc_rollup.reveal_activation_level .dal_attested_slots_validity_lag; blocks_per_cycle = parametric.blocks_per_cycle; + minimal_block_delay = Period.to_seconds parametric.minimal_block_delay; } (* We choose a previous offset (5 blocks from head) to ensure that the diff --git a/src/proto_alpha/lib_dal/dal_plugin_registration.ml b/src/proto_alpha/lib_dal/dal_plugin_registration.ml index f3ad19ecc43b27dbfb052e0dc8e047b8f4ddbfa0..14a7d33bb5f25d779e02ef47ea5c67c1d9b854c2 100644 --- a/src/proto_alpha/lib_dal/dal_plugin_registration.ml +++ b/src/proto_alpha/lib_dal/dal_plugin_registration.ml @@ -96,6 +96,7 @@ module Plugin = struct parametric.sc_rollup.reveal_activation_level .dal_attested_slots_validity_lag; blocks_per_cycle = parametric.blocks_per_cycle; + minimal_block_delay = Period.to_seconds parametric.minimal_block_delay; } (* We choose a previous offset (5 blocks from head) to ensure that the diff --git a/tezt/tests/dal.ml b/tezt/tests/dal.ml index 5796b3aeccdfe2088302bf5a072de47cf888134e..fa7ab775fd700c77f7bfeccc8ba56c9fa0a3d39e 100644 --- a/tezt/tests/dal.ml +++ b/tezt/tests/dal.ml @@ -4324,8 +4324,8 @@ let test_peers_reconnection _protocol _parameters _cryptobox node client (* Adapted from sc_rollup.ml *) let test_l1_migration_scenario ?(tags = []) ?(uses = []) ~migrate_from ~migrate_to ~migration_level ~scenario ~description ?operator_profiles - ?attestation_lag ?attestation_threshold ?number_of_slots ?number_of_shards - ?slot_size ?page_size ?redundancy_factor ?traps_fraction + ?custom_constants ?attestation_lag ?attestation_threshold ?number_of_slots + ?number_of_shards ?slot_size ?page_size ?redundancy_factor ?traps_fraction ?consensus_committee_size ?blocks_per_cycle ?minimal_block_delay ?activation_timestamp () = let tags = @@ -4362,6 +4362,7 @@ let test_l1_migration_scenario ?(tags = []) ?(uses = []) ~migrate_from in let* node, client, dal_parameters = setup_node + ~custom_constants ~parameter_overrides ~protocol:migrate_from ~l1_history_mode:Default_with_refutation @@ -4524,6 +4525,54 @@ let test_migration_accuser_issue ~migrate_from ~migrate_to = ~migrate_to () +let test_migration_parameters ~migrate_from ~migrate_to = + let tags = ["migration"; "parameters"] in + let description = "test parameters at migration" in + let scenario ~migration_level _dal_parameters client node dal_node = + let* proto_params = + Node.RPC.call node @@ RPC.get_chain_block_context_constants () + in + let minimal_block_delay = + JSON.(proto_params |-> "minimal_block_delay" |> as_int) + in + let attestation_lag = + JSON.(proto_params |-> "dal_parametric" |-> "attestation_lag" |> as_int) + in + let baker = + let dal_node_rpc_endpoint = Dal_node.as_rpc_endpoint dal_node in + Agnostic_baker.create ~dal_node_rpc_endpoint node client + in + let* () = Agnostic_baker.run baker in + + let* _level = Node.wait_for_level node migration_level in + Log.info "migrated to next protocol, starting a second DAL node accuser" ; + let* new_proto_params = + Node.RPC.call node @@ RPC.get_chain_block_context_constants () + in + let new_minimal_block_delay = + JSON.(new_proto_params |-> "minimal_block_delay" |> as_int) + in + let new_attestation_lag = + JSON.(proto_params |-> "dal_parametric" |-> "attestation_lag" |> as_int) + in + let same_parameters = + minimal_block_delay = new_minimal_block_delay + && attestation_lag = new_attestation_lag + in + Check.is_true same_parameters ~error_msg:"Deal with issue #7983" ; + unit + in + test_l1_migration_scenario + ~scenario + ~tags + ~description + ~uses:[Constant.octez_agnostic_baker] + ~activation_timestamp:Now + ~custom_constants:Protocol.Constants_mainnet + ~migrate_from + ~migrate_to + () + let test_operator_profile _protocol _dal_parameters _cryptobox _node _client dal_node = let index = 0 in @@ -10498,7 +10547,8 @@ let register_migration ~migrate_from ~migrate_to = ~migrate_from ~migrate_to ; tests_start_dal_node_around_migration ~migrate_from ~migrate_to ; - test_migration_accuser_issue ~migration_level:4 ~migrate_from ~migrate_to + test_migration_accuser_issue ~migration_level:4 ~migrate_from ~migrate_to ; + test_migration_parameters ~migration_level:3 ~migrate_from ~migrate_to let () = Regression.register