From 707791bf8718298c1c7d43edee8e7a76bd21ab00 Mon Sep 17 00:00:00 2001 From: Albin Coquereau Date: Wed, 27 Aug 2025 14:18:09 +0200 Subject: [PATCH 1/3] Teztcloud/layer1: rework baker account type --- tezt/tests/cloud/layer1.ml | 100 ++++++++++++++++--------------------- 1 file changed, 42 insertions(+), 58 deletions(-) diff --git a/tezt/tests/cloud/layer1.ml b/tezt/tests/cloud/layer1.ml index a4a5631e663b..7c3029316ca7 100644 --- a/tezt/tests/cloud/layer1.ml +++ b/tezt/tests/cloud/layer1.ml @@ -22,8 +22,8 @@ open Scenarios_helpers open Tezos open Yes_crypto -(** A baker account is its public key (pk) and its hash (pkh) *) -type baker_account = {pk : string; pkh : string} +(** A baker account is its delegate account and its consensus key account *) +type baker_account = {delegate : Account.key; consensus : Account.key} let wait_next_level ?(offset = 1) node = Lwt.bind @@ -186,39 +186,41 @@ module Node = struct in let* delegates, consensus_keys, rich_account_opt = let* known_addresses = Client.list_known_addresses client in - let get_pk alias = - let* account = Client.show_address ~alias client in - return account.public_key - in + let get_account alias = Client.show_address ~alias client in (Lwt_list.fold_left_s - (fun (delegates, consensus_keys, rich_account_opt) (alias, pkh) -> + (fun (delegates, consensus_keys, rich_account_opt) (alias, _pkh) -> if alias =~ rex "rich_" then (* if the alias match "rich_n" *) - let* pk = get_pk alias in - return (delegates, consensus_keys, Some {pkh; pk}) + let* rich_account = get_account alias in + return (delegates, consensus_keys, Some rich_account) else match alias =~* rex "(\\w+)_consensus_key" with | None -> (* if the alias does not contain "_consensus_key" *) - let* pk = get_pk alias in + let* delegate_account = get_account alias in return - ( String_map.add alias {pkh; pk} delegates, + ( String_map.add alias delegate_account delegates, consensus_keys, rich_account_opt ) | Some consensus_key_alias -> (* if the alias match "baker_n_consensus_key" *) - let* pk = get_pk alias in + let* consensus_account = get_account alias in return ( delegates, - String_map.add consensus_key_alias {pkh; pk} consensus_keys, + String_map.add + consensus_key_alias + consensus_account + consensus_keys, rich_account_opt ))) (String_map.empty, String_map.empty, None) (List.rev known_addresses) in let delegates_with_consensus_keys = String_map.mapi - (fun alias address_and_pk -> - (address_and_pk, String_map.find_opt alias consensus_keys)) + (fun alias delegate -> + match String_map.find_opt alias consensus_keys with + | None -> {delegate; consensus = delegate} + | Some consensus -> {delegate; consensus}) delegates in let* () = Client.forget_all_keys client in @@ -245,8 +247,11 @@ module Node = struct let* yes_wallet = Node_helpers.yes_wallet agent in let* () = Lwt_list.iter_s - (fun {pkh = alias; pk = public_key} -> - Client.import_public_key ~alias ~public_key client) + (fun {consensus; _} -> + Client.import_public_key + ~alias:consensus.public_key_hash + ~public_key:consensus.public_key + client) accounts in let* () = Yes_wallet.convert_wallet_inplace ~client yes_wallet in @@ -418,14 +423,14 @@ type baker = { agent : Agent.t; node : Node.t; baker : Agnostic_baker.t; - accounts : string list; + accounts : baker_account list; } type stresstester = { agent : Agent.t; node : Node.t; client : Client.t; - accounts : string list; + accounts : Account.key list; } type 'network t = { @@ -476,7 +481,10 @@ let init_baker_i i (configuration : configuration) cloud ~peers Agnostic_baker.Agent.init ~env ~name - ~delegates:(List.map (fun ({pkh; _} : baker_account) -> pkh) accounts) + ~delegates: + (List.map + (fun ({consensus; _} : baker_account) -> consensus.public_key_hash) + accounts) ~ppx_profiling:configuration.ppx_profiling ~client ~allow_fixed_random_seed: @@ -490,13 +498,7 @@ let init_baker_i i (configuration : configuration) cloud ~peers toplog "init_baker: %s is ready!" name ; Lwt.return agnostic_baker in - Lwt.return - { - agent; - node; - baker; - accounts = List.map (fun ({pkh; _} : baker_account) -> pkh) accounts; - } + Lwt.return {agent; node; baker; accounts} let fund_stresstest_accounts ~source client = Client.stresstest_fund_accounts_from_source @@ -524,7 +526,6 @@ let init_stresstest_i i (configuration : configuration) ~pkh ~pk ~peers (agent, node, name) ~tps in - let accounts = List.map (fun a -> a.Account.public_key_hash) accounts in Lwt.return {agent; node; client; accounts} let init_network ~peers (configuration : configuration) cloud teztale @@ -737,15 +738,8 @@ let init ~(configuration : configuration) cloud next_agent = in match configuration.stake with | [] -> - let res = - List.map - (fun (baker_account, consensus_key_opt) -> - match consensus_key_opt with - | None -> [baker_account] - | Some consensus_key -> [consensus_key]) - baker_accounts - in - Lwt.return res + Lwt.return + (List.map (fun baker_account -> [baker_account]) baker_accounts) | [x] -> if List.compare_length_with baker_accounts x != 0 then Test.fail @@ -753,23 +747,14 @@ let init ~(configuration : configuration) cloud next_agent = bakers (%d) retrieved in the yes wallet " x (List.length baker_accounts) ; - let res = - List.map - (fun (baker_account, consensus_key_opt) -> - match consensus_key_opt with - | None -> [baker_account] - | Some consensus_key -> [consensus_key]) - baker_accounts - in - Lwt.return res + Lwt.return + (List.map (fun baker_account -> [baker_account]) baker_accounts) | stake -> let* accounts = toplog "init_network: Fetching baker accounts baking power from client" ; Lwt_list.map_s - (fun ( (baker_account : baker_account), - (consensus_key_opt : baker_account option) ) - -> + (fun (baker_account : baker_account) -> let* power = Client.( rpc @@ -781,16 +766,11 @@ let init ~(configuration : configuration) cloud next_agent = "head"; "context"; "delegates"; - baker_account.pkh; + baker_account.delegate.public_key_hash; "current_baking_power"; ] bootstrap.client) in - let baker_account = - match consensus_key_opt with - | None -> baker_account - | Some consenusus_key -> consenusus_key - in Lwt.return (baker_account, power |> JSON.as_int)) baker_accounts in @@ -810,7 +790,7 @@ let init ~(configuration : configuration) cloud next_agent = Test.fail "Stresstest argument was provided but no rich account was found in \ the yes wallet" - | Some {tps; seed}, Some {pkh; pk} -> + | Some {tps; seed}, Some {public_key = pk; public_key_hash = pkh; _} -> let tps = tps / nb_stresstester configuration.network tps in let* stresstesters = (* init stresstest: init node and create accounts *) @@ -832,7 +812,7 @@ let init ~(configuration : configuration) cloud next_agent = Lwt_list.iter_p (fun {client; accounts; node; _} -> Lwt_list.iter_s - (fun pkh -> + (fun ({public_key_hash = pkh; _} : Account.key) -> (* For some reason, [try ... with ...] will make the scenario fail when a exception is raised *) let* need_reveal_operation = RPC.get_chain_block_context_contract_manager_key ~id:pkh () @@ -855,7 +835,11 @@ let init ~(configuration : configuration) cloud next_agent = copy it the the agent, and pass the filename to stresstest invocation directly *) let sources = - `A (List.map (fun pkh -> `O [("pkh", `String pkh)]) accounts) + `A + (List.map + (fun ({public_key_hash = pkh; _} : Account.key) -> + `O [("pkh", `String pkh)]) + accounts) in (* As we run in parrallel, and as Temp.file does not return a unique file name, we need a different base filename name for each stresstester *) -- GitLab From 8b0b0fed56f4cc9a41c2c5cf4ef28124898db7f0 Mon Sep 17 00:00:00 2001 From: Albin Coquereau Date: Mon, 25 Aug 2025 14:41:53 +0200 Subject: [PATCH 2/3] Teztcloud/layer1: add dal argument in the scenario --- tezt/tests/cloud/layer1.ml | 166 ++++++++++++++++++++++-------- tezt/tests/cloud/scenarios_cli.ml | 13 +++ 2 files changed, 137 insertions(+), 42 deletions(-) diff --git a/tezt/tests/cloud/layer1.ml b/tezt/tests/cloud/layer1.ml index 7c3029316ca7..417ced77041b 100644 --- a/tezt/tests/cloud/layer1.ml +++ b/tezt/tests/cloud/layer1.ml @@ -324,6 +324,7 @@ type configuration = { network : Network.t; snapshot : Snapshot_helpers.t; stresstest : stresstest_conf option; + without_dal : bool; maintenance_delay : int; migration_offset : int option; ppx_profiling : bool; @@ -350,6 +351,7 @@ let configuration_encoding = network; snapshot; stresstest; + without_dal; maintenance_delay; migration_offset; ppx_profiling; @@ -358,25 +360,27 @@ let configuration_encoding = fixed_random_seed; } -> - ( stake, - network, - snapshot, - stresstest, - maintenance_delay, - migration_offset, - ppx_profiling, - ppx_profiling_backends, - signing_delay, + ( ( stake, + network, + snapshot, + stresstest, + without_dal, + maintenance_delay, + migration_offset, + ppx_profiling, + ppx_profiling_backends, + signing_delay ), fixed_random_seed )) - (fun ( stake, - network, - snapshot, - stresstest, - maintenance_delay, - migration_offset, - ppx_profiling, - ppx_profiling_backends, - signing_delay, + (fun ( ( stake, + network, + snapshot, + stresstest, + without_dal, + maintenance_delay, + migration_offset, + ppx_profiling, + ppx_profiling_backends, + signing_delay ), fixed_random_seed ) -> { @@ -384,6 +388,7 @@ let configuration_encoding = network; snapshot; stresstest; + without_dal; maintenance_delay; migration_offset; ppx_profiling; @@ -391,37 +396,45 @@ let configuration_encoding = signing_delay; fixed_random_seed; }) - (obj10 - (req "stake" (list int31)) - (req "network" network_encoding) - (req "snapshot" Snapshot_helpers.encoding) - (opt "stresstest" stresstest_encoding) - (dft - "maintenance_delay" - int31 - Scenarios_cli.Layer1_default.default_maintenance_delay) - (opt "migration_offset" int31) - (dft - "ppx_profiling" - bool - Scenarios_cli.Layer1_default.default_ppx_profiling) - (dft - "ppx_profiling_backends" - (list string) - Scenarios_cli.Layer1_default.default_ppx_profiling_backends) - (opt "Signing_delay" (tup2 float float)) - (opt "fixed_random_seed" int31)) + (merge_objs + (obj10 + (req "stake" (list int31)) + (req "network" network_encoding) + (req "snapshot" Snapshot_helpers.encoding) + (opt "stresstest" stresstest_encoding) + (dft + "without_dal" + bool + Scenarios_cli.Layer1_default.default_without_dal) + (dft + "maintenance_delay" + int31 + Scenarios_cli.Layer1_default.default_maintenance_delay) + (opt "migration_offset" int31) + (dft + "ppx_profiling" + bool + Scenarios_cli.Layer1_default.default_ppx_profiling) + (dft + "ppx_profiling_backends" + (list string) + Scenarios_cli.Layer1_default.default_ppx_profiling_backends) + (opt "Signing_delay" (tup2 float float))) + (obj1 (opt "fixed_random_seed" int31))) type bootstrap = { agent : Agent.t; node : Node.t; node_p2p_endpoint : string; + dal_node : Dal_node.t option; + dal_node_p2p_endpoint : string option; client : Client.t; } type baker = { agent : Agent.t; node : Node.t; + dal_node : Dal_node.t option; baker : Agnostic_baker.t; accounts : baker_account list; } @@ -442,7 +455,7 @@ type 'network t = { } let init_baker_i i (configuration : configuration) cloud ~peers - (accounts : baker_account list) (agent, node, name) = + dal_node_p2p_endpoint (accounts : baker_account list) (agent, node, name) = let delay = i * configuration.maintenance_delay in let* client = toplog "init_baker: Initialize node" ; @@ -457,6 +470,30 @@ let init_baker_i i (configuration : configuration) cloud ~peers ~migration_offset:configuration.migration_offset (agent, node, name) in + let* dal_node = + if configuration.without_dal then Lwt.return_none + else + let name = name ^ "-dal-node" in + let* dal_node = Dal_node.Agent.create ~name cloud agent ~node in + let attester_profiles = + List.map (fun {delegate; _} -> delegate.public_key_hash) accounts + in + let* () = + Dal_node.init_config + ~expected_pow:26. + ~attester_profiles + ~peers:[dal_node_p2p_endpoint |> Option.get] + dal_node + in + let* () = + Dal_node.Agent.run + ~event_level:`Notice + ~ppx_profiling:configuration.ppx_profiling + ~ppx_profiling_backends:configuration.ppx_profiling_backends + dal_node + in + Lwt.return_some dal_node + in let* baker = toplog "init_baker: Initialize agnostic baker" ; let name = name ^ "-agnostic-baker" in @@ -477,6 +514,7 @@ let init_baker_i i (configuration : configuration) cloud ~peers | None -> env | Some (min, max) -> signing_delay_env min max env in + let dal_node_rpc_endpoint = Option.map Dal_node.as_rpc_endpoint dal_node in let* agnostic_baker = Agnostic_baker.Agent.init ~env @@ -485,6 +523,7 @@ let init_baker_i i (configuration : configuration) cloud ~peers (List.map (fun ({consensus; _} : baker_account) -> consensus.public_key_hash) accounts) + ?dal_node_rpc_endpoint ~ppx_profiling:configuration.ppx_profiling ~client ~allow_fixed_random_seed: @@ -498,7 +537,7 @@ let init_baker_i i (configuration : configuration) cloud ~peers toplog "init_baker: %s is ready!" name ; Lwt.return agnostic_baker in - Lwt.return {agent; node; baker; accounts} + Lwt.return {agent; node; dal_node; baker; accounts} let fund_stresstest_accounts ~source client = Client.stresstest_fund_accounts_from_source @@ -541,6 +580,32 @@ let init_network ~peers (configuration : configuration) cloud teztale ~migration_offset:configuration.migration_offset resources in + let* dal_node = + if configuration.without_dal then Lwt.return_none + else + let disable_shard_validation = true in + let* dal_node = + Dal_node.Agent.create + ~name:"bootstrap-dal-node" + cloud + agent + ~node + ~disable_shard_validation + in + let* () = + Dal_node.init_config ~expected_pow:26. ~bootstrap_profile:true dal_node + in + let* () = Node.wait_for_ready node in + let* () = + Dal_node.Agent.run + ~event_level:`Notice + ~disable_shard_validation + ~ppx_profiling:configuration.ppx_profiling + ~ppx_profiling_backends:configuration.ppx_profiling_backends + dal_node + in + Lwt.return_some dal_node + in toplog "init_network: Add a Teztale archiver" ; let* () = Teztale.add_archiver @@ -551,7 +616,14 @@ let init_network ~peers (configuration : configuration) cloud teztale ~node_port:(Node.rpc_port node) in let bootstrap = - {agent; node; node_p2p_endpoint = Node.point_str node; client} + { + agent; + node; + node_p2p_endpoint = Node.point_str node; + dal_node; + dal_node_p2p_endpoint = Option.map Dal_node.point_str dal_node; + client; + } in Lwt.return (bootstrap, delegates, rich_account) @@ -780,7 +852,14 @@ let init ~(configuration : configuration) cloud next_agent = (fun i accounts -> let ((_, node, _) as agent) = List.nth baker_agents i in let peers = List.filter (( <> ) (Node.point_str node)) peers in - init_baker_i i ~peers configuration cloud accounts agent) + init_baker_i + i + ~peers + configuration + cloud + bootstrap.dal_node_p2p_endpoint + accounts + agent) distribution in let* stresstesters = @@ -1026,6 +1105,7 @@ let register (module Cli : Scenarios_cli.Layer1) = in let maintenance_delay = Cli.maintenance_delay in let snapshot = Cli.snapshot in + let without_dal = Cli.without_dal in let migration_offset = Cli.migration_offset in let ppx_profiling = Cli.ppx_profiling in let ppx_profiling_backends = Cli.ppx_profiling_backends in @@ -1038,6 +1118,7 @@ let register (module Cli : Scenarios_cli.Layer1) = stake = Option.value ~default:conf.stake stake; network = Option.value ~default:conf.network network; snapshot = Option.value ~default:conf.snapshot snapshot; + without_dal = conf.without_dal || without_dal; stresstest = (if stresstest <> None then stresstest else conf.stresstest); maintenance_delay = @@ -1065,6 +1146,7 @@ let register (module Cli : Scenarios_cli.Layer1) = ~default:Scenarios_cli.Layer1_default.default_maintenance_delay maintenance_delay; snapshot = Option.get snapshot; + without_dal; migration_offset; ppx_profiling; ppx_profiling_backends; diff --git a/tezt/tests/cloud/scenarios_cli.ml b/tezt/tests/cloud/scenarios_cli.ml index f56b39d0a81c..d68e3cc82814 100644 --- a/tezt/tests/cloud/scenarios_cli.ml +++ b/tezt/tests/cloud/scenarios_cli.ml @@ -735,6 +735,8 @@ module type Layer1 = sig val vms_config : string option + val without_dal : bool + val ppx_profiling : bool val ppx_profiling_backends : string list @@ -746,6 +748,8 @@ module Layer1_default = struct let default_ppx_profiling = false let default_ppx_profiling_backends = [] + + let default_without_dal = false end module Layer1 () = struct @@ -895,6 +899,15 @@ module Layer1 () = struct test" () + let without_dal = + Clap.flag + ~section + ~set_long:"without-dal" + ~description: + "Disable running DAL nodes on bootstrap and bakers nodes. It is set to \ + `false` by default." + Layer1_default.default_without_dal + let ppx_profiling = Clap.flag ~section -- GitLab From 3e8ccf50a18d7047feb4f3e6120a40ecf0102820 Mon Sep 17 00:00:00 2001 From: Albin Coquereau Date: Wed, 27 Aug 2025 13:42:13 +0200 Subject: [PATCH 3/3] teztcloud/layer1: add support for DAL producers --- tezt/tests/cloud/layer1.ml | 205 ++++++++++++++++++++++++++---- tezt/tests/cloud/scenarios_cli.ml | 12 ++ 2 files changed, 190 insertions(+), 27 deletions(-) diff --git a/tezt/tests/cloud/layer1.ml b/tezt/tests/cloud/layer1.ml index 417ced77041b..0624e75bb242 100644 --- a/tezt/tests/cloud/layer1.ml +++ b/tezt/tests/cloud/layer1.ml @@ -158,8 +158,8 @@ module Node = struct create the associated client, create the yes-wallet. *) - let init_bootstrap_node ?stresstest ~ppx_profiling ~peers ~snapshot ~network - ~migration_offset (agent, node, name) = + let init_bootstrap_node ?stresstest ?dal_node_producers ~ppx_profiling ~peers + ~snapshot ~network ~migration_offset (agent, node, name) = toplog "Initializing an L1 node (public network): %s" name ; let* () = init_bootstrap_node_from_snapshot @@ -175,9 +175,11 @@ module Node = struct let* _filename = Yes_wallet.create_from_context ?rich_accounts: - (match stresstest with - | None -> None - | Some _ -> Some (1, 1_000_000)) + (match (stresstest, dal_node_producers) with + | None, None -> None + | Some _, Some l -> Some (List.length l + 1, 1_000_000) + | Some _, None -> Some (1, 1_000_000) + | None, Some l -> Some (List.length l, 1_000_000)) (* If the stresstest argument is set we try to find an account with at least 1M tez *) ~node ~client @@ -188,11 +190,11 @@ module Node = struct let* known_addresses = Client.list_known_addresses client in let get_account alias = Client.show_address ~alias client in (Lwt_list.fold_left_s - (fun (delegates, consensus_keys, rich_account_opt) (alias, _pkh) -> + (fun (delegates, consensus_keys, rich_accounts) (alias, _pkh) -> if alias =~ rex "rich_" then (* if the alias match "rich_n" *) let* rich_account = get_account alias in - return (delegates, consensus_keys, Some rich_account) + return (delegates, consensus_keys, rich_account :: rich_accounts) else match alias =~* rex "(\\w+)_consensus_key" with | None -> @@ -201,7 +203,7 @@ module Node = struct return ( String_map.add alias delegate_account delegates, consensus_keys, - rich_account_opt ) + rich_accounts ) | Some consensus_key_alias -> (* if the alias match "baker_n_consensus_key" *) let* consensus_account = get_account alias in @@ -211,8 +213,8 @@ module Node = struct consensus_key_alias consensus_account consensus_keys, - rich_account_opt ))) - (String_map.empty, String_map.empty, None) + rich_accounts ))) + (String_map.empty, String_map.empty, []) (List.rev known_addresses) in let delegates_with_consensus_keys = @@ -325,6 +327,7 @@ type configuration = { snapshot : Snapshot_helpers.t; stresstest : stresstest_conf option; without_dal : bool; + dal_node_producers : int list option; maintenance_delay : int; migration_offset : int option; ppx_profiling : bool; @@ -352,6 +355,7 @@ let configuration_encoding = snapshot; stresstest; without_dal; + dal_node_producers; maintenance_delay; migration_offset; ppx_profiling; @@ -365,23 +369,23 @@ let configuration_encoding = snapshot, stresstest, without_dal, + dal_node_producers, maintenance_delay, migration_offset, ppx_profiling, - ppx_profiling_backends, - signing_delay ), - fixed_random_seed )) + ppx_profiling_backends ), + (signing_delay, fixed_random_seed) )) (fun ( ( stake, network, snapshot, stresstest, without_dal, + dal_node_producers, maintenance_delay, migration_offset, ppx_profiling, - ppx_profiling_backends, - signing_delay ), - fixed_random_seed ) + ppx_profiling_backends ), + (signing_delay, fixed_random_seed) ) -> { stake; @@ -389,6 +393,7 @@ let configuration_encoding = snapshot; stresstest; without_dal; + dal_node_producers; maintenance_delay; migration_offset; ppx_profiling; @@ -406,6 +411,7 @@ let configuration_encoding = "without_dal" bool Scenarios_cli.Layer1_default.default_without_dal) + (opt "dal_node_producers" (list int31)) (dft "maintenance_delay" int31 @@ -418,9 +424,10 @@ let configuration_encoding = (dft "ppx_profiling_backends" (list string) - Scenarios_cli.Layer1_default.default_ppx_profiling_backends) - (opt "Signing_delay" (tup2 float float))) - (obj1 (opt "fixed_random_seed" int31))) + Scenarios_cli.Layer1_default.default_ppx_profiling_backends)) + (obj2 + (opt "Signing_delay" (tup2 float float)) + (opt "fixed_random_seed" int31))) type bootstrap = { agent : Agent.t; @@ -451,6 +458,7 @@ type 'network t = { cloud : Cloud.t; bootstrap : bootstrap; bakers : baker list; + producers : Dal_node_helpers.producer list; stresstesters : stresstester list; } @@ -539,6 +547,52 @@ let init_baker_i i (configuration : configuration) cloud ~peers in Lwt.return {agent; node; dal_node; baker; accounts} +let init_producer_i i (configuration : configuration) slot_index + (account : Account.key) cloud ~peers dal_node_p2p_endpoint + (agent, node, name) = + let delay = i * configuration.maintenance_delay in + let () = toplog "Initializing the DAL producer %s" name in + let* client = + let name = name ^ "-node" in + Node.init_baker_node + ~accounts:[] + ~delay + ~peers + ~ppx_profiling:configuration.ppx_profiling + ~snapshot:configuration.snapshot + ~network:configuration.network + ~migration_offset:configuration.migration_offset + (agent, node, name) + in + let* () = + Client.import_public_key + ~alias:account.public_key_hash + ~public_key:account.public_key + client + in + let* dal_node = + let name = name ^ "-dal-node" in + let* dal_node = Dal_node.Agent.create ~name cloud agent ~node in + let* () = + Dal_node.init_config + ~expected_pow:26. + ~observer_profiles:[slot_index] + ~peers:[dal_node_p2p_endpoint |> Option.get] + dal_node + in + let* () = + Dal_node.Agent.run + ~event_level:`Notice + ~ppx_profiling:configuration.ppx_profiling + ~ppx_profiling_backends:configuration.ppx_profiling_backends + dal_node + in + Lwt.return dal_node + in + Lwt.return + ({client; node; dal_node; account; is_ready = Lwt.return_unit; slot_index} + : Dal_node_helpers.producer) + let fund_stresstest_accounts ~source client = Client.stresstest_fund_accounts_from_source ~batch_size:150 @@ -573,6 +627,7 @@ let init_network ~peers (configuration : configuration) cloud teztale let* client, delegates, rich_account = Node.init_bootstrap_node ?stresstest:configuration.stresstest + ?dal_node_producers:configuration.dal_node_producers ~peers ~ppx_profiling:configuration.ppx_profiling ~snapshot:configuration.snapshot @@ -769,6 +824,18 @@ let init ~(configuration : configuration) cloud next_agent = |> Lwt_list.map_s @@ fun i -> agent_and_node next_agent cloud ~name:(sf "stresstest-%d" i) in + let* producers_agents = + Lwt_list.map_s + (fun slot_index -> + let* agent = + agent_and_node + next_agent + cloud + ~name:(sf "dal-node-producer-%d" slot_index) + in + return (agent, slot_index)) + (Option.value ~default:[] configuration.dal_node_producers) + in let* baker_agents = let* n = if configuration.stake = [] then @@ -796,11 +863,17 @@ let init ~(configuration : configuration) cloud next_agent = let peers : string list = List.map (fun (_, node, _) -> Node.point_str node) - (stresstest_agents @ baker_agents) + (stresstest_agents @ List.map fst producers_agents @ baker_agents) in - let* bootstrap, baker_accounts, stresstest_rich_account_opt = + let* bootstrap, baker_accounts, rich_accounts = init_network ~peers configuration cloud teztale bootstrap in + let stresstest_rich_account_opt, producer_accounts = + match configuration.stresstest with + | None -> (None, rich_accounts) + | Some _ -> ( + match rich_accounts with a :: l -> (Some a, l) | _ -> assert false) + in let peers = Node.point_str bootstrap_node :: peers in let* bakers = toplog "Initializing bakers" ; @@ -862,6 +935,23 @@ let init ~(configuration : configuration) cloud next_agent = agent) distribution in + let () = + toplog "Init: initializing %d DAL producers" (List.length producer_accounts) + in + let* producers = + Lwt_list.mapi_p + (fun i ((agent, slot_index), account) -> + init_producer_i + i + (configuration : configuration) + slot_index + account + cloud + ~peers + bootstrap.dal_node_p2p_endpoint + agent) + (List.combine producers_agents producer_accounts) + in let* stresstesters = match (configuration.stresstest, stresstest_rich_account_opt) with | None, _ -> Lwt.return_nil @@ -869,7 +959,8 @@ let init ~(configuration : configuration) cloud next_agent = Test.fail "Stresstest argument was provided but no rich account was found in \ the yes wallet" - | Some {tps; seed}, Some {public_key = pk; public_key_hash = pkh; _} -> + | ( Some {tps; seed}, + Some ({public_key = pk; public_key_hash = pkh; _} : Account.key) ) -> let tps = tps / nb_stresstester configuration.network tps in let* stresstesters = (* init stresstest: init node and create accounts *) @@ -956,7 +1047,7 @@ let init ~(configuration : configuration) cloud next_agent = add_prometheus_source ~node cloud agent (Agent.name agent)) stresstesters in - Lwt.return {cloud; configuration; bootstrap; bakers; stresstesters} + Lwt.return {cloud; configuration; bootstrap; bakers; producers; stresstesters} let on_new_level = let push_level t level = @@ -1046,17 +1137,21 @@ let vm_conf_encoding = type vms_conf = { bootstrap : vm_conf option; bakers : vm_conf list option; + producers : vm_conf list option; stresstester : vm_conf option; } let vms_conf_encoding = let open Data_encoding in conv - (fun {bootstrap; bakers; stresstester} -> (bootstrap, bakers, stresstester)) - (fun (bootstrap, bakers, stresstester) -> {bootstrap; bakers; stresstester}) - (obj3 + (fun {bootstrap; bakers; producers; stresstester} -> + (bootstrap, bakers, producers, stresstester)) + (fun (bootstrap, bakers, producers, stresstester) -> + {bootstrap; bakers; producers; stresstester}) + (obj4 (opt "bootstrap" vm_conf_encoding) (opt "bakers" @@ list vm_conf_encoding) + (opt "producers" @@ list vm_conf_encoding) (opt "stresstester" vm_conf_encoding)) (** Copy/paste from teztale_server_main.ml *) @@ -1103,6 +1198,7 @@ let register (module Cli : Scenarios_cli.Layer1) = let stresstest = Option.map (fun (tps, seed) -> {tps; seed}) Cli.stresstest in + let dal_node_producers = Cli.dal_producers_slot_indices in let maintenance_delay = Cli.maintenance_delay in let snapshot = Cli.snapshot in let without_dal = Cli.without_dal in @@ -1121,6 +1217,9 @@ let register (module Cli : Scenarios_cli.Layer1) = without_dal = conf.without_dal || without_dal; stresstest = (if stresstest <> None then stresstest else conf.stresstest); + dal_node_producers = + (if dal_node_producers <> None then dal_node_producers + else conf.dal_node_producers); maintenance_delay = Option.value ~default:conf.maintenance_delay maintenance_delay; migration_offset = @@ -1147,6 +1246,7 @@ let register (module Cli : Scenarios_cli.Layer1) = maintenance_delay; snapshot = Option.get snapshot; without_dal; + dal_node_producers; migration_offset; ppx_profiling; ppx_profiling_backends; @@ -1157,6 +1257,15 @@ let register (module Cli : Scenarios_cli.Layer1) = if configuration.stake = [] then Test.fail "stake parameter cannot be empty" ; if configuration.snapshot = Snapshot_helpers.No_snapshot then Test.fail "snapshot parameter cannot be empty" ; + let with_dal_producers = + match configuration.dal_node_producers with + | None | Some [] -> false + | _ -> true + in + if configuration.without_dal && with_dal_producers then + Test.fail + "Dal producer indices provided but DAL network disabled with \ + `--without-dal`" ; let vms_conf = Option.map (parse_conf vms_conf_encoding) Cli.vms_config in toplog "Parsing CLI done" ; @@ -1166,6 +1275,10 @@ let register (module Cli : Scenarios_cli.Layer1) = (match configuration.stake with | [n] -> List.init n (fun i -> `Baker i) | stake -> List.mapi (fun i _ -> `Baker i) stake) + @ (match configuration.dal_node_producers with + | Some dal_node_producers -> + List.map (fun i -> `Producer i) dal_node_producers + | None -> []) @ match configuration.stresstest with | None -> [] @@ -1213,7 +1326,13 @@ let register (module Cli : Scenarios_cli.Layer1) = make_vm_conf ~name:(Format.sprintf "baker-%d" i) @@ Option.bind vms_conf (function | {bakers = Some bakers; _} -> List.nth_opt bakers i - | {bakers = None; _} -> None)) + | {bakers = None; _} -> None) + | `Producer i -> + make_vm_conf ~name:(Format.sprintf "dal-node-producer-%d" i) + @@ Option.bind vms_conf (function + | {producers = Some producers; _} -> + List.nth_opt producers i + | {producers = None; _} -> None)) in Cloud.register (* Docker images are pushed before executing the test in case binaries @@ -1241,10 +1360,42 @@ let register (module Cli : Scenarios_cli.Layer1) = in let* t = init ~configuration cloud next_agent in toplog "Starting main loop" ; + let produce_slot (t : 'network t) level = + Lwt_list.iter_p + (fun (producer : Dal_node_helpers.producer) -> + let index = producer.slot_index in + let content = + Format.asprintf "%d:%d" level index + |> Dal_common.Helpers.make_slot ~padding:false ~slot_size:131072 + in + let* _ = Node.wait_for_level producer.node level in + let fee = 800 in + let* _commitment = + (* A dry-run of the "publish dal commitment" command for each tz kinds outputs: + - tz1: fees of 513µtz and 1333 gas consumed + - tz2: fees of 514µtz and 1318 gas consumed + - tz3: fees of 543µtz and 1607 gas consumed + - tz4: fees of 700µtz and 2837 gas consumed + We added a (quite small) margin to it. *) + Dal_common.Helpers.publish_and_store_slot + ~fee + ~gas_limit:3000 + ~dont_wait:true + producer.client + producer.dal_node + producer.account + ~force:true + ~index + content + in + Lwt.return_unit) + t.producers + in Lwt.bind (Network.get_level (Node.as_rpc_endpoint t.bootstrap.node)) (let rec loop level = let level = succ level in + let* () = produce_slot t level in let* () = on_new_level t level in loop level in diff --git a/tezt/tests/cloud/scenarios_cli.ml b/tezt/tests/cloud/scenarios_cli.ml index d68e3cc82814..645c31118cfb 100644 --- a/tezt/tests/cloud/scenarios_cli.ml +++ b/tezt/tests/cloud/scenarios_cli.ml @@ -737,6 +737,8 @@ module type Layer1 = sig val without_dal : bool + val dal_producers_slot_indices : int list option + val ppx_profiling : bool val ppx_profiling_backends : string list @@ -908,6 +910,16 @@ module Layer1 () = struct `false` by default." Layer1_default.default_without_dal + let dal_producers_slot_indices = + Clap.optional + ~section + ~long:"producer-slot-indices" + ~description: + "Specify the slot indices for DAL producers to run. The number of DAL \ + producers run is the size of the list." + (Clap.list_of_int ~dummy:[] "producer_slot_indices") + () + let ppx_profiling = Clap.flag ~section -- GitLab