From c17f04dfbccdbe2c4c86f0e4bab21b2ed253cc38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Thir=C3=A9?= Date: Tue, 14 Jan 2025 17:11:57 +0100 Subject: [PATCH 1/5] Manifest: The DAL plugin depends on Octez shell services --- manifest/product_octez.ml | 1 + src/proto_020_PsParisC/lib_dal/dune | 2 ++ src/proto_021_PsQuebec/lib_dal/dune | 2 ++ src/proto_alpha/lib_dal/dune | 2 ++ 4 files changed, 7 insertions(+) diff --git a/manifest/product_octez.ml b/manifest/product_octez.ml index fc32fd9b2b48..3a55338397a6 100644 --- a/manifest/product_octez.ml +++ b/manifest/product_octez.ml @@ -6889,6 +6889,7 @@ let hash = Protocol.hash |> error_monad_module N.(number <= 018); octez_protocol_compiler_registerer |> open_; octez_stdlib_unix |> open_; + octez_shell_services |> open_; octez_dal_node_lib |> open_; client |> if_some |> open_; plugin |> if_some |> open_; diff --git a/src/proto_020_PsParisC/lib_dal/dune b/src/proto_020_PsParisC/lib_dal/dune index 49958af8559f..fd0e4457c4c1 100644 --- a/src/proto_020_PsParisC/lib_dal/dune +++ b/src/proto_020_PsParisC/lib_dal/dune @@ -9,6 +9,7 @@ octez-libs.base octez-protocol-compiler.registerer octez-libs.stdlib-unix + octez-shell-libs.shell-services tezos-dal-node-lib octez-protocol-020-PsParisC-libs.client octez-protocol-020-PsParisC-libs.plugin @@ -28,6 +29,7 @@ -open Tezos_base.TzPervasives -open Tezos_protocol_registerer -open Tezos_stdlib_unix + -open Tezos_shell_services -open Tezos_dal_node_lib -open Tezos_client_020_PsParisC -open Tezos_protocol_plugin_020_PsParisC diff --git a/src/proto_021_PsQuebec/lib_dal/dune b/src/proto_021_PsQuebec/lib_dal/dune index 65fb946cd70f..2bc3c492d48d 100644 --- a/src/proto_021_PsQuebec/lib_dal/dune +++ b/src/proto_021_PsQuebec/lib_dal/dune @@ -9,6 +9,7 @@ octez-libs.base octez-protocol-compiler.registerer octez-libs.stdlib-unix + octez-shell-libs.shell-services tezos-dal-node-lib octez-protocol-021-PsQuebec-libs.client octez-protocol-021-PsQuebec-libs.plugin @@ -28,6 +29,7 @@ -open Tezos_base.TzPervasives -open Tezos_protocol_registerer -open Tezos_stdlib_unix + -open Tezos_shell_services -open Tezos_dal_node_lib -open Tezos_client_021_PsQuebec -open Tezos_protocol_plugin_021_PsQuebec diff --git a/src/proto_alpha/lib_dal/dune b/src/proto_alpha/lib_dal/dune index 6efe42b5f1d7..f261457a9a5e 100644 --- a/src/proto_alpha/lib_dal/dune +++ b/src/proto_alpha/lib_dal/dune @@ -9,6 +9,7 @@ octez-libs.base octez-protocol-compiler.registerer octez-libs.stdlib-unix + octez-shell-libs.shell-services tezos-dal-node-lib octez-protocol-alpha-libs.client octez-protocol-alpha-libs.plugin @@ -28,6 +29,7 @@ -open Tezos_base.TzPervasives -open Tezos_protocol_registerer -open Tezos_stdlib_unix + -open Tezos_shell_services -open Tezos_dal_node_lib -open Tezos_client_alpha -open Tezos_protocol_plugin_alpha -- GitLab From 45f347c1a4b84669fad1d1bff3a27027677c32d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Thir=C3=A9?= Date: Tue, 14 Jan 2025 17:12:16 +0100 Subject: [PATCH 2/5] Proto/Paris: Implement a fallback for injecting entrpament evidence --- .../lib_dal/dal_plugin_registration.ml | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/proto_020_PsParisC/lib_dal/dal_plugin_registration.ml b/src/proto_020_PsParisC/lib_dal/dal_plugin_registration.ml index 654898ba401f..b6d44f6c9fd0 100644 --- a/src/proto_020_PsParisC/lib_dal/dal_plugin_registration.ml +++ b/src/proto_020_PsParisC/lib_dal/dal_plugin_registration.ml @@ -72,6 +72,26 @@ module Plugin = struct blocks_per_cycle = parametric.blocks_per_cycle; } + type error += DAL_accusation_not_available + + let () = + register_error_kind + `Permanent + ~id:"dal_accusation_not_available_paris" + ~title:"DAL accusation not available on Paris" + ~description:"DAL accusation is not available in protocol Paris." + ~pp:(fun fmt () -> + Format.fprintf fmt "DAL accusation is not available in protocol Paris") + Data_encoding.unit + (function DAL_accusation_not_available -> Some () | _ -> None) + (fun () -> DAL_accusation_not_available) + + let inject_entrapment_evidence _cctxt ~attested_level:_ _attestation + ~slot_index:_ ~shard:_ ~proof:_ = + let open Lwt_result_syntax in + (* This is supposed to be dead code, but we implement a fallback to be defensive. *) + fail [DAL_accusation_not_available] + let block_info ?chain ?block ~metadata ctxt = let cpctxt = new Protocol_client_context.wrap_rpc_context ctxt in Protocol_client_context.Alpha_block_services.info -- GitLab From ec8531f8e963de73d5fd26bd6541527b709cc977 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Thir=C3=A9?= Date: Tue, 14 Jan 2025 17:12:55 +0100 Subject: [PATCH 3/5] Proto/Quebec: Implement a fallback for injecting entrpament evidence --- .../lib_dal/dal_plugin_registration.ml | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) 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 9b752919c95b..79b5fec08a73 100644 --- a/src/proto_021_PsQuebec/lib_dal/dal_plugin_registration.ml +++ b/src/proto_021_PsQuebec/lib_dal/dal_plugin_registration.ml @@ -72,6 +72,26 @@ module Plugin = struct blocks_per_cycle = parametric.blocks_per_cycle; } + type error += DAL_accusation_not_available + + let () = + register_error_kind + `Permanent + ~id:"dal_accusation_not_available_quebec" + ~title:"DAL accusation not available on Quebec" + ~description:"DAL accusation is not available in protocol Quebec." + ~pp:(fun fmt () -> + Format.fprintf fmt "DAL accusation is not available in protocol Quebec") + Data_encoding.unit + (function DAL_accusation_not_available -> Some () | _ -> None) + (fun () -> DAL_accusation_not_available) + + let inject_entrapment_evidence _cctxt ~attested_level:_ _attestation + ~slot_index:_ ~shard:_ ~proof:_ = + let open Lwt_result_syntax in + (* This is supposed to be dead code, but we implement a fallback to be defensive. *) + fail [DAL_accusation_not_available] + let block_info ?chain ?block ~metadata ctxt = let cpctxt = new Protocol_client_context.wrap_rpc_context ctxt in Protocol_client_context.Alpha_block_services.info -- GitLab From 49e7ab9d88fb778137e39dea7050e0ffb7131bd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Thir=C3=A9?= Date: Tue, 14 Jan 2025 17:13:06 +0100 Subject: [PATCH 4/5] Proto/Alpha: Forge and inject an entrapment evidence --- .../lib_dal/dal_plugin_registration.ml | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/src/proto_alpha/lib_dal/dal_plugin_registration.ml b/src/proto_alpha/lib_dal/dal_plugin_registration.ml index 104451287206..4bd4a866b113 100644 --- a/src/proto_alpha/lib_dal/dal_plugin_registration.ml +++ b/src/proto_alpha/lib_dal/dal_plugin_registration.ml @@ -74,6 +74,87 @@ module Plugin = struct blocks_per_cycle = parametric.blocks_per_cycle; } + (* We choose a previous offset (5 blocks from head) to ensure that the + injected operation is branched from a valid + predecessor. Denunciation operations can be emitted when the + consensus is under attack and may occur so you want to inject the + operation from a block which is considered "final". *) + let get_block_offset ~offset level = + let open Lwt_syntax in + let offset_int32 = Raw_level.of_int32_exn (Int32.of_int offset) in + let level_with_offset = Raw_level.diff level offset_int32 in + if Compare.Int32.(level_with_offset >= 0l) then return (`Head offset) + else return (`Head 0) + + (* We can provide more context in the future. *) + type error += Not_an_attestation + + let () = + register_error_kind + `Permanent + ~id:"not_an_attestation" + ~title:"Not an attestation" + ~description: + "This error is raised if the DAL node tries to accuse with an \ + operation which is not an attestation" + ~pp:(fun fmt () -> + Format.fprintf + fmt + "This error is raised if the DAL node tries to accuse with an \ + operation which is not an attestation") + Data_encoding.unit + (function Not_an_attestation -> Some () | _ -> None) + (fun () -> Not_an_attestation) + + let inject_entrapment_evidence cctxt ~attested_level operation ~slot_index + ~shard ~proof = + let open Lwt_result_syntax in + let cpctxt = new Protocol_client_context.wrap_rpc_context cctxt in + let chain = `Main in + let*? attested_level = + Raw_level.of_int32 attested_level |> Environment.wrap_tzresult + in + let*! block = get_block_offset ~offset:5 attested_level in + let* {dal = {number_of_slots; _}; _} = + (* Let's use Head. In practice the number of slots of `Head will + be greater. If the slot index is not valid, in any case it + will be caught by the forge or during the injection. *) + Protocol.Constants_services.parametric cpctxt (chain, `Head 0) + in + (* If the number of slots changes between two protocol, the call + could fail while it should succeed. This is a corner case to + solve in the future (or just apply a retry policy). *) + let*? slot_index = + Dal.Slot_index.of_int ~number_of_slots slot_index + |> Environment.wrap_tzresult + in + let* block_hash = + Protocol_client_context.Alpha_block_services.hash cctxt ~chain ~block () + in + let shard_with_proof = Dal.Shard_with_proof.{shard; proof} in + match operation.protocol_data with + | Operation_data protocol_data -> ( + match protocol_data.contents with + | Single (Attestation _) -> + let attestation : Kind.attestation Alpha_context.operation = + {shell = operation.shell; protocol_data} + in + let* bytes = + Plugin.RPC.Forge.dal_entrapment_evidence + cpctxt + (chain, block) + ~branch:block_hash + ~attestation + ~slot_index + ~shard_with_proof + in + let bytes = Signature.concat bytes Signature.zero in + let* _op_hash = + Shell_services.Injection.operation cctxt ~chain bytes + in + return_unit + | _ -> fail [Not_an_attestation]) + let block_info ?chain ?block ~metadata ctxt = let cpctxt = new Protocol_client_context.wrap_rpc_context ctxt in Protocol_client_context.Alpha_block_services.info -- GitLab From 959373e225802641d8ba5c622d92d7090f8830ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Thir=C3=A9?= Date: Tue, 14 Jan 2025 17:13:23 +0100 Subject: [PATCH 5/5] DAL/Node: Enable to inject an entrapment evidence --- src/lib_dal_node/dal_plugin.ml | 9 +++++++++ src/lib_dal_node/dal_plugin.mli | 11 +++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/lib_dal_node/dal_plugin.ml b/src/lib_dal_node/dal_plugin.ml index f0bcca8cd694..d3aff5755d91 100644 --- a/src/lib_dal_node/dal_plugin.ml +++ b/src/lib_dal_node/dal_plugin.ml @@ -161,6 +161,15 @@ module type T = sig val block_shell_header : block_info -> Block_header.shell_header + val inject_entrapment_evidence : + Tezos_rpc.Context.generic -> + attested_level:Int32.t -> + Proto.operation -> + slot_index:slot_index -> + shard:Cryptobox.shard -> + proof:Cryptobox.shard_proof -> + unit tzresult Lwt.t + (* Section of helpers for Skip lists *) module Skip_list : sig diff --git a/src/lib_dal_node/dal_plugin.mli b/src/lib_dal_node/dal_plugin.mli index 4bc7f0429ab2..0fb0a8420ca1 100644 --- a/src/lib_dal_node/dal_plugin.mli +++ b/src/lib_dal_node/dal_plugin.mli @@ -120,6 +120,17 @@ module type T = sig whose information are given . *) val block_shell_header : block_info -> Block_header.shell_header + (** Call this function to inject an entrapment evidence to the + corresponding L1 node. *) + val inject_entrapment_evidence : + Tezos_rpc.Context.generic -> + attested_level:Int32.t -> + Proto.operation -> + slot_index:slot_index -> + shard:Cryptobox.shard -> + proof:Cryptobox.shard_proof -> + unit tzresult Lwt.t + (* Section of helpers for Skip lists *) module Skip_list : sig -- GitLab