diff --git a/tezt/lib_tezos/client.ml b/tezt/lib_tezos/client.ml index d90fd8e8e23161cd06d47631b1598b59cc80fe34..b2ee589fd5679af5254fcaebd8c6798c164f231d 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 86b66fe1259b7a001a6bf03f84f80963aa8cde7e..f5a81986ef391b2a1c549713d40d3f0ffacd39ea 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: diff --git a/tezt/tests/dal.ml b/tezt/tests/dal.ml index c229f6f8194d8bda7c8fd2ea1c83ffe35816b1b3..0e9f778cfde69708e2a05767628a89af7019a6a5 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 @@ -9499,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 @@ -9559,24 +9569,18 @@ 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 - + 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 - ~round ~signers:[baker] ~nb_slots baker_attestation @@ -9587,9 +9591,13 @@ 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 - ~round ~signers:[attesting_dal_slot_10] ~nb_slots attestation @@ -9602,7 +9610,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 @@ -9613,15 +9620,21 @@ 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 - ~round ~signers:[not_sufficiently_attesting_dal_slot_10] ~nb_slots slots_to_attest client in + Log.info + "At level %d, there are %d bakers that DAL attested" + level + !count_dal_attesting_bakers ; unit in @@ -9636,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 ; @@ -9648,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) = @@ -9660,7 +9677,37 @@ 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) + 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 @@ -9677,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 @@ -9689,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, @@ -9709,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__ @@ -9869,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)