diff --git a/src/bin_dal_node/daemon.ml b/src/bin_dal_node/daemon.ml index f72c0c43040de4793347d9032ed5ad312e71cc69..810700927c7ea6b43c6f99a65b346cccd89a92fa 100644 --- a/src/bin_dal_node/daemon.ml +++ b/src/bin_dal_node/daemon.ml @@ -509,58 +509,81 @@ module Handler = struct index = slot_index && 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 - 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) + 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 -> + 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 + | None -> + Event.emit_warn_attester_not_dal_attesting + ~attester:delegate + ~attested_level:block_level + | Some bitset -> + 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 - 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))) - | 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 + ( 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 + (fun delegate -> + if Signature.Public_key_hash.Map.mem delegate committee then + check_attester delegate + else Lwt.return_unit) + attesters in return_unit diff --git a/src/bin_dal_node/event.ml b/src/bin_dal_node/event.ml index 7e5227e1012491a8fcb5a9fa781587d1878246a2..2362423152cc37a67dc4685bf7472139458c9807 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 @@ -740,6 +740,32 @@ 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 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 @@ -752,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 @@ -1113,18 +1143,23 @@ 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_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 = diff --git a/src/lib_stdlib/utils.ml b/src/lib_stdlib/utils.ml index 3ac7f0e99a29f246b776b577aa146e4ecc39f976..dab50fe92a4258d95c28b77c205621fea5d21c5d 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 ac332e00144adcf48916d986d6e6abb3aa51bded..ca34cff115addf3cb27e2daffc5b41a42eaedefe 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 diff --git a/tezt/tests/dal.ml b/tezt/tests/dal.ml index 11f8682789690eb2f95e7c0f01dbd6fb1ddef254..33cc6e55191eee07799b7f02f77d836ca3cad554 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"