diff --git a/.gitlab/ci/jobs/packaging/opam_package.yml b/.gitlab/ci/jobs/packaging/opam_package.yml index 737e99cfe6f4f71f90ad9f62069dd3635251ca94..c55e7e33cf074a3613a01a01d7cfc2bd259d2e3f 100644 --- a/.gitlab/ci/jobs/packaging/opam_package.yml +++ b/.gitlab/ci/jobs/packaging/opam_package.yml @@ -928,7 +928,7 @@ opam:tezos-client-base: opam:tezos-client-base-unix: extends: - .opam_template - - .rules_template__trigger_all_opam_batch_3 + - .rules_template__trigger_all_opam_batch_2 variables: package: tezos-client-base-unix @@ -1688,7 +1688,7 @@ opam:tezos-protocol-plugin-alpha: opam:tezos-protocol-plugin-alpha-registerer: extends: - .opam_template - - .rules_template__trigger_all_opam_batch_2 + - .rules_template__trigger_all_opam_batch_3 variables: package: tezos-protocol-plugin-alpha-registerer diff --git a/CHANGES.rst b/CHANGES.rst index 34eddeb09d277111b8b40fa32263eb42dc8e375c..2a391f61f1ca8b60fe30c89ee9305c7eacbe3c53 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -213,6 +213,8 @@ Node to output ``attesting rewards`` and ``lost attesting rewards`` kinds in the JSON result. (MR :gl:`!9253`) +- Added a syntactic operation filter in the protocol's plugins. + Client ------ - Adding client commands to generate, open and verify a time-lock. diff --git a/manifest/main.ml b/manifest/main.ml index 1584748ca344d7aaf50d705344d10343440962e3..c733a96db15301957771f255b8d58ddb6db438a6 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -5503,7 +5503,7 @@ let hash = Protocol.hash |> open_ ~m:"TzPervasives.Error_monad.Legacy_monad_globals"; embedded |> open_; plugin |> open_; - octez_shell |> open_; + octez_validation |> open_; ] ~modules:["Plugin_registerer"] ~bisect_ppx:(if N.(number >= 008) then Yes else No) diff --git a/opam/tezos-protocol-plugin-007-PsDELPH1-registerer.opam b/opam/tezos-protocol-plugin-007-PsDELPH1-registerer.opam index d169583ab899636c743a8d69442b48454d4aa839..c13568420e0aa146fea3a64032427545ad82845b 100644 --- a/opam/tezos-protocol-plugin-007-PsDELPH1-registerer.opam +++ b/opam/tezos-protocol-plugin-007-PsDELPH1-registerer.opam @@ -13,7 +13,7 @@ depends: [ "tezos-base" "tezos-embedded-protocol-007-PsDELPH1" "tezos-protocol-plugin-007-PsDELPH1" - "tezos-shell" + "tezos-validation" ] build: [ ["rm" "-r" "vendors" "contrib"] diff --git a/opam/tezos-protocol-plugin-008-PtEdo2Zk-registerer.opam b/opam/tezos-protocol-plugin-008-PtEdo2Zk-registerer.opam index 32d999ca4333e7d52b576fbd0205bff24db19ff0..5a632988fd6eab0061d258dd1907d67203f47006 100644 --- a/opam/tezos-protocol-plugin-008-PtEdo2Zk-registerer.opam +++ b/opam/tezos-protocol-plugin-008-PtEdo2Zk-registerer.opam @@ -13,7 +13,7 @@ depends: [ "tezos-base" "tezos-embedded-protocol-008-PtEdo2Zk" "tezos-protocol-plugin-008-PtEdo2Zk" - "tezos-shell" + "tezos-validation" ] build: [ ["rm" "-r" "vendors" "contrib"] diff --git a/opam/tezos-protocol-plugin-009-PsFLoren-registerer.opam b/opam/tezos-protocol-plugin-009-PsFLoren-registerer.opam index 8fd16668fdb39ece8f1fe15aca5342b9a067e63f..222d150a70978a9ecfa7db5fd0158feb60e9cb8e 100644 --- a/opam/tezos-protocol-plugin-009-PsFLoren-registerer.opam +++ b/opam/tezos-protocol-plugin-009-PsFLoren-registerer.opam @@ -13,7 +13,7 @@ depends: [ "tezos-base" "tezos-embedded-protocol-009-PsFLoren" "tezos-protocol-plugin-009-PsFLoren" - "tezos-shell" + "tezos-validation" ] build: [ ["rm" "-r" "vendors" "contrib"] diff --git a/opam/tezos-protocol-plugin-010-PtGRANAD-registerer.opam b/opam/tezos-protocol-plugin-010-PtGRANAD-registerer.opam index 19144e5d737be854ae4ad050fb262b53097ac43c..3bd57717abd1a2488e87334a64ee7298c78679a5 100644 --- a/opam/tezos-protocol-plugin-010-PtGRANAD-registerer.opam +++ b/opam/tezos-protocol-plugin-010-PtGRANAD-registerer.opam @@ -13,7 +13,7 @@ depends: [ "tezos-base" "tezos-embedded-protocol-010-PtGRANAD" "tezos-protocol-plugin-010-PtGRANAD" - "tezos-shell" + "tezos-validation" ] build: [ ["rm" "-r" "vendors" "contrib"] diff --git a/opam/tezos-protocol-plugin-011-PtHangz2-registerer.opam b/opam/tezos-protocol-plugin-011-PtHangz2-registerer.opam index 77cf70178849f164e40bbb001176ea8f1882479d..1803807fbd1ed4db8d818d3b928ab977ce97145c 100644 --- a/opam/tezos-protocol-plugin-011-PtHangz2-registerer.opam +++ b/opam/tezos-protocol-plugin-011-PtHangz2-registerer.opam @@ -13,7 +13,7 @@ depends: [ "tezos-base" "tezos-embedded-protocol-011-PtHangz2" "tezos-protocol-plugin-011-PtHangz2" - "tezos-shell" + "tezos-validation" ] build: [ ["rm" "-r" "vendors" "contrib"] diff --git a/opam/tezos-protocol-plugin-012-Psithaca-registerer.opam b/opam/tezos-protocol-plugin-012-Psithaca-registerer.opam index 00449b0d0ef065cb5a1e21427478f40737dc8d26..c3f53f1a98ad18a578991c391096934a86504456 100644 --- a/opam/tezos-protocol-plugin-012-Psithaca-registerer.opam +++ b/opam/tezos-protocol-plugin-012-Psithaca-registerer.opam @@ -13,7 +13,7 @@ depends: [ "tezos-base" "tezos-embedded-protocol-012-Psithaca" "tezos-protocol-plugin-012-Psithaca" - "tezos-shell" + "tezos-validation" ] build: [ ["rm" "-r" "vendors" "contrib"] diff --git a/opam/tezos-protocol-plugin-013-PtJakart-registerer.opam b/opam/tezos-protocol-plugin-013-PtJakart-registerer.opam index 059cb99c0033d1487139638a3c43a7dd99f79bf3..fd50249654728c0d02a887ccd9dc7fa41d56f707 100644 --- a/opam/tezos-protocol-plugin-013-PtJakart-registerer.opam +++ b/opam/tezos-protocol-plugin-013-PtJakart-registerer.opam @@ -13,7 +13,7 @@ depends: [ "tezos-base" "tezos-embedded-protocol-013-PtJakart" "tezos-protocol-plugin-013-PtJakart" - "tezos-shell" + "tezos-validation" ] build: [ ["rm" "-r" "vendors" "contrib"] diff --git a/opam/tezos-protocol-plugin-014-PtKathma-registerer.opam b/opam/tezos-protocol-plugin-014-PtKathma-registerer.opam index e024598ced02d72548ac29e0b797c3f5ed336744..97c2c5efa00a9618f4e8cc0d5b7fc145ec919ec7 100644 --- a/opam/tezos-protocol-plugin-014-PtKathma-registerer.opam +++ b/opam/tezos-protocol-plugin-014-PtKathma-registerer.opam @@ -13,7 +13,7 @@ depends: [ "tezos-base" "tezos-embedded-protocol-014-PtKathma" "tezos-protocol-plugin-014-PtKathma" - "tezos-shell" + "tezos-validation" ] build: [ ["rm" "-r" "vendors" "contrib"] diff --git a/opam/tezos-protocol-plugin-015-PtLimaPt-registerer.opam b/opam/tezos-protocol-plugin-015-PtLimaPt-registerer.opam index f5f416327402dc389f6e190079825b95d624f2e7..3f10461dc085a240f3a16c34c7a7077e01ae31c4 100644 --- a/opam/tezos-protocol-plugin-015-PtLimaPt-registerer.opam +++ b/opam/tezos-protocol-plugin-015-PtLimaPt-registerer.opam @@ -13,7 +13,7 @@ depends: [ "tezos-base" "tezos-embedded-protocol-015-PtLimaPt" "tezos-protocol-plugin-015-PtLimaPt" - "tezos-shell" + "tezos-validation" ] build: [ ["rm" "-r" "vendors" "contrib"] diff --git a/opam/tezos-protocol-plugin-016-PtMumbai-registerer.opam b/opam/tezos-protocol-plugin-016-PtMumbai-registerer.opam index 956e772a0c31f97baeaaeabb86e49a6fc421d6e4..4235e342e934cd935fb9dbce5def7586b5baa812 100644 --- a/opam/tezos-protocol-plugin-016-PtMumbai-registerer.opam +++ b/opam/tezos-protocol-plugin-016-PtMumbai-registerer.opam @@ -13,7 +13,7 @@ depends: [ "tezos-base" "tezos-embedded-protocol-016-PtMumbai" "tezos-protocol-plugin-016-PtMumbai" - "tezos-shell" + "tezos-validation" ] build: [ ["rm" "-r" "vendors" "contrib"] diff --git a/opam/tezos-protocol-plugin-017-PtNairob-registerer.opam b/opam/tezos-protocol-plugin-017-PtNairob-registerer.opam index 33e5a1f4094d3c42a9b7dfa53b5976fcfa9e9dfc..a805cee484c0a78243db98ea61885c7d22667c26 100644 --- a/opam/tezos-protocol-plugin-017-PtNairob-registerer.opam +++ b/opam/tezos-protocol-plugin-017-PtNairob-registerer.opam @@ -13,7 +13,7 @@ depends: [ "tezos-base" "tezos-embedded-protocol-017-PtNairob" "tezos-protocol-plugin-017-PtNairob" - "tezos-shell" + "tezos-validation" ] build: [ ["rm" "-r" "vendors" "contrib"] diff --git a/opam/tezos-protocol-plugin-alpha-registerer.opam b/opam/tezos-protocol-plugin-alpha-registerer.opam index fb72a67c293474f28f8e2a60871daccd3e9bc3f4..5aa84a3535cca40ba9022ef78f87560480780887 100644 --- a/opam/tezos-protocol-plugin-alpha-registerer.opam +++ b/opam/tezos-protocol-plugin-alpha-registerer.opam @@ -13,7 +13,7 @@ depends: [ "tezos-base" "tezos-embedded-protocol-alpha" "tezos-protocol-plugin-alpha" - "tezos-shell" + "tezos-validation" ] build: [ ["rm" "-r" "vendors" "contrib"] diff --git a/src/lib_shell/chain_validator.ml b/src/lib_shell/chain_validator.ml index baf0e6828baab9bf6a063ee3227b8ad92bd14ffa..f58cba23e50215b1265a0002cf4b6128ec2abf60 100644 --- a/src/lib_shell/chain_validator.ml +++ b/src/lib_shell/chain_validator.ml @@ -350,31 +350,6 @@ let may_switch_test_chain w active_chains spawn_child block = let*! () = Events.(emit could_not_switch_testchain) err in Lwt.return_unit -let safe_get_prevalidator_filter hash = - let open Lwt_syntax in - match Shell_plugin.find_filter hash with - | Some filter -> return_ok filter - | None -> ( - match Registered_protocol.get hash with - | None -> - (* FIXME. *) - (* This should not happen: it should be handled in the validator. *) - failwith - "chain_validator: missing protocol '%a' for the current block." - Protocol_hash.pp_short - hash - | Some (module Proto : Registered_protocol.T) -> - let* () = - match Proto.environment_version with - | V0 -> - (* This is normal for protocols Genesis and 000 - because they don't have a plugin. *) - Lwt.return_unit - | _ -> Events.(emit prevalidator_filter_not_found) hash - in - return_ok - (module Shell_plugin.No_filter (Proto) : Shell_plugin.FILTER)) - let instantiate_prevalidator parameters set_prevalidator block chain_db = let open Lwt_syntax in let* r = @@ -382,7 +357,9 @@ let instantiate_prevalidator parameters set_prevalidator block chain_db = let* new_protocol = Store.Block.protocol_hash parameters.chain_store block in - let* filter = safe_get_prevalidator_filter new_protocol in + let* filter = + Shell_plugin.find_filter ~block_hash:(Store.Block.hash block) new_protocol + in Prevalidator.create parameters.prevalidator_limits filter chain_db in match r with diff --git a/src/lib_shell/prevalidation.ml b/src/lib_shell/prevalidation.ml index 98424b4e51db5f220e9c38830778d7579852f7e7..5a6ebd42b17c251ced44c97359c939e3e3a67f4b 100644 --- a/src/lib_shell/prevalidation.ml +++ b/src/lib_shell/prevalidation.ml @@ -178,7 +178,14 @@ module MakeAbstract create_aux ~old_state chain_store head timestamp let pre_filter state (filter_config, (_ : Prevalidator_bounding.config)) op = - Filter.Mempool.pre_filter state.filter_info filter_config op.protocol + match Filter.Mempool.syntactic_check op.protocol with + | `Ill_formed -> + Lwt.return + (`Refused + (Error_monad.TzTrace.make + (Error_monad.error_of_fmt "Ill-formed operation filtered"))) + | `Well_formed -> + Filter.Mempool.pre_filter state.filter_info filter_config op.protocol type error_classification = Prevalidator_classification.error_classification diff --git a/src/lib_validation/block_validation.ml b/src/lib_validation/block_validation.ml index 4b4c72be3cc2802768bf070bdd84ebd08a88c648..4a7953c6d7698a4801860bfd1809a131edb7afb8 100644 --- a/src/lib_validation/block_validation.ml +++ b/src/lib_validation/block_validation.ml @@ -318,7 +318,9 @@ let may_patch_protocol ~user_activated_upgrades in return {validation_result with context} -module Make (Proto : Registered_protocol.T) = struct +module Make (Filter : Shell_plugin.FILTER) = struct + module Proto = Filter.Proto + type 'operation_data preapplied_operation = { hash : Operation_hash.t; raw : Operation.t; @@ -896,11 +898,14 @@ module Make (Proto : Registered_protocol.T) = struct in let open Lwt_result_syntax in let* validation_state = - Proto.validate_operation - ~check_signature:op.check_signature - pv.validation_state - op.hash - operation + match Filter.Mempool.syntactic_check operation with + | `Ill_formed -> failwith "Ill-formed operation filtered" + | `Well_formed -> + Proto.validate_operation + ~check_signature:op.check_signature + pv.validation_state + op.hash + operation in let* application_state, receipt = Proto.apply_operation pv.application_state op.hash operation @@ -1275,15 +1280,16 @@ module Make (Proto : Registered_protocol.T) = struct ~predecessor:predecessor_block_header.shell ~cache in + let* state = List.fold_left_es (fun state ops -> List.fold_left_es (fun state (oph, op, check_signature) -> - let* state = - Proto.validate_operation ~check_signature state oph op - in - return state) + match Filter.Mempool.syntactic_check op with + | `Ill_formed -> failwith "Ill-formed operation filtered" + | `Well_formed -> + Proto.validate_operation ~check_signature state oph op) state ops) state @@ -1376,15 +1382,10 @@ let recompute_metadata chain_id ~predecessor_block_header ~predecessor_context block_hash block_header operations = let open Lwt_result_syntax in let*! pred_protocol_hash = Context_ops.get_protocol predecessor_context in - let* (module Proto) = - match Registered_protocol.get pred_protocol_hash with - | None -> - tzfail - (Unavailable_protocol - {block = block_hash; protocol = pred_protocol_hash}) - | Some p -> return p + let* (module Filter) = + Shell_plugin.find_filter ~block_hash pred_protocol_hash in - let module Block_validation = Make (Proto) in + let module Block_validation = Make (Filter) in Block_validation.recompute_metadata chain_id ~predecessor_block_header @@ -1423,15 +1424,10 @@ let precheck ~chain_id ~predecessor_block_header ~predecessor_block_hash let open Lwt_result_syntax in let block_hash = Block_header.hash block_header in let*! pred_protocol_hash = Context_ops.get_protocol predecessor_context in - let* (module Proto) = - match Registered_protocol.get pred_protocol_hash with - | None -> - tzfail - (Unavailable_protocol - {block = block_hash; protocol = pred_protocol_hash}) - | Some p -> return p + let* (module Filter) = + Shell_plugin.find_filter ~block_hash pred_protocol_hash in - let module Block_validation = Make (Proto) in + let module Block_validation = Make (Filter) in Block_validation.precheck chain_id ~predecessor_block_header @@ -1457,16 +1453,12 @@ let apply ?simulate ?cached_result ?(should_precheck = true) } ~cache block_hash block_header operations = let open Lwt_result_syntax in let*! pred_protocol_hash = Context_ops.get_protocol predecessor_context in - let* (module Proto) = - match Registered_protocol.get pred_protocol_hash with - | None -> - tzfail - (Unavailable_protocol - {block = block_hash; protocol = pred_protocol_hash}) - | Some p -> return p + let* (module Filter) = + Shell_plugin.find_filter ~block_hash pred_protocol_hash in let* () = - if should_precheck && Proto.(compare environment_version V7 >= 0) then + if should_precheck && Filter.Proto.(compare environment_version V7 >= 0) + then precheck ~chain_id ~predecessor_block_header @@ -1478,7 +1470,7 @@ let apply ?simulate ?cached_result ?(should_precheck = true) operations else return_unit in - let module Block_validation = Make (Proto) in + let module Block_validation = Make (Filter) in Block_validation.apply ?simulate ?cached_result @@ -1545,24 +1537,16 @@ let preapply ~chain_id ~user_activated_upgrades ~predecessor_block_metadata_hash ~predecessor_ops_metadata_hash operations = let open Lwt_result_syntax in let*! protocol = Context_ops.get_protocol predecessor_context in - let* (module Proto) = - match Registered_protocol.get protocol with - | None -> - (* FIXME: https://gitlab.com/tezos/tezos/-/issues/1718 *) - (* This should not happen: it should be handled in the validator. *) - failwith - "Prevalidation: missing protocol '%a' for the current block." - Protocol_hash.pp_short - protocol - | Some protocol -> return protocol + let* (module Filter) = + Shell_plugin.find_filter ~block_hash:predecessor_hash protocol in (* The cache might be inconsistent with the context. By forcing the reloading of the cache, we restore the consistency. *) - let module Block_validation = Make (Proto) in + let module Block_validation = Make (Filter) in let* protocol_data = match Data_encoding.Binary.of_bytes_opt - Proto.block_header_data_encoding + Filter.Proto.block_header_data_encoding protocol_data with | None -> failwith "Invalid block header" diff --git a/src/lib_shell/shell_plugin.ml b/src/lib_validation/shell_plugin.ml similarity index 79% rename from src/lib_shell/shell_plugin.ml rename to src/lib_validation/shell_plugin.ml index b99d423cc2c1edd80acba3c873276196157858cf..2fa89540ac8cbd8e6629989b1e53e89c44dfb8ea 100644 --- a/src/lib_shell/shell_plugin.ml +++ b/src/lib_validation/shell_plugin.ml @@ -46,12 +46,17 @@ module type FILTER = sig head:Tezos_base.Block_header.shell_header -> filter_info tzresult Lwt.t + val syntactic_check : Proto.operation -> [`Well_formed | `Ill_formed] + val pre_filter : filter_info -> config -> Proto.operation -> - [ `Passed_prefilter of Prevalidator_pending_operations.priority - | Prevalidator_classification.error_classification ] + [ `Passed_prefilter of [`High | `Medium | `Low of Q.t list] + | `Branch_delayed of tztrace + | `Branch_refused of tztrace + | `Refused of tztrace + | `Outdated of tztrace ] Lwt.t val conflict_handler : config -> Proto.Mempool.conflict_handler @@ -102,6 +107,8 @@ module No_filter (Proto : Registered_protocol.T) : let flush _ ~head:_ = Lwt_result_syntax.return_unit + let syntactic_check _ = `Well_formed + let pre_filter _ _ _ = Lwt.return @@ `Passed_prefilter (`Low []) let conflict_handler _ ~existing_operation ~new_operation = @@ -179,4 +186,34 @@ let add_to_filter_table proto_hash filter = let register_filter (module Filter : FILTER) = add_to_filter_table Filter.Proto.hash (module Filter) -let find_filter = Protocol_hash.Table.find filter_table +let validator_filter_not_found = + Internal_event.Simple.declare_1 + ~section:["block"; "validation"] + ~name:"protocol_filter_not_found" + ~msg:"no protocol filter found for protocol {protocol_hash}" + ~level:Warning + ~pp1:Protocol_hash.pp + ("protocol_hash", Protocol_hash.encoding) + +let find_filter ~block_hash protocol_hash = + let open Lwt_result_syntax in + match Protocol_hash.Table.find filter_table protocol_hash with + | Some filter -> return filter + | None -> ( + match Registered_protocol.get protocol_hash with + | None -> + tzfail + (Block_validator_errors.Unavailable_protocol + {block = block_hash; protocol = protocol_hash}) + | Some (module Proto : Registered_protocol.T) -> + let*! () = + match Proto.environment_version with + | V0 -> + (* This is normal for protocols Genesis and 000 + because they don't have a plugin. *) + Lwt.return_unit + | _ -> + Internal_event.Simple.(emit validator_filter_not_found) + protocol_hash + in + return (module No_filter (Proto) : FILTER)) diff --git a/src/lib_shell/shell_plugin.mli b/src/lib_validation/shell_plugin.mli similarity index 91% rename from src/lib_shell/shell_plugin.mli rename to src/lib_validation/shell_plugin.mli index bbe813cf347883be9c1d1a6dd8c36e6e5047475c..1869cf3c187a4e6ecb87123c5902e5ec66d42361 100644 --- a/src/lib_shell/shell_plugin.mli +++ b/src/lib_validation/shell_plugin.mli @@ -64,6 +64,14 @@ module type FILTER = sig head:Tezos_base.Block_header.shell_header -> filter_info tzresult Lwt.t + (** Perform some syntactic checks on the operation. + + To be used mostly as an exceptional mechanism to prevent + ill-formed operations to block block application. + + Should be called before the {!pre_filter}, does not need a context. *) + val syntactic_check : Proto.operation -> [`Well_formed | `Ill_formed] + (** Perform some light preliminary checks on the operation. If successful, return [`Passed_prefilter] with the priority of the @@ -77,8 +85,11 @@ module type FILTER = sig filter_info -> config -> Proto.operation -> - [ `Passed_prefilter of Prevalidator_pending_operations.priority - | Prevalidator_classification.error_classification ] + [ `Passed_prefilter of [`High | `Medium | `Low of Q.t list] + | `Branch_delayed of tztrace + | `Branch_refused of tztrace + | `Refused of tztrace + | `Outdated of tztrace ] Lwt.t (** Return a conflict handler for [Proto.Mempool.add_operation]. @@ -182,8 +193,10 @@ val register_rpc : (module RPC) -> unit (** Register a metrics plugin module *) val register_metrics : (module METRICS) -> unit -(** Looks for a mempool filter plug-in for a specific protocol. *) -val find_filter : Protocol_hash.t -> (module FILTER) option +(** Looks for a protocol filter plug-in for a specific protocol. The + [block_hash] argument is used for the error message. *) +val find_filter : + block_hash:Block_hash.t -> Protocol_hash.t -> (module FILTER) tzresult Lwt.t (** Looks for an rpc plug-in for a specific protocol. *) val find_rpc : Protocol_hash.t -> (module RPC) option diff --git a/src/proto_007_PsDELPH1/lib_plugin/dune b/src/proto_007_PsDELPH1/lib_plugin/dune index b4f3fcd6ed5e7dc848a7b83cddc1f7e51eca9081..72b937ff6e697111b26047af068c3ccc6d59587e 100644 --- a/src/proto_007_PsDELPH1/lib_plugin/dune +++ b/src/proto_007_PsDELPH1/lib_plugin/dune @@ -21,12 +21,12 @@ tezos-base tezos-embedded-protocol-007-PsDELPH1 tezos-protocol-plugin-007-PsDELPH1 - tezos-shell) + tezos-validation) (flags (:standard) -open Tezos_base.TzPervasives -open Tezos_base.TzPervasives.Error_monad.Legacy_monad_globals -open Tezos_embedded_protocol_007_PsDELPH1 -open Tezos_protocol_plugin_007_PsDELPH1 - -open Tezos_shell) + -open Tezos_validation) (modules Plugin_registerer)) diff --git a/src/proto_008_PtEdo2Zk/lib_plugin/dune b/src/proto_008_PtEdo2Zk/lib_plugin/dune index 624c38de08ff500beaeab3a970dd3aca5d6cfd3e..fe0905f1f400411d075ea7f07d0ddb7ef36df4ff 100644 --- a/src/proto_008_PtEdo2Zk/lib_plugin/dune +++ b/src/proto_008_PtEdo2Zk/lib_plugin/dune @@ -23,12 +23,12 @@ tezos-base tezos-embedded-protocol-008-PtEdo2Zk tezos-protocol-plugin-008-PtEdo2Zk - tezos-shell) + tezos-validation) (flags (:standard) -open Tezos_base.TzPervasives -open Tezos_base.TzPervasives.Error_monad.Legacy_monad_globals -open Tezos_embedded_protocol_008_PtEdo2Zk -open Tezos_protocol_plugin_008_PtEdo2Zk - -open Tezos_shell) + -open Tezos_validation) (modules Plugin_registerer)) diff --git a/src/proto_009_PsFLoren/lib_plugin/dune b/src/proto_009_PsFLoren/lib_plugin/dune index 2e834249870384b437f9e939a57098ee3f024cdf..88c97a269bbd70d0dba8227ee6fec09ef54eb886 100644 --- a/src/proto_009_PsFLoren/lib_plugin/dune +++ b/src/proto_009_PsFLoren/lib_plugin/dune @@ -23,12 +23,12 @@ tezos-base tezos-embedded-protocol-009-PsFLoren tezos-protocol-plugin-009-PsFLoren - tezos-shell) + tezos-validation) (flags (:standard) -open Tezos_base.TzPervasives -open Tezos_base.TzPervasives.Error_monad.Legacy_monad_globals -open Tezos_embedded_protocol_009_PsFLoren -open Tezos_protocol_plugin_009_PsFLoren - -open Tezos_shell) + -open Tezos_validation) (modules Plugin_registerer)) diff --git a/src/proto_010_PtGRANAD/lib_plugin/dune b/src/proto_010_PtGRANAD/lib_plugin/dune index a249bc0db86f45356a56af0938aa6eb739c76cfb..0c21a73736e0e3806cf8a3869248189e35aa8747 100644 --- a/src/proto_010_PtGRANAD/lib_plugin/dune +++ b/src/proto_010_PtGRANAD/lib_plugin/dune @@ -23,12 +23,12 @@ tezos-base tezos-embedded-protocol-010-PtGRANAD tezos-protocol-plugin-010-PtGRANAD - tezos-shell) + tezos-validation) (flags (:standard) -open Tezos_base.TzPervasives -open Tezos_base.TzPervasives.Error_monad.Legacy_monad_globals -open Tezos_embedded_protocol_010_PtGRANAD -open Tezos_protocol_plugin_010_PtGRANAD - -open Tezos_shell) + -open Tezos_validation) (modules Plugin_registerer)) diff --git a/src/proto_011_PtHangz2/lib_plugin/dune b/src/proto_011_PtHangz2/lib_plugin/dune index f5838c36abc3df305b3e6fc96c687a2ea3256b25..be7b099664655ec45077442e20e37a36f9750b1d 100644 --- a/src/proto_011_PtHangz2/lib_plugin/dune +++ b/src/proto_011_PtHangz2/lib_plugin/dune @@ -23,12 +23,12 @@ tezos-base tezos-embedded-protocol-011-PtHangz2 tezos-protocol-plugin-011-PtHangz2 - tezos-shell) + tezos-validation) (flags (:standard) -open Tezos_base.TzPervasives -open Tezos_base.TzPervasives.Error_monad.Legacy_monad_globals -open Tezos_embedded_protocol_011_PtHangz2 -open Tezos_protocol_plugin_011_PtHangz2 - -open Tezos_shell) + -open Tezos_validation) (modules Plugin_registerer)) diff --git a/src/proto_012_Psithaca/lib_plugin/dune b/src/proto_012_Psithaca/lib_plugin/dune index edb66c2d20a2a8a0c2a5fc83237ebd427df34e38..4e11c0bb314347e9c5e37e0532cfc76e2c9b7724 100644 --- a/src/proto_012_Psithaca/lib_plugin/dune +++ b/src/proto_012_Psithaca/lib_plugin/dune @@ -23,12 +23,12 @@ tezos-base tezos-embedded-protocol-012-Psithaca tezos-protocol-plugin-012-Psithaca - tezos-shell) + tezos-validation) (flags (:standard) -open Tezos_base.TzPervasives -open Tezos_base.TzPervasives.Error_monad.Legacy_monad_globals -open Tezos_embedded_protocol_012_Psithaca -open Tezos_protocol_plugin_012_Psithaca - -open Tezos_shell) + -open Tezos_validation) (modules Plugin_registerer)) diff --git a/src/proto_013_PtJakart/lib_plugin/dune b/src/proto_013_PtJakart/lib_plugin/dune index 8afa4d74c043ed7285be0d101ef67b2d0a4bc532..0a306d1209466a738e424335964bb81cd5abf071 100644 --- a/src/proto_013_PtJakart/lib_plugin/dune +++ b/src/proto_013_PtJakart/lib_plugin/dune @@ -23,12 +23,12 @@ tezos-base tezos-embedded-protocol-013-PtJakart tezos-protocol-plugin-013-PtJakart - tezos-shell) + tezos-validation) (flags (:standard) -open Tezos_base.TzPervasives -open Tezos_base.TzPervasives.Error_monad.Legacy_monad_globals -open Tezos_embedded_protocol_013_PtJakart -open Tezos_protocol_plugin_013_PtJakart - -open Tezos_shell) + -open Tezos_validation) (modules Plugin_registerer)) diff --git a/src/proto_014_PtKathma/lib_plugin/dune b/src/proto_014_PtKathma/lib_plugin/dune index ad8aba89065067b7aa65260dc778fb31d84560fe..ff1a881658a474a5ba11d295875add0b4388223d 100644 --- a/src/proto_014_PtKathma/lib_plugin/dune +++ b/src/proto_014_PtKathma/lib_plugin/dune @@ -23,12 +23,12 @@ tezos-base tezos-embedded-protocol-014-PtKathma tezos-protocol-plugin-014-PtKathma - tezos-shell) + tezos-validation) (flags (:standard) -open Tezos_base.TzPervasives -open Tezos_base.TzPervasives.Error_monad.Legacy_monad_globals -open Tezos_embedded_protocol_014_PtKathma -open Tezos_protocol_plugin_014_PtKathma - -open Tezos_shell) + -open Tezos_validation) (modules Plugin_registerer)) diff --git a/src/proto_015_PtLimaPt/lib_plugin/dune b/src/proto_015_PtLimaPt/lib_plugin/dune index 6d1fe04877654098347f619fc0aa7696aac4c0d4..baa723a3b681dfd253bada2f02d1bd111356e976 100644 --- a/src/proto_015_PtLimaPt/lib_plugin/dune +++ b/src/proto_015_PtLimaPt/lib_plugin/dune @@ -23,12 +23,12 @@ tezos-base tezos-embedded-protocol-015-PtLimaPt tezos-protocol-plugin-015-PtLimaPt - tezos-shell) + tezos-validation) (flags (:standard) -open Tezos_base.TzPervasives -open Tezos_base.TzPervasives.Error_monad.Legacy_monad_globals -open Tezos_embedded_protocol_015_PtLimaPt -open Tezos_protocol_plugin_015_PtLimaPt - -open Tezos_shell) + -open Tezos_validation) (modules Plugin_registerer)) diff --git a/src/proto_016_PtMumbai/lib_plugin/dune b/src/proto_016_PtMumbai/lib_plugin/dune index 4b63789b72b73579e16bd4d06c17a323ca19437e..7021bb912e5096b48a157e6d1cdf4d8df7399d8d 100644 --- a/src/proto_016_PtMumbai/lib_plugin/dune +++ b/src/proto_016_PtMumbai/lib_plugin/dune @@ -25,12 +25,12 @@ tezos-base tezos-embedded-protocol-016-PtMumbai tezos-protocol-plugin-016-PtMumbai - tezos-shell) + tezos-validation) (flags (:standard) -open Tezos_base.TzPervasives -open Tezos_base.TzPervasives.Error_monad.Legacy_monad_globals -open Tezos_embedded_protocol_016_PtMumbai -open Tezos_protocol_plugin_016_PtMumbai - -open Tezos_shell) + -open Tezos_validation) (modules Plugin_registerer)) diff --git a/src/proto_016_PtMumbai/lib_plugin/mempool.ml b/src/proto_016_PtMumbai/lib_plugin/mempool.ml index 72b0b694290d59ef062e27c7e79269623ddccad4..5122404d1ad3b5e8ac2af3a56b8f657ce0ac3bbe 100644 --- a/src/proto_016_PtMumbai/lib_plugin/mempool.ml +++ b/src/proto_016_PtMumbai/lib_plugin/mempool.ml @@ -508,6 +508,8 @@ let pre_filter_far_future_consensus_ops filter_info config in match res with Ok b -> Lwt.return b | Error _ -> Lwt.return_false +let syntactic_check _ = `Well_formed + (** A quasi infinite amount of "valid" (pre)endorsements could be sent by a committee member, one for each possible round number. diff --git a/src/proto_016_PtMumbai/lib_plugin/mempool.mli b/src/proto_016_PtMumbai/lib_plugin/mempool.mli index 97d1cad6f8f681c722a29db8167f88b95bbbf093..76c2a8f9347b2c7bf050baddd835132decec015e 100644 --- a/src/proto_016_PtMumbai/lib_plugin/mempool.mli +++ b/src/proto_016_PtMumbai/lib_plugin/mempool.mli @@ -66,6 +66,15 @@ val init : val flush : filter_info -> head:Block_header.shell_header -> filter_info tzresult Lwt.t +(** Perform some syntactic checks on the operation. + + To be used mostly as an exceptional mechanism to prevent + ill-formed operations to block block application. + + Should be called before the {!pre_filter}, does not need a context. *) +val syntactic_check : + Protocol.Alpha_context.packed_operation -> [`Well_formed | `Ill_formed] + (** Perform some preliminary checks on an operation. For manager operations, check that its fee, fee/gas ratio, and diff --git a/src/proto_017_PtNairob/lib_plugin/dune b/src/proto_017_PtNairob/lib_plugin/dune index 2c59eac8e4ed9a6966579ea08a7239a8a14483a1..250c70cf1842f229dc2274d51e2479c6ac5f665b 100644 --- a/src/proto_017_PtNairob/lib_plugin/dune +++ b/src/proto_017_PtNairob/lib_plugin/dune @@ -25,12 +25,12 @@ tezos-base tezos-embedded-protocol-017-PtNairob tezos-protocol-plugin-017-PtNairob - tezos-shell) + tezos-validation) (flags (:standard) -open Tezos_base.TzPervasives -open Tezos_base.TzPervasives.Error_monad.Legacy_monad_globals -open Tezos_embedded_protocol_017_PtNairob -open Tezos_protocol_plugin_017_PtNairob - -open Tezos_shell) + -open Tezos_validation) (modules Plugin_registerer)) diff --git a/src/proto_017_PtNairob/lib_plugin/mempool.ml b/src/proto_017_PtNairob/lib_plugin/mempool.ml index 72b0b694290d59ef062e27c7e79269623ddccad4..246611ecde615d161173bdde585459f880e38ee9 100644 --- a/src/proto_017_PtNairob/lib_plugin/mempool.ml +++ b/src/proto_017_PtNairob/lib_plugin/mempool.ml @@ -269,6 +269,63 @@ let weight_and_resources_manager_operation ~hard_gas_limit_per_block ?size ~fee let resources = Q.max size_ratio gas_ratio in (Q.(fee_f / resources), resources) +let output_proof_encoding = + let open Data_encoding in + obj3 + (req + "output_proof" + Sc_rollup_wasm.V2_0_0.Protocol_implementation.proof_encoding) + (req "output_proof_state" Sc_rollup.State_hash.encoding) + (req "output_proof_output" Variable.bytes) + +let kinded_hash_to_state_hash = function + | `Value hash | `Node hash -> + Sc_rollup.State_hash.context_hash_to_state_hash hash + +let is_invalid_op : type t. t manager_operation -> bool = function + | Sc_rollup_execute_outbox_message + {rollup = _; cemented_commitment = _; output_proof} -> ( + match + Data_encoding.Binary.of_string_opt output_proof_encoding output_proof + with + | None -> true + | Some (output_proof, output_proof_state, _) -> + not + (Sc_rollup.State_hash.equal + output_proof_state + (kinded_hash_to_state_hash + output_proof.Environment.Context.Proof.before))) + | _ -> false + +let rec contains_invalid_op : type t. t Kind.manager contents_list -> bool = + function + | Single (Manager_operation {operation; _}) -> is_invalid_op operation + | Cons (Manager_operation {operation; _}, rest) -> + is_invalid_op operation || contains_invalid_op rest + +let syntactic_check + ({shell = _; protocol_data = Operation_data {contents; _}} : Main.operation) + = + match contents with + | Single (Failing_noop _) + | Single (Preendorsement _) + | Single (Endorsement _) + | Single (Dal_attestation _) + | Single (Seed_nonce_revelation _) + | Single (Double_preendorsement_evidence _) + | Single (Double_endorsement_evidence _) + | Single (Double_baking_evidence _) + | Single (Activate_account _) + | Single (Proposals _) + | Single (Vdf_revelation _) + | Single (Drain_delegate _) + | Single (Ballot _) -> + `Well_formed + | Single (Manager_operation _) as op -> + if contains_invalid_op op then `Ill_formed else `Well_formed + | Cons (Manager_operation _, _) as op -> + if contains_invalid_op op then `Ill_formed else `Well_formed + let pre_filter_manager : type t. filter_info -> diff --git a/src/proto_017_PtNairob/lib_plugin/mempool.mli b/src/proto_017_PtNairob/lib_plugin/mempool.mli index 97d1cad6f8f681c722a29db8167f88b95bbbf093..76c2a8f9347b2c7bf050baddd835132decec015e 100644 --- a/src/proto_017_PtNairob/lib_plugin/mempool.mli +++ b/src/proto_017_PtNairob/lib_plugin/mempool.mli @@ -66,6 +66,15 @@ val init : val flush : filter_info -> head:Block_header.shell_header -> filter_info tzresult Lwt.t +(** Perform some syntactic checks on the operation. + + To be used mostly as an exceptional mechanism to prevent + ill-formed operations to block block application. + + Should be called before the {!pre_filter}, does not need a context. *) +val syntactic_check : + Protocol.Alpha_context.packed_operation -> [`Well_formed | `Ill_formed] + (** Perform some preliminary checks on an operation. For manager operations, check that its fee, fee/gas ratio, and diff --git a/src/proto_alpha/lib_plugin/dune b/src/proto_alpha/lib_plugin/dune index d68db6e047471cf25517c61fe7b66cd7f03587a3..c0ae384ad9c5fd2d0ea68ca9086a4ae999bf26d7 100644 --- a/src/proto_alpha/lib_plugin/dune +++ b/src/proto_alpha/lib_plugin/dune @@ -25,12 +25,12 @@ tezos-base tezos-embedded-protocol-alpha tezos-protocol-plugin-alpha - tezos-shell) + tezos-validation) (flags (:standard) -open Tezos_base.TzPervasives -open Tezos_base.TzPervasives.Error_monad.Legacy_monad_globals -open Tezos_embedded_protocol_alpha -open Tezos_protocol_plugin_alpha - -open Tezos_shell) + -open Tezos_validation) (modules Plugin_registerer)) diff --git a/src/proto_alpha/lib_plugin/mempool.ml b/src/proto_alpha/lib_plugin/mempool.ml index 4a939a41946605dc912d6ee432823187b45cdcdc..c9386fbaba26a05c089bbf99c10968d15da95d59 100644 --- a/src/proto_alpha/lib_plugin/mempool.ml +++ b/src/proto_alpha/lib_plugin/mempool.ml @@ -557,6 +557,8 @@ let pre_filter filter_info config | Single (Manager_operation _) as op -> prefilter_manager_op op | Cons (Manager_operation _, _) as op -> prefilter_manager_op op +let syntactic_check _ = `Well_formed + let is_manager_operation op = match Operation.acceptable_pass op with | Some pass -> Compare.Int.equal pass Operation_repr.manager_pass diff --git a/src/proto_alpha/lib_plugin/mempool.mli b/src/proto_alpha/lib_plugin/mempool.mli index 97d1cad6f8f681c722a29db8167f88b95bbbf093..d50404525979c24f4dbb6e53d4cf3804c71fc3d2 100644 --- a/src/proto_alpha/lib_plugin/mempool.mli +++ b/src/proto_alpha/lib_plugin/mempool.mli @@ -66,6 +66,15 @@ val init : val flush : filter_info -> head:Block_header.shell_header -> filter_info tzresult Lwt.t +(** Perform some syntactic checks on the operation. + + To be used mostly as an exceptional mechanism to prevent + ill-formed operations to block block application. + + Should be called before the {!pre_filter}, does not need a context. *) +val syntactic_check : + Protocol.Alpha_context.packed_operation -> [`Well_formed | `Ill_formed] + (** Perform some preliminary checks on an operation. For manager operations, check that its fee, fee/gas ratio, and