diff --git a/src/bin_smart_rollup_node/main_smart_rollup_node.ml b/src/bin_smart_rollup_node/main_smart_rollup_node.ml index 5004a2d7df2a9de87e11ca3a296d77bcdae66178..f0b042423823f7c0f2dd0f5cd3c9cefa6c225eed 100644 --- a/src/bin_smart_rollup_node/main_smart_rollup_node.ml +++ b/src/bin_smart_rollup_node/main_smart_rollup_node.ml @@ -127,6 +127,7 @@ let config_init_command = ~history_mode ~allowed_origins ~allowed_headers + ~apply_unsafe_patches:false in let* () = Configuration.save ~force ~data_dir config in let*! () = @@ -152,7 +153,7 @@ let legacy_run_command = rpc_port_arg acl_override_arg metrics_addr_arg) - (args19 + (args20 loser_mode_arg reconnection_delay_arg dal_node_endpoint_arg @@ -171,7 +172,8 @@ let legacy_run_command = gc_frequency_arg history_mode_arg cors_allowed_origins_arg - cors_allowed_headers_arg)) + cors_allowed_headers_arg + apply_unsafe_patches_switch)) (prefixes ["run"] @@ stop) (fun ( ( data_dir, mode, @@ -198,7 +200,8 @@ let legacy_run_command = gc_frequency, history_mode, allowed_origins, - allowed_headers ) ) + allowed_headers, + apply_unsafe_patches ) ) cctxt -> let* configuration = Configuration.Cli.create_or_read_config @@ -228,6 +231,7 @@ let legacy_run_command = ~history_mode ~allowed_origins ~allowed_headers + ~apply_unsafe_patches in Rollup_node_daemon.run ~data_dir @@ -246,59 +250,63 @@ let run_command = ~desc: "Run the rollup node daemon. Arguments overwrite values provided in the \ configuration file." - (args24 - data_dir_arg - rpc_addr_arg - rpc_port_arg - acl_override_arg - metrics_addr_arg - loser_mode_arg - reconnection_delay_arg - dal_node_endpoint_arg - dac_observer_endpoint_arg - dac_timeout_arg - pre_images_endpoint_arg - injector_retention_period_arg - injector_attempts_arg - injection_ttl_arg - index_buffer_size_arg - irmin_cache_size_arg - log_kernel_debug_arg - log_kernel_debug_file_arg - boot_sector_file_arg - no_degraded_arg - gc_frequency_arg - history_mode_arg - cors_allowed_origins_arg - cors_allowed_headers_arg) + (merge_options + (args11 + data_dir_arg + rpc_addr_arg + rpc_port_arg + acl_override_arg + metrics_addr_arg + loser_mode_arg + reconnection_delay_arg + dal_node_endpoint_arg + dac_observer_endpoint_arg + dac_timeout_arg + pre_images_endpoint_arg) + (args14 + injector_retention_period_arg + injector_attempts_arg + injection_ttl_arg + index_buffer_size_arg + irmin_cache_size_arg + log_kernel_debug_arg + log_kernel_debug_file_arg + boot_sector_file_arg + no_degraded_arg + gc_frequency_arg + history_mode_arg + cors_allowed_origins_arg + cors_allowed_headers_arg + apply_unsafe_patches_switch)) (prefixes ["run"] @@ mode_param @@ prefixes ["for"] @@ sc_rollup_address_param @@ prefixes ["with"; "operators"] @@ seq_of_param @@ operator_param) - (fun ( data_dir, - rpc_addr, - rpc_port, - acl_override, - metrics_addr, - loser_mode, - reconnection_delay, - dal_node_endpoint, - dac_observer_endpoint, - dac_timeout, - pre_images_endpoint, - injector_retention_period, - injector_attempts, - injection_ttl, - index_buffer_size, - irmin_cache_size, - log_kernel_debug, - log_kernel_debug_file, - boot_sector_file, - no_degraded, - gc_frequency, - history_mode, - allowed_origins, - allowed_headers ) + (fun ( ( data_dir, + rpc_addr, + rpc_port, + acl_override, + metrics_addr, + loser_mode, + reconnection_delay, + dal_node_endpoint, + dac_observer_endpoint, + dac_timeout, + pre_images_endpoint ), + ( injector_retention_period, + injector_attempts, + injection_ttl, + index_buffer_size, + irmin_cache_size, + log_kernel_debug, + log_kernel_debug_file, + boot_sector_file, + no_degraded, + gc_frequency, + history_mode, + allowed_origins, + allowed_headers, + apply_unsafe_patches ) ) mode sc_rollup_address operators @@ -331,6 +339,7 @@ let run_command = ~history_mode ~allowed_origins ~allowed_headers + ~apply_unsafe_patches in Rollup_node_daemon.run ~data_dir diff --git a/src/lib_smart_rollup_node/cli.ml b/src/lib_smart_rollup_node/cli.ml index c60a9cc2aedb07045db176674c85d83cb626d4bf..28fea6602e47a06fbe3846cba4d4e4852d331e3d 100644 --- a/src/lib_smart_rollup_node/cli.ml +++ b/src/lib_smart_rollup_node/cli.ml @@ -512,3 +512,10 @@ let protocol_hash_arg = the last registered protocol in the rollup node which may be different \ between different versions of the node." protocol_hash_parameter + +let apply_unsafe_patches_switch : (bool, Client_context.full) Tezos_clic.arg = + Tezos_clic.switch + ~long:"apply-unsafe-patches" + ~doc: + "Apply unsafe PVM patches in the configuration or hardcoded by the node." + () diff --git a/src/lib_smart_rollup_node/configuration.ml b/src/lib_smart_rollup_node/configuration.ml index 552bb1a8caeb9cd10a42a957cbc0cd217fbaaa56..4dc485c2507ee048f0845a01cf97d69645e53b6e 100644 --- a/src/lib_smart_rollup_node/configuration.ml +++ b/src/lib_smart_rollup_node/configuration.ml @@ -64,6 +64,7 @@ type t = { fee_parameters : fee_parameters; mode : mode; loser_mode : Loser_mode.t; + apply_unsafe_patches : bool; unsafe_pvm_patches : Pvm_patches.unsafe_patch list; dal_node_endpoint : Uri.t option; dac_observer_endpoint : Uri.t option; @@ -437,6 +438,7 @@ let encoding default_display : t Data_encoding.t = fee_parameters; mode; loser_mode; + apply_unsafe_patches = _; unsafe_pvm_patches; dal_node_endpoint; dac_observer_endpoint; @@ -529,6 +531,10 @@ let encoding default_display : t Data_encoding.t = fee_parameters; mode; loser_mode; + apply_unsafe_patches = + (* Flag --apply-unsafe-patches must always be given on command + line. *) + false; unsafe_pvm_patches; dal_node_endpoint; dac_observer_endpoint; @@ -739,7 +745,7 @@ module Cli = struct ~injector_attempts ~injection_ttl ~mode ~sc_rollup_address ~boot_sector_file ~operators ~index_buffer_size ~irmin_cache_size ~log_kernel_debug ~no_degraded ~gc_frequency ~history_mode - ~allowed_origins ~allowed_headers = + ~allowed_origins ~allowed_headers ~apply_unsafe_patches = let open Result_syntax in let* purposed_operator, default_operator = get_purposed_and_default_operators operators @@ -771,6 +777,7 @@ module Cli = struct fee_parameters = Operation_kind.Map.empty; mode; loser_mode = Option.value ~default:Loser_mode.no_failures loser_mode; + apply_unsafe_patches; unsafe_pvm_patches = []; batcher = default_batcher; injector = @@ -818,7 +825,8 @@ module Cli = struct ~pre_images_endpoint ~injector_retention_period ~injector_attempts ~injection_ttl ~mode ~sc_rollup_address ~boot_sector_file ~operators ~index_buffer_size ~irmin_cache_size ~log_kernel_debug ~no_degraded - ~gc_frequency ~history_mode ~allowed_origins ~allowed_headers = + ~gc_frequency ~history_mode ~allowed_origins ~allowed_headers + ~apply_unsafe_patches = let open Result_syntax in let mode = Option.value ~default:configuration.mode mode in let* () = check_custom_mode mode in @@ -874,6 +882,7 @@ module Cli = struct Option.value ~default:default_injector.injection_ttl injection_ttl; }; loser_mode = Option.value ~default:configuration.loser_mode loser_mode; + apply_unsafe_patches; metrics_addr = Option.either metrics_addr configuration.metrics_addr; index_buffer_size = Option.either index_buffer_size configuration.index_buffer_size; @@ -911,7 +920,7 @@ module Cli = struct ~injector_retention_period ~injector_attempts ~injection_ttl ~mode ~sc_rollup_address ~boot_sector_file ~operators ~index_buffer_size ~irmin_cache_size ~log_kernel_debug ~no_degraded ~gc_frequency - ~history_mode ~allowed_origins ~allowed_headers = + ~history_mode ~allowed_origins ~allowed_headers ~apply_unsafe_patches = let open Lwt_result_syntax in let open Filename.Infix in (* Check if the data directory of the smart rollup node is not the one of Octez node *) @@ -959,6 +968,7 @@ module Cli = struct ~history_mode ~allowed_origins ~allowed_headers + ~apply_unsafe_patches in return configuration else @@ -1008,6 +1018,7 @@ module Cli = struct ~history_mode ~allowed_headers ~allowed_origins + ~apply_unsafe_patches in return config end diff --git a/src/lib_smart_rollup_node/configuration.mli b/src/lib_smart_rollup_node/configuration.mli index fefcc0373276dad10a15c2395781c042cbcf92a0..89bdce4be0d9d16090d7dabb48d916eed2ce42a6 100644 --- a/src/lib_smart_rollup_node/configuration.mli +++ b/src/lib_smart_rollup_node/configuration.mli @@ -93,6 +93,7 @@ type t = { fee_parameters : fee_parameters; mode : mode; loser_mode : Loser_mode.t; + apply_unsafe_patches : bool; unsafe_pvm_patches : Pvm_patches.unsafe_patch list; (*DAL/FIXME: https://gitlab.com/tezos/tezos/-/issues/3718 Decide whether we want to handle connections to multiple @@ -288,6 +289,7 @@ module Cli : sig history_mode:history_mode option -> allowed_origins:string list option -> allowed_headers:string list option -> + apply_unsafe_patches:bool -> t tzresult val create_or_read_config : @@ -320,5 +322,6 @@ module Cli : sig history_mode:history_mode option -> allowed_origins:string list option -> allowed_headers:string list option -> + apply_unsafe_patches:bool -> t tzresult Lwt.t end diff --git a/src/lib_smart_rollup_node/interpreter.ml b/src/lib_smart_rollup_node/interpreter.ml index 2521be42f52b14aad4eb27c43de8c9feeb519e03..5fe2c3463565c19d5efdfdfd4382c398f2e152b1 100644 --- a/src/lib_smart_rollup_node/interpreter.ml +++ b/src/lib_smart_rollup_node/interpreter.ml @@ -47,6 +47,11 @@ let apply_unsafe_patches (module Plugin : Protocol_plugin_sig.PARTIAL) match (node_ctxt.unsafe_patches :> Pvm_patches.unsafe_patch list) with | [] -> return state | patches -> + let*? () = + error_unless + node_ctxt.config.apply_unsafe_patches + (Rollup_node_errors.Needs_apply_unsafe_flag patches) + in let* whitelist = Plugin.Layer1_helpers.find_whitelist node_ctxt.cctxt diff --git a/src/lib_smart_rollup_node/node_context_loader.ml b/src/lib_smart_rollup_node/node_context_loader.ml index 0a8d579d56036051747f1641595cf15e3b92acce..ec867e68b63ec1816c27227a76e2c841b2d34b02 100644 --- a/src/lib_smart_rollup_node/node_context_loader.ml +++ b/src/lib_smart_rollup_node/node_context_loader.ml @@ -258,6 +258,7 @@ module For_snapshots = struct fee_parameters = Configuration.default_fee_parameters; mode; loser_mode; + apply_unsafe_patches = true; unsafe_pvm_patches = []; dal_node_endpoint = None; dac_observer_endpoint = None; @@ -364,6 +365,7 @@ module Internal_for_tests = struct fee_parameters = Configuration.default_fee_parameters; mode; loser_mode; + apply_unsafe_patches = false; unsafe_pvm_patches = []; dal_node_endpoint = None; dac_observer_endpoint = None; diff --git a/src/lib_smart_rollup_node/rollup_node_errors.ml b/src/lib_smart_rollup_node/rollup_node_errors.ml index 7bd71eeb28c65bdaeb7e5464cf3af3afe0edb5f2..68924fda0d6f324a9e64335424d33d0cca8ca8ae 100644 --- a/src/lib_smart_rollup_node/rollup_node_errors.ml +++ b/src/lib_smart_rollup_node/rollup_node_errors.ml @@ -77,7 +77,9 @@ type error += type error += Operator_not_in_whitelist -type error += Cannot_patch_pvm_of_public_rollup +type error += + | Cannot_patch_pvm_of_public_rollup + | Needs_apply_unsafe_flag of Pvm_patches.unsafe_patch list type error += Operator_has_no_staked @@ -448,6 +450,25 @@ let () = (function Cannot_patch_pvm_of_public_rollup -> Some () | _ -> None) (fun () -> Cannot_patch_pvm_of_public_rollup) ; + register_error_kind + ~id:"sc_rollup.node.needs_apply_unsafe_flag" + ~title:"Needs --apply-unsafe-patches flag for this rollup" + ~description:"Needs --apply-unsafe-patches flag for this rollup." + ~pp:(fun ppf patches -> + Format.fprintf + ppf + "This rollup requires the application of the following unsafe PVM \ + patches: @[%a.@,\ + @]The rollup node must be started with option --apply-unsafe-patches \ + to allow the application of these patches." + (Format.pp_print_list Pvm_patches.pp_unsafe_patch) + patches) + `Permanent + Data_encoding.( + obj1 (req "patches" (list Pvm_patches.unsafe_patch_encoding))) + (function Needs_apply_unsafe_flag p -> Some p | _ -> None) + (fun p -> Needs_apply_unsafe_flag p) ; + register_error_kind ~id:"sc_rollup.node.operator_has_no_staked" ~title:"The operator does not has any stake" diff --git a/tezt/lib_tezos/sc_rollup_node.ml b/tezt/lib_tezos/sc_rollup_node.ml index be91bc621c9051809ddbab572804af97d8f2a528..a3e7d2656a7976ccfe65caabc3d83346d7f93131 100644 --- a/tezt/lib_tezos/sc_rollup_node.ml +++ b/tezt/lib_tezos/sc_rollup_node.ml @@ -105,6 +105,7 @@ type argument = | Mode of mode | Rollup of string | Pre_images_endpoint of string + | Apply_unsafe_patches let make_argument = function | Data_dir dir -> ["--data-dir"; dir] @@ -124,6 +125,7 @@ let make_argument = function | Mode mode -> ["--mode"; string_of_mode mode] | Rollup addr -> ["--rollup"; addr] | Pre_images_endpoint addr -> ["--pre-images-endpoint"; addr] + | Apply_unsafe_patches -> ["--apply-unsafe-patches"] let is_redundant = function | Data_dir _, Data_dir _ @@ -141,7 +143,8 @@ let is_redundant = function | Dal_node _, Dal_node _ | Mode _, Mode _ | Rollup _, Rollup _ - | Pre_images_endpoint _, Pre_images_endpoint _ -> + | Pre_images_endpoint _, Pre_images_endpoint _ + | Apply_unsafe_patches, Apply_unsafe_patches -> true | Metrics_addr addr1, Metrics_addr addr2 -> addr1 = addr2 | Metrics_addr _, _ @@ -160,7 +163,8 @@ let is_redundant = function | Dal_node _, _ | Mode _, _ | Rollup _, _ - | Pre_images_endpoint _, _ -> + | Pre_images_endpoint _, _ + | Apply_unsafe_patches, _ -> false let make_arguments arguments = List.flatten (List.map make_argument arguments) diff --git a/tezt/lib_tezos/sc_rollup_node.mli b/tezt/lib_tezos/sc_rollup_node.mli index d84f5d913003903647576fc2685dc164cf6374d3..4a444a7ebbfb0b8adb1802006828d66bcb606942 100644 --- a/tezt/lib_tezos/sc_rollup_node.mli +++ b/tezt/lib_tezos/sc_rollup_node.mli @@ -73,6 +73,7 @@ type argument = | Mode of mode | Rollup of string | Pre_images_endpoint of string + | Apply_unsafe_patches type event = {name : string; value : JSON.t; timestamp : float} diff --git a/tezt/tests/sc_rollup.ml b/tezt/tests/sc_rollup.ml index ef4418a516fc0d0016f2257c1c0982ed6ade506a..5e25240c059eed591e62198b025a9fafaca15a06 100644 --- a/tezt/tests/sc_rollup.ml +++ b/tezt/tests/sc_rollup.ml @@ -4714,7 +4714,13 @@ let test_unsafe_genesis_patch ~private_ ~kind = (sf {| [ { "increase_max_nb_tick" : "%Ld"} ] |} max_nb_tick) ) config) ; () ; - let* () = Sc_rollup_node.run ~wait_ready:false rollup_node rollup [] in + let* () = + Sc_rollup_node.run + ~wait_ready:false + rollup_node + rollup + [Apply_unsafe_patches] + in if should_fail then let msg = if unsupported_pvm then rex "Patch .* is not supported"