diff --git a/src/lib_shell/prevalidation.ml b/src/lib_shell/prevalidation.ml index 8081b3aef73c144b83df934c2d47fbf72d5265bb..c369e5edd073a0bd36aee6453b1c79070d525ce1 100644 --- a/src/lib_shell/prevalidation.ml +++ b/src/lib_shell/prevalidation.ml @@ -176,16 +176,7 @@ module MakeAbstract create_aux ~old_state chain_store head timestamp let pre_filter state (filter_config, (_ : Prevalidator_bounding.config)) op = - let open Lwt_syntax in - let* status = Proto.Plugin.syntactic_check op.protocol in - match status with - | `Ill_formed -> - Lwt.return - (`Refused - (Error_monad.TzTrace.make - (Error_monad.error_of_fmt "Ill-formed operation filtered"))) - | `Well_formed -> - Proto.Plugin.pre_filter state.plugin_info filter_config op.protocol + Proto.Plugin.pre_filter state.plugin_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 c1c1fa1e7ade2b8f1f278543415799f735ca25a5..73438c89e7be033a23d46b0fb5df527b2f5c89bf 100644 --- a/src/lib_validation/block_validation.ml +++ b/src/lib_validation/block_validation.ml @@ -896,16 +896,12 @@ module Make (Proto : Protocol_plugin.T) = struct {shell = op.raw.shell; protocol_data = op.protocol_data} in let open Lwt_result_syntax in - let*! status = Proto.Plugin.syntactic_check operation in let* validation_state = - match status with - | `Ill_formed -> failwith "Ill-formed operation filtered" - | `Well_formed -> - Proto.validate_operation - ~check_signature:op.check_signature - pv.validation_state - op.hash - operation + 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 @@ -1286,11 +1282,7 @@ module Make (Proto : Protocol_plugin.T) = struct (fun state ops -> List.fold_left_es (fun state (oph, op, check_signature) -> - let*! status = Proto.Plugin.syntactic_check op in - match status with - | `Ill_formed -> failwith "Ill-formed operation filtered" - | `Well_formed -> - Proto.validate_operation ~check_signature state oph op) + Proto.validate_operation ~check_signature state oph op) state ops) state diff --git a/src/lib_validation/protocol_plugin.ml b/src/lib_validation/protocol_plugin.ml index 28d763c6d7c137d603c96ace683108ec560bd395..66cb80a08ae3a8242f4b79aca06b9a0ba22ab58c 100644 --- a/src/lib_validation/protocol_plugin.ml +++ b/src/lib_validation/protocol_plugin.ml @@ -193,25 +193,79 @@ let validation_plugin_not_found = ~pp1:Protocol_hash.pp ("protocol_hash", Protocol_hash.encoding) +type error += Ill_formed_operation of Operation_hash.t + +let () = + register_error_kind + `Permanent + ~id:"validation.plugin.ill_formed_operation" + ~title:"Ill_formed_operation" + ~description:"Ill-formed operation filtered" + ~pp:(fun ppf oph -> + Format.fprintf + ppf + "Ill-formed operation filtered: %a." + Operation_hash.pp + oph) + Data_encoding.(obj1 (req "operation_hash" Operation_hash.encoding)) + (function Ill_formed_operation oph -> Some oph | _ -> None) + (fun oph -> Ill_formed_operation oph) + +module Patch_T (Proto : T) : T = struct + include Proto + + let validate_operation ?check_signature validation_state oph op = + let open Lwt_syntax in + let* status = Proto.Plugin.syntactic_check op in + match status with + | `Ill_formed -> Lwt_result_syntax.tzfail (Ill_formed_operation oph) + | `Well_formed -> + Proto.validate_operation ?check_signature validation_state oph op + + module Mempool = struct + include Proto.Mempool + + let add_operation ?check_signature ?conflict_handler validation_info + mempool_state (oph, op) = + let open Lwt_syntax in + let* status = Proto.Plugin.syntactic_check op in + match status with + | `Ill_formed -> + Lwt.return_error + (Proto.Mempool.Validation_error + (TzTrace.make (Ill_formed_operation oph))) + | `Well_formed -> + Proto.Mempool.add_operation + ?check_signature + ?conflict_handler + validation_info + mempool_state + (oph, op) + end +end + let proto_with_validation_plugin ~block_hash protocol_hash = let open Lwt_result_syntax in - match Protocol_hash.Table.find validation_plugin_table protocol_hash with - | Some proto_with_plugin -> return proto_with_plugin - | 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 validation_plugin_not_found) - protocol_hash - in - return (module No_plugin (Proto) : T)) + let* (module Proto_with_plugin) = + match Protocol_hash.Table.find validation_plugin_table protocol_hash with + | Some proto_with_plugin -> return proto_with_plugin + | 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 validation_plugin_not_found) + protocol_hash + in + return (module No_plugin (Proto) : T)) + in + return (module Patch_T (Proto_with_plugin) : T) diff --git a/src/lib_validation/protocol_plugin.mli b/src/lib_validation/protocol_plugin.mli index 73177d9b3d821e4f0845db5f2df199809c48afc3..f3461dd252e0cb26ff74ef56d7ddc9ecf4f5966b 100644 --- a/src/lib_validation/protocol_plugin.mli +++ b/src/lib_validation/protocol_plugin.mli @@ -68,7 +68,9 @@ module type T = sig 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. *) + Note that the functions exposed in the output of + {!proto_with_validation_plugin} already call [syntactic_check] + when appropriate. *) val syntactic_check : operation -> [`Well_formed | `Ill_formed] Lwt.t (** Perform some light preliminary checks on the operation.