diff --git a/src/lib_dal_node/accuser.ml b/src/lib_dal_node/accuser.ml index fa5a57e05c315155af1b4f482e91e72e9abe83df..26c6ac402aecb924dfc525764f7c05cb33f91618 100644 --- a/src/lib_dal_node/accuser.ml +++ b/src/lib_dal_node/accuser.ml @@ -10,13 +10,13 @@ their corresponding attestation operation and DAL attestation. *) let get_attestation_map attestations = List.fold_left - (fun map (_tb_slot, delegate_opt, operation, dal_attestation) -> + (fun map (tb_slot, delegate_opt, operation, dal_attestation) -> match delegate_opt with | None -> map | Some delegate -> Signature.Public_key_hash.Map.add delegate - (operation, dal_attestation) + (operation, dal_attestation, tb_slot) map) Signature.Public_key_hash.Map.empty attestations @@ -36,17 +36,18 @@ let filter_injectable_traps attestation_map traps = (* The delegate did not TB attest or we have not found the delegate in the attestation operation's receipt. *) None - | Some (_attestation, None) -> + | Some (_attestation, None, _tb_slot) -> (* The delegate did not DAL attest. *) None - | Some (attestation, Some dal_attestation) -> + | Some (attestation, Some dal_attestation, tb_slot) -> Some ( delegate, slot_index, attestation, dal_attestation, shard, - shard_proof )) + shard_proof, + tb_slot )) traps (* [inject_entrapment_evidences] processes and injects trap evidence @@ -56,11 +57,13 @@ let filter_injectable_traps attestation_map traps = Guarded by [proto_parameters.incentives_enable]. *) -let inject_entrapment_evidences (type attestation_operation dal_attestation) +let inject_entrapment_evidences + (type attestation_operation dal_attestation tb_slot) (module Plugin : Dal_plugin.T with type attestation_operation = attestation_operation - and type dal_attestation = dal_attestation) attestations node_ctxt - rpc_ctxt ~attested_level = + and type dal_attestation = dal_attestation + and type tb_slot = tb_slot) attestations node_ctxt rpc_ctxt + ~attested_level = let open Lwt_result_syntax in let*? proto_parameters = Node_context.get_proto_parameters node_ctxt ~level:(`Level attested_level) @@ -86,7 +89,8 @@ let inject_entrapment_evidences (type attestation_operation dal_attestation) attestation, dal_attestation, shard, - shard_proof ) -> + shard_proof, + tb_slot ) -> if Plugin.is_attested dal_attestation slot_index then let*! () = Event.emit_trap_injection @@ -104,6 +108,7 @@ let inject_entrapment_evidences (type attestation_operation dal_attestation) ~slot_index ~shard ~proof:shard_proof + ~tb_slot in match res with | Ok () -> return_unit diff --git a/src/lib_dal_node/accuser.mli b/src/lib_dal_node/accuser.mli index e17ddfd814454696e1864e4384f8d47d0d5c1914..ff0f63a3b8abe14191f1be32af777d82ba96d387 100644 --- a/src/lib_dal_node/accuser.mli +++ b/src/lib_dal_node/accuser.mli @@ -16,8 +16,9 @@ val inject_entrapment_evidences : (module Dal_plugin.T with type attestation_operation = 'attestation_operation - and type dal_attestation = 'dal_attestation) -> - (int + and type dal_attestation = 'dal_attestation + and type tb_slot = 'tb_slot) -> + ('tb_slot * Signature.public_key_hash option * 'attestation_operation * 'dal_attestation option) diff --git a/src/lib_dal_node/dal_plugin.ml b/src/lib_dal_node/dal_plugin.ml index 8730ab5901fca6195945b592d8a885c7860806de..5d1f8447c8c775c60fe56fb238d0b5113db84d79 100644 --- a/src/lib_dal_node/dal_plugin.ml +++ b/src/lib_dal_node/dal_plugin.ml @@ -42,6 +42,8 @@ module type T = sig type attestation_operation + type tb_slot + val block_info : ?chain:Tezos_shell_services.Block_services.chain -> ?block:Tezos_shell_services.Block_services.block -> @@ -63,7 +65,7 @@ module type T = sig val get_attestations : block_level:int32 -> Tezos_rpc__RPC_context.generic -> - (int + (tb_slot * Signature.public_key_hash option * attestation_operation * dal_attestation option) @@ -93,6 +95,7 @@ module type T = sig slot_index:slot_index -> shard:Cryptobox.shard -> proof:Cryptobox.shard_proof -> + tb_slot:tb_slot -> unit tzresult Lwt.t val is_delegate : diff --git a/src/lib_dal_node/dal_plugin.mli b/src/lib_dal_node/dal_plugin.mli index 1671f7dbd2363a454c215611d30301f5efae8038..dcaf9662aa6f10a9593a55235bdff8754e0c3309 100644 --- a/src/lib_dal_node/dal_plugin.mli +++ b/src/lib_dal_node/dal_plugin.mli @@ -51,6 +51,8 @@ module type T = sig type attestation_operation + type tb_slot + (** [block_info ?chain ?block ~metadata ctxt] returns the information of the [block] in [ctxt] for the given [chain]. Block's metadata are included or skipped depending on the value of [metadata]. This is a wrapper on top of @@ -81,7 +83,7 @@ module type T = sig val get_attestations : block_level:int32 -> Tezos_rpc__RPC_context.generic -> - (int + (tb_slot * Signature.public_key_hash option * attestation_operation * dal_attestation option) @@ -128,6 +130,7 @@ module type T = sig slot_index:slot_index -> shard:Cryptobox.shard -> proof:Cryptobox.shard_proof -> + tb_slot:tb_slot -> unit tzresult Lwt.t val is_delegate : 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 796e59d7dc92c98d8a925d973d8b3a5928a18112..79de163f2bc99b27ea2dc89c988ce264ae46416e 100644 --- a/src/proto_021_PsQuebec/lib_dal/dal_plugin_registration.ml +++ b/src/proto_021_PsQuebec/lib_dal/dal_plugin_registration.ml @@ -37,6 +37,8 @@ module Plugin = struct type attestation_operation = Kind.attestation Alpha_context.operation + type tb_slot = int + let parametric_constants chain block ctxt = let cpctxt = new Protocol_client_context.wrap_rpc_context ctxt in Protocol.Constants_services.parametric cpctxt (chain, block) @@ -89,7 +91,7 @@ module Plugin = struct (fun () -> DAL_accusation_not_available) let inject_entrapment_evidence _cctxt ~attested_level:_ _attestation - ~slot_index:_ ~shard:_ ~proof:_ = + ~slot_index:_ ~shard:_ ~proof:_ ~tb_slot:_ = 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] 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 943d2ce78a203520cadf6d95bd854a9cfaedaf85..818d80be104fe9023f0d2b8f93e3ed1b6ddcae8c 100644 --- a/src/proto_022_PsRiotum/lib_dal/dal_plugin_registration.ml +++ b/src/proto_022_PsRiotum/lib_dal/dal_plugin_registration.ml @@ -37,6 +37,8 @@ module Plugin = struct type attestation_operation = Kind.attestation Alpha_context.operation + type tb_slot = int + let parametric_constants chain block ctxt = let cpctxt = new Protocol_client_context.wrap_rpc_context ctxt in Protocol.Constants_services.parametric cpctxt (chain, block) @@ -89,7 +91,7 @@ module Plugin = struct else return (`Head 0) let inject_entrapment_evidence cctxt ~attested_level - (operation : attestation_operation) ~slot_index ~shard ~proof = + (operation : attestation_operation) ~slot_index ~shard ~proof ~tb_slot:_ = let open Lwt_result_syntax in let cpctxt = new Protocol_client_context.wrap_rpc_context cctxt in let chain = `Main in diff --git a/src/proto_alpha/lib_dal/dal_plugin_registration.ml b/src/proto_alpha/lib_dal/dal_plugin_registration.ml index bdb5d21a15b6a5d575c0dce1ab010d4362235111..f3ad19ecc43b27dbfb052e0dc8e047b8f4ddbfa0 100644 --- a/src/proto_alpha/lib_dal/dal_plugin_registration.ml +++ b/src/proto_alpha/lib_dal/dal_plugin_registration.ml @@ -35,7 +35,29 @@ module Plugin = struct type dal_attestation = Environment.Bitset.t - type attestation_operation = Kind.attestation Alpha_context.operation + type attestation_operation = + | Op : 'a Kind.consensus Alpha_context.operation -> attestation_operation + + type tb_slot = Slot.t + + type error += Aggregation_result_size_error + + let () = + register_error_kind + `Permanent + ~id:"Aggregation_result_size_error" + ~title:"Bad aggregagtion result size" + ~description: + "Aggregation result should have as many elements as the original \ + aggregated attestation" + ~pp:(fun ppf () -> + Format.fprintf + ppf + "Aggregation result should have as many elements as the original \ + aggregated attestation") + Data_encoding.unit + (function Aggregation_result_size_error -> Some () | _ -> None) + (fun () -> Aggregation_result_size_error) let parametric_constants chain block ctxt = let cpctxt = new Protocol_client_context.wrap_rpc_context ctxt in @@ -89,7 +111,8 @@ module Plugin = struct else return (`Head 0) let inject_entrapment_evidence cctxt ~attested_level - (operation : attestation_operation) ~slot_index ~shard ~proof = + (Op attestation : attestation_operation) ~slot_index ~shard ~proof + ~tb_slot = let open Lwt_result_syntax in let cpctxt = new Protocol_client_context.wrap_rpc_context cctxt in let chain = `Main in @@ -114,26 +137,19 @@ module Plugin = struct Protocol_client_context.Alpha_block_services.hash cctxt ~chain ~block () in let shard_with_proof = Dal.Shard_with_proof.{shard; proof} in - let protocol_data = operation.protocol_data in - match operation.protocol_data.contents with - | Single (Attestation {consensus_content = {slot = consensus_slot; _}; _}) - -> - 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 - ~consensus_slot - ~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 + let* bytes = + Plugin.RPC.Forge.dal_entrapment_evidence + cpctxt + (chain, block) + ~branch:block_hash + ~consensus_slot:tb_slot + ~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 let block_info ?chain ?block ~metadata ctxt = let cpctxt = new Protocol_client_context.wrap_rpc_context ctxt in @@ -189,22 +205,24 @@ module Plugin = struct ~metadata:`Always 0 in - return - @@ List.filter_map + Lwt.return @@ Result.map List.flatten + @@ List.map_e (fun operation -> let (Operation_data operation_data) = operation.protocol_data in match operation_data.contents with | Single (Attestation attestation) -> ( - let packed_operation : Kind.attestation Alpha_context.operation = - { - Alpha_context.shell = operation.shell; - protocol_data = operation_data; - } + let packed_operation = + Op + { + Alpha_context.shell = operation.shell; + protocol_data = operation_data; + } in - let tb_slot = Slot.to_int attestation.consensus_content.slot in - let dal_attestation : dal_attestation option = + let tb_slot = attestation.consensus_content.slot in + let dal_attestation = Option.map - (fun x -> (x.attestation :> dal_attestation)) + (fun dal_content -> + (dal_content.attestation :> dal_attestation)) attestation.dal_content in match operation.receipt with @@ -215,16 +233,62 @@ module Plugin = struct Tezos_crypto.Signature.Of_V2.public_key_hash result.delegate in - Some - ( tb_slot, - Some delegate, - packed_operation, - dal_attestation ) - | _ -> Some (tb_slot, None, packed_operation, dal_attestation) - ) + Ok + [ + ( tb_slot, + Some delegate, + packed_operation, + dal_attestation ); + ] + | _ -> + Ok [(tb_slot, None, packed_operation, dal_attestation)]) + | Empty | Too_large | Receipt No_operation_metadata -> + Ok [(tb_slot, None, packed_operation, dal_attestation)]) + | Single (Attestations_aggregate {committee; _}) -> ( + let packed_operation = + Op + { + Alpha_context.shell = operation.shell; + protocol_data = operation_data; + } + in + let slots_and_dal_attestations = + List.map + (fun (slot, dal_content_opt) -> + ( slot, + Option.map + (fun dal_content -> + (dal_content.attestation :> dal_attestation)) + dal_content_opt )) + committee + in + match operation.receipt with + | Receipt (Operation_metadata operation_metadata) -> ( + match operation_metadata.contents with + | Single_result + (Attestations_aggregate_result {committee; _}) -> + List.map2 + ~when_different_lengths:[Aggregation_result_size_error] + (fun (tb_slot, dal_attestation) consensus_key -> + ( tb_slot, + Some consensus_key.Consensus_key.delegate, + packed_operation, + dal_attestation )) + slots_and_dal_attestations + committee + | _ -> + Ok + (List.map + (fun (tb_slot, dal_attestation) -> + (tb_slot, None, packed_operation, dal_attestation)) + slots_and_dal_attestations)) | Empty | Too_large | Receipt No_operation_metadata -> - Some (tb_slot, None, packed_operation, dal_attestation)) - | _ -> None) + Ok + (List.map + (fun (tb_slot, dal_attestation) -> + (tb_slot, None, packed_operation, dal_attestation)) + slots_and_dal_attestations)) + | _ -> Ok []) consensus_ops let get_committee ctxt ~level =