From 0cf9288559350ce21db9c348d033e218ae3f1237 Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Wed, 12 Feb 2025 17:01:53 +0100 Subject: [PATCH 1/6] Tests/DAL: use predecessor block's round by default for building attestations --- tezt/tests/dal.ml | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/tezt/tests/dal.ml b/tezt/tests/dal.ml index c229f6f8194d..860a1126aaad 100644 --- a/tezt/tests/dal.ml +++ b/tezt/tests/dal.ml @@ -860,7 +860,7 @@ type attestation_availability = | Bitset of bool array | No_dal_attestation -let craft_dal_attestation ?level ?(round = 0) ?payload_level ~signer ~nb_slots +let craft_dal_attestation ?level ?round ?payload_level ~signer ~nb_slots availability client = let dal_attestation = match availability with @@ -885,11 +885,20 @@ let craft_dal_attestation ?level ?(round = 0) ?payload_level ~signer ~nb_slots JSON.(List.hd JSON.(slots |> as_list) |-> "slots" |> as_list) |> List.hd |> JSON.as_int in - let* block_payload_hash = + let* block_payload_hash, round = let block = (match payload_level with None -> level | Some l -> l) |> string_of_int in - Operation.Consensus.get_block_payload_hash ~block client + let* block_payload_hash = + Operation.Consensus.get_block_payload_hash ~block client + in + let* round = + match round with + | None -> + Client.RPC.call client @@ RPC.get_chain_block_helper_round ~block () + | Some round -> return round + in + return (block_payload_hash, round) in Operation.Consensus.operation ~with_dal:true @@ -903,12 +912,12 @@ let craft_dal_attestation ?level ?(round = 0) ?payload_level ~signer ~nb_slots ()) client -let inject_dal_attestation ?level ?(round = 0) ?payload_level ?force ?error - ?request ~signer ~nb_slots availability client = +let inject_dal_attestation ?level ?round ?payload_level ?force ?error ?request + ~signer ~nb_slots availability client = let* op = craft_dal_attestation ?level - ~round + ?round ?payload_level ~signer ~nb_slots -- GitLab From e1a23e44243b512de2721b659f87eb56e3413bb3 Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Wed, 12 Feb 2025 17:03:24 +0100 Subject: [PATCH 2/6] Tests/DAL: use default round in participation test --- tezt/tests/dal.ml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/tezt/tests/dal.ml b/tezt/tests/dal.ml index 860a1126aaad..efb10e8c5bfc 100644 --- a/tezt/tests/dal.ml +++ b/tezt/tests/dal.ml @@ -9568,15 +9568,6 @@ let test_dal_rewards_distribution _protocol dal_parameters cryptobox node client delegates depending on their profiles. *) let inject_attestations () = let* level = Node.get_level node in - let* rights = - Node.RPC.call node - @@ RPC.get_chain_block_helper_baking_rights - ~level - ~delegate:baker.public_key_hash - () - in - let round = JSON.(List.hd (as_list rights) |-> "round" |> as_int) in - (* 1. Baker always attests TB and all DAL slots *) let* (_ : (Operation_core.t * [`OpHash of peer_id]) list) = (* The baker delegate will miss 1/10 of its DAL attestations and will send @@ -9585,7 +9576,6 @@ let test_dal_rewards_distribution _protocol dal_parameters cryptobox node client if level mod 10 = 0 then No_dal_attestation else Slots all_slots in inject_dal_attestations - ~round ~signers:[baker] ~nb_slots baker_attestation @@ -9598,7 +9588,6 @@ let test_dal_rewards_distribution _protocol dal_parameters cryptobox node client rewards. *) let attestation = if level mod 11 = 0 then Slots [] else Slots [10] in inject_dal_attestations - ~round ~signers:[attesting_dal_slot_10] ~nb_slots attestation @@ -9611,7 +9600,6 @@ let test_dal_rewards_distribution _protocol dal_parameters cryptobox node client if level mod 2 = 0 then No_dal_attestation else Slots [] in inject_dal_attestations - ~round ~signers:[not_attesting_dal] ~nb_slots dal_attestation @@ -9625,7 +9613,6 @@ let test_dal_rewards_distribution _protocol dal_parameters cryptobox node client if level mod 4 = 0 then Slots [10] else No_dal_attestation in inject_dal_attestations - ~round ~signers:[not_sufficiently_attesting_dal_slot_10] ~nb_slots slots_to_attest -- GitLab From 47a787191b10fa65a2a0fb8f9209193be056e6dd Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Thu, 13 Feb 2025 11:24:54 +0100 Subject: [PATCH 3/6] Tezt/Tezos: add Client.propose_for_and_wait --- tezt/lib_tezos/client.ml | 14 ++++++++++++++ tezt/lib_tezos/client.mli | 11 +++++++++++ 2 files changed, 25 insertions(+) diff --git a/tezt/lib_tezos/client.ml b/tezt/lib_tezos/client.ml index d90fd8e8e231..b2ee589fd567 100644 --- a/tezt/lib_tezos/client.ml +++ b/tezt/lib_tezos/client.ml @@ -1002,6 +1002,20 @@ let propose_for ?endpoint ?(minimal_timestamp = true) ?protocol ?key ?force spawn_propose_for ?endpoint ?protocol ?key ?force ~minimal_timestamp client |> Process.check +let propose_for_and_wait ?endpoint ?minimal_timestamp ?protocol ?key ?force + client = + let node = + match node_of_client_mode client.mode with + | Some n -> n + | None -> Test.fail "No node found for propose_for_and_wait" + in + let actual_level_before = Node.get_last_seen_level node in + let* () = + propose_for ?endpoint ?minimal_timestamp ?protocol ?key ?force client + in + let* _level = Node.wait_for_level node (actual_level_before + 1) in + unit + let id = ref 0 let spawn_gen_keys ?(force = false) ?alias ?sig_alg client = diff --git a/tezt/lib_tezos/client.mli b/tezt/lib_tezos/client.mli index 86b66fe1259b..f5a81986ef39 100644 --- a/tezt/lib_tezos/client.mli +++ b/tezt/lib_tezos/client.mli @@ -760,6 +760,17 @@ val propose_for : t -> unit Lwt.t +(** [propose_for_and_wait] is the analogous of {!bake_for_and_wait} for + {!propose_for}. *) +val propose_for_and_wait : + ?endpoint:endpoint -> + ?minimal_timestamp:bool -> + ?protocol:Protocol.t -> + ?key:string list -> + ?force:bool -> + t -> + unit Lwt.t + (** Run [octez-client show address --show-secret] and parse the output into an [Account.key]. E.g. for [~alias:"bootstrap1"] the command yields: -- GitLab From 2e3f2641dd1c65407da460df12a3a3b592c98e35 Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Wed, 12 Feb 2025 20:27:53 +0100 Subject: [PATCH 4/6] Tests/DAL: use `propose_for` instead of `bake_for` to avoid injecting two attestations for the same baker --- tezt/tests/dal.ml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tezt/tests/dal.ml b/tezt/tests/dal.ml index efb10e8c5bfc..8e6e3121142f 100644 --- a/tezt/tests/dal.ml +++ b/tezt/tests/dal.ml @@ -9656,7 +9656,9 @@ let test_dal_rewards_distribution _protocol dal_parameters cryptobox node client client in let* () = inject_attestations () in - bake_for ~delegates:(`For [baker.Account.public_key_hash]) client) + (* Do not use [bake_for] because it also injects an attestation + operation for [baker]. *) + Client.propose_for_and_wait ~key:[baker.Account.public_key_hash] client) in (* After this first round of blocks, we snapshot the balances of our delegates -- GitLab From dcfb9e4e4de674781dbd87388a7fa7a4d2520855 Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Wed, 12 Feb 2025 17:05:40 +0100 Subject: [PATCH 5/6] Tests/DAL: add more checks and logging in participation test --- tezt/tests/dal.ml | 70 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 60 insertions(+), 10 deletions(-) diff --git a/tezt/tests/dal.ml b/tezt/tests/dal.ml index 8e6e3121142f..d1ff27712161 100644 --- a/tezt/tests/dal.ml +++ b/tezt/tests/dal.ml @@ -9508,6 +9508,7 @@ let test_dal_rewards_distribution _protocol dal_parameters cryptobox node client let* () = bake_for client in let* level = Node.get_level node in assert (level < blocks_per_cycle) ; + let level = ref level in let nb_slots = dal_parameters.Dal.Parameters.number_of_slots in let all_slots = List.init nb_slots Fun.id in @@ -9568,12 +9569,16 @@ let test_dal_rewards_distribution _protocol dal_parameters cryptobox node client delegates depending on their profiles. *) let inject_attestations () = let* level = Node.get_level node in + let count_dal_attesting_bakers = ref 0 in (* 1. Baker always attests TB and all DAL slots *) let* (_ : (Operation_core.t * [`OpHash of peer_id]) list) = (* The baker delegate will miss 1/10 of its DAL attestations and will send [No_dal_attestation] in this case. *) let baker_attestation = - if level mod 10 = 0 then No_dal_attestation else Slots all_slots + if level mod 10 = 0 then No_dal_attestation + else ( + incr count_dal_attesting_bakers ; + Slots all_slots) in inject_dal_attestations ~signers:[baker] @@ -9586,7 +9591,12 @@ let test_dal_rewards_distribution _protocol dal_parameters cryptobox node client (* The attesting_dal_slot_10 delegate misses 1/11th of its DAL attestations and will send Slots [], but it should be fine for its rewards. *) - let attestation = if level mod 11 = 0 then Slots [] else Slots [10] in + let attestation = + if level mod 11 = 0 then Slots [] + else ( + incr count_dal_attesting_bakers ; + Slots [10]) + in inject_dal_attestations ~signers:[attesting_dal_slot_10] ~nb_slots @@ -9610,7 +9620,10 @@ let test_dal_rewards_distribution _protocol dal_parameters cryptobox node client let* (_ : (Operation_core.t * [`OpHash of peer_id]) list) = let* level = Node.get_level node in let slots_to_attest = - if level mod 4 = 0 then Slots [10] else No_dal_attestation + if level mod 4 = 0 then ( + incr count_dal_attesting_bakers ; + Slots [10]) + else No_dal_attestation in inject_dal_attestations ~signers:[not_sufficiently_attesting_dal_slot_10] @@ -9618,6 +9631,10 @@ let test_dal_rewards_distribution _protocol dal_parameters cryptobox node client slots_to_attest client in + Log.info + "At level %d, there are %d bakers that DAL attested" + level + !count_dal_attesting_bakers ; unit in @@ -9632,6 +9649,10 @@ let test_dal_rewards_distribution _protocol dal_parameters cryptobox node client let block_dal_attestation_bitset = JSON.(block_json |-> "dal_attestation" |> as_int) in + Log.info + "At level %d, dal_attestation = %d" + !level + block_dal_attestation_bitset ; (* count when slot 10 is attested *) if block_dal_attestation_bitset = 1024 then incr count_set_dal_attestation_bitset ; @@ -9644,7 +9665,7 @@ let test_dal_rewards_distribution _protocol dal_parameters cryptobox node client where DAL rewards are distributed. *) let* () = repeat - (blocks_per_cycle - level - 1) + (blocks_per_cycle - !level - 1) (fun () -> let* () = count_slot_10_if_attested () in let* (`OpHash _oph1) = @@ -9656,9 +9677,37 @@ let test_dal_rewards_distribution _protocol dal_parameters cryptobox node client client in let* () = inject_attestations () in - (* Do not use [bake_for] because it also injects an attestation - operation for [baker]. *) - Client.propose_for_and_wait ~key:[baker.Account.public_key_hash] client) + let* () = + (* Do not use [bake_for] because it also injects an attestation + operation for [baker]. *) + Client.propose_for_and_wait + ~key:[baker.Account.public_key_hash] + client + in + incr level ; + let* manager_ops = + Node.RPC.call node + @@ RPC.get_chain_block_operations_validation_pass + ~validation_pass:3 + () + in + Check.( + (List.length @@ JSON.as_list manager_ops = 1) + int + ~__LOC__ + ~error_msg:"expected 1 manager operation in block, got %L") ; + let* attestations = + Node.RPC.call node + @@ RPC.get_chain_block_operations_validation_pass + ~validation_pass:0 + () + in + Check.( + (List.length @@ JSON.as_list attestations = 4) + int + ~__LOC__ + ~error_msg:"expected 4 attestations in block, got %L") ; + unit) in (* After this first round of blocks, we snapshot the balances of our delegates @@ -9675,8 +9724,7 @@ let test_dal_rewards_distribution _protocol dal_parameters cryptobox node client let* bootstrap_accounts_participation = Lwt_list.map_s - (fun (account, account_role) -> - Log.info "Get DAL participation info of %s" account_role ; + (fun (account, _account_role) -> let* dal_participation = get_dal_participation node account.Account.public_key_hash in @@ -9687,6 +9735,7 @@ let test_dal_rewards_distribution _protocol dal_parameters cryptobox node client (* We now bake the last block of the cycle, which should trigger TB and DAL rewards distribution. TB rewards are actually set to 0. *) let* () = bake_for ~delegates:(`For [baker.Account.public_key_hash]) client in + incr level ; (* We snapshot the balances of the delegates at the end of the cycle. *) let* ( _baker_bal2, @@ -9707,7 +9756,8 @@ let test_dal_rewards_distribution _protocol dal_parameters cryptobox node client ^ ", expected balance to be unchanged. Got %R, expecting %L" else "account " ^ account.Account.public_key_hash - ^ ", expected balance b1 to increase. Got %R, expecting %L" + ^ ", unexpected balance: got %R, expecting %L = " + ^ Int64.to_string bal_before ^ " + " ^ string_of_int delta in Check.(Int64.(add bal_before (of_int delta)) = bal_after) ~__LOC__ -- GitLab From c4f1e6d627c578406a16b30640da06eeab807348 Mon Sep 17 00:00:00 2001 From: Eugen Zalinescu Date: Wed, 12 Feb 2025 17:37:01 +0100 Subject: [PATCH 6/6] Tests/DAL: untag test as flaky --- tezt/tests/dal.ml | 1 - 1 file changed, 1 deletion(-) diff --git a/tezt/tests/dal.ml b/tezt/tests/dal.ml index d1ff27712161..0e9f778cfde6 100644 --- a/tezt/tests/dal.ml +++ b/tezt/tests/dal.ml @@ -9917,7 +9917,6 @@ let register ~protocols = test_slot_management_logic protocols ; scenario_with_layer1_node - ~tags:[Tag.flaky] "attesters receive expected DAL rewards depending on participation" test_dal_rewards_distribution (List.filter (fun p -> Protocol.number p >= 022) protocols) -- GitLab