From 37b2ec2b883110577409bc3665c2deca696502ba Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Thu, 20 Feb 2025 08:33:08 +0100 Subject: [PATCH 1/7] Stdlib: add (---) helper function --- src/lib_stdlib/utils.ml | 2 ++ src/lib_stdlib/utils.mli | 3 +++ 2 files changed, 5 insertions(+) diff --git a/src/lib_stdlib/utils.ml b/src/lib_stdlib/utils.ml index 3ac7f0e99a29..dab50fe92a42 100644 --- a/src/lib_stdlib/utils.ml +++ b/src/lib_stdlib/utils.ml @@ -25,6 +25,8 @@ module Infix = struct let ( -- ) i j = List.init (j - i + 1) (fun x -> x + i) + + let ( --- ) j i = List.init (j - i + 1) (fun x -> j - x) end let cut ?(copy = false) sz bytes = diff --git a/src/lib_stdlib/utils.mli b/src/lib_stdlib/utils.mli index ac332e00144a..ca34cff115ad 100644 --- a/src/lib_stdlib/utils.mli +++ b/src/lib_stdlib/utils.mli @@ -26,6 +26,9 @@ module Infix : sig (** Sequence: [i--j] is the sequence [i;i+1;...;j-1;j] *) val ( -- ) : int -> int -> int list + + (** Sequence: [j---i] is the sequence [j;j-1;...;i+1;i] *) + val ( --- ) : int -> int -> int list end (** [cut ?copy size bytes] cut [bytes] the in a list of successive -- GitLab From cbf62d96c541081d596f3e0face5887a5946a1e9 Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Thu, 20 Feb 2025 07:38:14 +0100 Subject: [PATCH 2/7] DAL/Node: refactor check_attesters main loop instead of looping through the attestations, loop through the registered attesters --- src/bin_dal_node/daemon.ml | 93 +++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 46 deletions(-) diff --git a/src/bin_dal_node/daemon.ml b/src/bin_dal_node/daemon.ml index f72c0c43040d..f9ca7b2ed6c9 100644 --- a/src/bin_dal_node/daemon.ml +++ b/src/bin_dal_node/daemon.ml @@ -510,57 +510,58 @@ module Handler = struct && Signature.Public_key_hash.equal delegate pkh) in let*! () = - List.iter_s - (fun (_, delegate_opt, _attestation_op, dal_attestation_opt) -> - match delegate_opt with - | Some delegate - when Signature.Public_key_hash.Set.mem delegate attesters -> ( - match dal_attestation_opt with - | None -> - let in_committee = - match - Signature.Public_key_hash.Map.find delegate committee - with - | Some (_ :: _) -> true - | _ -> false - in - if in_committee then + Signature.Public_key_hash.Set.iter_s + (fun delegate -> + if not @@ Signature.Public_key_hash.Map.mem delegate committee then + Lwt.return_unit + else + let attestation_opt = + List.find + (fun ( _tb_slot, + delegate_opt, + _attestation_op, + _dal_attestation_opt ) -> + match delegate_opt with + | Some pkh -> Signature.Public_key_hash.equal delegate pkh + | None -> false) + attestations + in + match attestation_opt with + | None -> + (* TODO: emit event: attestation not included! *) + Lwt.return_unit + | Some + (_tb_slot, _delegate_opt, _attestation_op, dal_attestation_opt) + -> ( + match dal_attestation_opt with + | None -> Event.emit_warn_attester_not_dal_attesting ~attester:delegate ~attested_level:block_level - else (* no assigned shards... *) - Lwt.return_unit - | Some bitset -> - List.iter_s - (fun index -> - if - should_be_attested index - && not (is_attested bitset index) - then + | Some bitset -> + List.iter_s + (fun index -> if - parameters.incentives_enable - && contains_traps delegate index + should_be_attested index + && not (is_attested bitset index) then - Event - .emit_attester_did_not_attest_slot_because_of_traps - ~attester:delegate - ~slot_index:index - ~attested_level:block_level - else - Event.emit_warn_attester_did_not_attest_slot - ~attester:delegate - ~slot_index:index - ~attested_level:block_level - else Lwt.return_unit) - (0 -- (parameters.number_of_slots - 1))) - | None | Some _ -> - (* None = the receipt does not contain the delegate (which - probably should not happen; if it can happen, we should use - the Tenderbake slot instead)... - Some _ = the delegate who signed the operation is not among - the registered attesters *) - Lwt.return_unit) - attestations + if + parameters.incentives_enable + && contains_traps delegate index + then + Event + .emit_attester_did_not_attest_slot_because_of_traps + ~attester:delegate + ~slot_index:index + ~attested_level:block_level + else + Event.emit_warn_attester_did_not_attest_slot + ~attester:delegate + ~slot_index:index + ~attested_level:block_level + else Lwt.return_unit) + (0 -- (parameters.number_of_slots - 1)))) + attesters in return_unit -- GitLab From a0a9ea0a17acdef9fc956e51525ba2ceb40116e3 Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Thu, 20 Feb 2025 07:47:30 +0100 Subject: [PATCH 3/7] DAL/Node: create new helper function in check_attesters_attested --- src/bin_dal_node/daemon.ml | 90 ++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 47 deletions(-) diff --git a/src/bin_dal_node/daemon.ml b/src/bin_dal_node/daemon.ml index f9ca7b2ed6c9..894fc7e55798 100644 --- a/src/bin_dal_node/daemon.ml +++ b/src/bin_dal_node/daemon.ml @@ -509,58 +509,54 @@ module Handler = struct index = slot_index && Signature.Public_key_hash.equal delegate pkh) in + let check_attester delegate = + let attestation_opt = + List.find + (fun (_tb_slot, delegate_opt, _attestation_op, _dal_attestation_opt) -> + match delegate_opt with + | Some pkh -> Signature.Public_key_hash.equal delegate pkh + | None -> false) + attestations + in + match attestation_opt with + | None -> + (* TODO: emit event: attestation not included! *) + Lwt.return_unit + | Some (_tb_slot, _delegate_opt, _attestation_op, dal_attestation_opt) + -> ( + match dal_attestation_opt with + | None -> + Event.emit_warn_attester_not_dal_attesting + ~attester:delegate + ~attested_level:block_level + | Some bitset -> + List.iter_s + (fun index -> + if + should_be_attested index && not (is_attested bitset index) + then + if + parameters.incentives_enable + && contains_traps delegate index + then + Event.emit_attester_did_not_attest_slot_because_of_traps + ~attester:delegate + ~slot_index:index + ~attested_level:block_level + else + Event.emit_warn_attester_did_not_attest_slot + ~attester:delegate + ~slot_index:index + ~attested_level:block_level + else Lwt.return_unit) + (0 -- (parameters.number_of_slots - 1))) + in let*! () = Signature.Public_key_hash.Set.iter_s (fun delegate -> if not @@ Signature.Public_key_hash.Map.mem delegate committee then Lwt.return_unit - else - let attestation_opt = - List.find - (fun ( _tb_slot, - delegate_opt, - _attestation_op, - _dal_attestation_opt ) -> - match delegate_opt with - | Some pkh -> Signature.Public_key_hash.equal delegate pkh - | None -> false) - attestations - in - match attestation_opt with - | None -> - (* TODO: emit event: attestation not included! *) - Lwt.return_unit - | Some - (_tb_slot, _delegate_opt, _attestation_op, dal_attestation_opt) - -> ( - match dal_attestation_opt with - | None -> - Event.emit_warn_attester_not_dal_attesting - ~attester:delegate - ~attested_level:block_level - | Some bitset -> - List.iter_s - (fun index -> - if - should_be_attested index - && not (is_attested bitset index) - then - if - parameters.incentives_enable - && contains_traps delegate index - then - Event - .emit_attester_did_not_attest_slot_because_of_traps - ~attester:delegate - ~slot_index:index - ~attested_level:block_level - else - Event.emit_warn_attester_did_not_attest_slot - ~attester:delegate - ~slot_index:index - ~attested_level:block_level - else Lwt.return_unit) - (0 -- (parameters.number_of_slots - 1)))) + else check_attester delegate) attesters in return_unit -- GitLab From 8c9c2185f6d1a473f5b6d05b5e00cc6650e7ff0f Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Mon, 24 Feb 2025 14:57:37 +0000 Subject: [PATCH 4/7] DAL/Node: make minor refactoring for clarity Co-authored-by: Guillaume Genestier --- src/bin_dal_node/daemon.ml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/bin_dal_node/daemon.ml b/src/bin_dal_node/daemon.ml index 894fc7e55798..c314257cdc7c 100644 --- a/src/bin_dal_node/daemon.ml +++ b/src/bin_dal_node/daemon.ml @@ -554,9 +554,9 @@ module Handler = struct let*! () = Signature.Public_key_hash.Set.iter_s (fun delegate -> - if not @@ Signature.Public_key_hash.Map.mem delegate committee then - Lwt.return_unit - else check_attester delegate) + if Signature.Public_key_hash.Map.mem delegate committee then + check_attester delegate + else Lwt.return_unit) attesters in return_unit -- GitLab From 392e81ebaf69f8c7b1b7725d311d7459b9909b98 Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Thu, 20 Feb 2025 07:53:55 +0100 Subject: [PATCH 5/7] DAL/Node: emit warning if attestation not included --- src/bin_dal_node/daemon.ml | 5 +++-- src/bin_dal_node/event.ml | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/bin_dal_node/daemon.ml b/src/bin_dal_node/daemon.ml index c314257cdc7c..093496edcc39 100644 --- a/src/bin_dal_node/daemon.ml +++ b/src/bin_dal_node/daemon.ml @@ -520,8 +520,9 @@ module Handler = struct in match attestation_opt with | None -> - (* TODO: emit event: attestation not included! *) - Lwt.return_unit + Event.emit_warn_no_attestation + ~attester:delegate + ~attested_level:block_level | Some (_tb_slot, _delegate_opt, _attestation_op, dal_attestation_opt) -> ( match dal_attestation_opt with diff --git a/src/bin_dal_node/event.ml b/src/bin_dal_node/event.ml index 7e5227e10124..a15c9537558c 100644 --- a/src/bin_dal_node/event.ml +++ b/src/bin_dal_node/event.ml @@ -740,6 +740,18 @@ open struct ("current_level", Data_encoding.int32) ("current_baker_level", Data_encoding.int32) + let warn_no_attestation = + declare_2 + ~section + ~name:"no_attestation" + ~msg: + "An attestation operation was not included for {attester} at attested \ + level {attested_level}." + ~level:Warning + ("attester", Signature.Public_key_hash.encoding) + ("attested_level", Data_encoding.int32) + ~pp1:Signature.Public_key_hash.pp_short + let warn_attester_not_dal_attesting = declare_2 ~section @@ -1113,6 +1125,9 @@ let emit_get_attestable_slots_future_level_warning ~current_level get_attestable_slots_future_level_warning (current_level, current_baker_level) +let emit_warn_no_attestation ~attester ~attested_level = + emit warn_no_attestation (attester, attested_level) + let emit_warn_attester_not_dal_attesting ~attester ~attested_level = emit warn_attester_not_dal_attesting (attester, attested_level) -- GitLab From a03056ecdffa139231b0d2beb12f4bcf0d590a44 Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Thu, 20 Feb 2025 08:33:50 +0100 Subject: [PATCH 6/7] DAL/Node: adjust attester events for all slot indexes --- src/bin_dal_node/daemon.ml | 65 +++++++++++++++++++++++++----------- src/bin_dal_node/event.ml | 68 ++++++++++++++++++++++++-------------- 2 files changed, 89 insertions(+), 44 deletions(-) diff --git a/src/bin_dal_node/daemon.ml b/src/bin_dal_node/daemon.ml index 093496edcc39..810700927c7e 100644 --- a/src/bin_dal_node/daemon.ml +++ b/src/bin_dal_node/daemon.ml @@ -531,26 +531,51 @@ module Handler = struct ~attester:delegate ~attested_level:block_level | Some bitset -> - List.iter_s - (fun index -> - if - should_be_attested index && not (is_attested bitset index) - then - if - parameters.incentives_enable - && contains_traps delegate index - then - Event.emit_attester_did_not_attest_slot_because_of_traps - ~attester:delegate - ~slot_index:index - ~attested_level:block_level - else - Event.emit_warn_attester_did_not_attest_slot - ~attester:delegate - ~slot_index:index - ~attested_level:block_level - else Lwt.return_unit) - (0 -- (parameters.number_of_slots - 1))) + let attested, not_attested, not_attested_with_traps = + List.fold_left + (fun (attested, not_attested, not_attested_with_traps) index -> + if should_be_attested index then + if is_attested bitset index then + ( index :: attested, + not_attested, + not_attested_with_traps ) + else if + parameters.incentives_enable + && contains_traps delegate index + then + ( attested, + not_attested, + index :: not_attested_with_traps ) + else + ( attested, + index :: not_attested, + not_attested_with_traps ) + else (attested, not_attested, not_attested_with_traps)) + ([], [], []) + (parameters.number_of_slots - 1 --- 0) + in + let*! () = + if attested <> [] then + Event.emit_attester_attested + ~attester:delegate + ~attested_level:block_level + ~slot_indexes:attested + else Lwt.return_unit + in + let*! () = + if not_attested <> [] then + Event.emit_warn_attester_did_not_attest + ~attester:delegate + ~attested_level:block_level + ~slot_indexes:not_attested + else Lwt.return_unit + in + if not_attested_with_traps <> [] then + Event.emit_attester_did_not_attest_because_of_traps + ~attester:delegate + ~attested_level:block_level + ~slot_indexes:not_attested_with_traps + else Lwt.return_unit) in let*! () = Signature.Public_key_hash.Set.iter_s diff --git a/src/bin_dal_node/event.ml b/src/bin_dal_node/event.ml index a15c9537558c..2362423152cc 100644 --- a/src/bin_dal_node/event.ml +++ b/src/bin_dal_node/event.ml @@ -25,6 +25,13 @@ open Internal_event.Simple +let pp_int_list fmt l = + Format.pp_print_list + ~pp_sep:(fun fmt () -> Format.pp_print_string fmt ", ") + Format.pp_print_int + fmt + l + (* DAL node event definitions *) open struct @@ -680,13 +687,6 @@ open struct ~level:Info ("query_id", Data_encoding.int31) - let pp_int_list fmt l = - Format.pp_print_list - ~pp_sep:(fun fmt () -> Format.pp_print_string fmt ", ") - Format.pp_print_int - fmt - l - let get_attestable_slots_ok_notice = declare_3 ~section @@ -752,6 +752,20 @@ open struct ("attested_level", Data_encoding.int32) ~pp1:Signature.Public_key_hash.pp_short + let attester_attested = + declare_3 + ~section + ~name:"attester_attested" + ~msg: + "{attester} attested slot(s) {slot_indexes} at attested level \ + {attested_level}." + ~level:Notice + ("attester", Signature.Public_key_hash.encoding) + ("attested_level", Data_encoding.int32) + ("slot_indexes", Data_encoding.(list int31)) + ~pp1:Signature.Public_key_hash.pp_short + ~pp3:pp_int_list + let warn_attester_not_dal_attesting = declare_2 ~section @@ -764,31 +778,35 @@ open struct ("attested_level", Data_encoding.int32) ~pp1:Signature.Public_key_hash.pp_short - let warn_attester_did_not_attest_slot = + let warn_attester_did_not_attest = declare_3 ~section - ~name:"attester_did_not_attest_slot" + ~name:"attester_did_not_attest" ~msg: - "At level {attested_level}, slot index {slot_index} was sufficiently \ - attested, but shards from {attester} are missing" + "At level {attested_level}, slot index(es) {slot_indexes} were \ + sufficiently attested, but {attester} neither attested them nor \ + identified them as traps." ~level:Warning ("attester", Signature.Public_key_hash.encoding) - ("slot_index", Data_encoding.int31) ("attested_level", Data_encoding.int32) + ("slot_indexes", Data_encoding.(list int31)) ~pp1:Signature.Public_key_hash.pp_short + ~pp3:pp_int_list - let attester_did_not_attest_slot_because_of_traps = + let attester_did_not_attest_because_of_traps = declare_3 ~section - ~name:"attester_did_not_attest_slot_with_traps" + ~name:"attester_did_not_attest_traps" ~msg: - "At level {attested_level}, slot index {slot_index} was sufficiently \ - attested, but {attester} did not attest because of traps" + "At level {attested_level}, slot index(es) {slot_indexes} were \ + sufficiently attested, but {attester} did not attest them because of \ + traps" ~level:Notice ("attester", Signature.Public_key_hash.encoding) - ("slot_index", Data_encoding.int31) ("attested_level", Data_encoding.int32) + ("slot_indexes", Data_encoding.(list int31)) ~pp1:Signature.Public_key_hash.pp_short + ~pp3:pp_int_list let trap_injection = declare_5 @@ -1128,18 +1146,20 @@ let emit_get_attestable_slots_future_level_warning ~current_level let emit_warn_no_attestation ~attester ~attested_level = emit warn_no_attestation (attester, attested_level) +let emit_attester_attested ~attester ~attested_level ~slot_indexes = + emit attester_attested (attester, attested_level, slot_indexes) + let emit_warn_attester_not_dal_attesting ~attester ~attested_level = emit warn_attester_not_dal_attesting (attester, attested_level) -let emit_warn_attester_did_not_attest_slot ~attester ~slot_index ~attested_level - = - emit warn_attester_did_not_attest_slot (attester, slot_index, attested_level) +let emit_warn_attester_did_not_attest ~attester ~attested_level ~slot_indexes = + emit warn_attester_did_not_attest (attester, attested_level, slot_indexes) -let emit_attester_did_not_attest_slot_because_of_traps ~attester ~slot_index - ~attested_level = +let emit_attester_did_not_attest_because_of_traps ~attester ~attested_level + ~slot_indexes = emit - attester_did_not_attest_slot_because_of_traps - (attester, slot_index, attested_level) + attester_did_not_attest_because_of_traps + (attester, attested_level, slot_indexes) let emit_trap_injection ~delegate ~published_level ~attested_level ~slot_index ~shard_index = -- GitLab From ea84c1417f2f9b477b07d2f93d53b8d4f3504c37 Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Thu, 20 Feb 2025 14:17:53 +0100 Subject: [PATCH 7/7] Tests/DAL: adapt test to new event name --- tezt/tests/dal.ml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tezt/tests/dal.ml b/tezt/tests/dal.ml index 11f868278969..33cc6e55191e 100644 --- a/tezt/tests/dal.ml +++ b/tezt/tests/dal.ml @@ -8823,10 +8823,10 @@ let test_producer_attester (_protocol : Protocol.t) ~error_msg:"Published slot was supposed to be attested.") ; unit -(* Check if the [attester_did_not_attest_slot] warning is correctly emitted. +(* Check if the [attester_did_not_attest] warning is correctly emitted. This test is a variation of [test_producer_attester] where an attestation not attesting the published DAL slot is injected. *) -let test_attester_did_not_attest_slot (_protocol : Protocol.t) +let test_attester_did_not_attest (_protocol : Protocol.t) (dal_params : Dal_common.Parameters.t) (_cryptobox : Cryptobox.t) (node : Node.t) (client : Client.t) (_dal_node : Dal_node.t) : unit Lwt.t = let log_step = init_logger () in @@ -8849,7 +8849,7 @@ let test_attester_did_not_attest_slot (_protocol : Protocol.t) "We promise the attester_did_not_attest_slot will be emitted by the \ [attester node]" ; let not_attested_by_bootstrap2_promise = - Dal_node.wait_for attester_node "attester_did_not_attest_slot.v0" (fun _ -> + Dal_node.wait_for attester_node "attester_did_not_attest.v0" (fun _ -> Some ()) in log_step "The producer crafts a commitment and publish it" ; @@ -10198,8 +10198,8 @@ let register ~protocols = ~attestation_threshold:1 ~l1_history_mode:Default_with_refutation ~event_sections_levels:[("prevalidator", `Debug)] - "attetster_did_not_attest_slot warning is emitted" - test_attester_did_not_attest_slot + "attester_did_not_attest warning is emitted" + test_attester_did_not_attest protocols ; scenario_with_layer1_and_dal_nodes "baker registers profiles with dal node" -- GitLab