From a21a354b4d6eee9c3a5497fccb0440f90267585b Mon Sep 17 00:00:00 2001 From: Sebastien Mondet Date: Thu, 16 May 2019 15:49:30 -0400 Subject: [PATCH 01/12] Flextesa: add `nay-for-promotion` test variant It is a new option for the test `daemons-upgrade`. --- .../command_daemons_protocol_change.ml | 58 ++++++++++++++++--- 1 file changed, 49 insertions(+), 9 deletions(-) diff --git a/src/bin_flextesa/command_daemons_protocol_change.ml b/src/bin_flextesa/command_daemons_protocol_change.ml index eb087a55a0bb..42dd8092e509 100644 --- a/src/bin_flextesa/command_daemons_protocol_change.ml +++ b/src/bin_flextesa/command_daemons_protocol_change.ml @@ -50,7 +50,7 @@ let run state ~protocol ~size ~base_port ~no_daemons_for ?external_peer_ports ?generate_kiln_config ~node_exec ~client_exec ~first_baker_exec ~first_endorser_exec ~first_accuser_exec ~second_baker_exec ~second_endorser_exec ~second_accuser_exec ~admin_exec ~new_protocol_path - () = + test_variant () = Helpers.System_dependencies.precheck state `Or_fail ~executables: [ node_exec; client_exec; first_baker_exec; first_endorser_exec @@ -253,11 +253,17 @@ let run state ~protocol ~size ~base_port ~no_daemons_for ?external_peer_ports >>= fun () -> wait_for_voting_period state ~client:client_0 ~attempts:50 Promotion_vote >>= fun _ -> + let protocol_switch_will_happen = + match test_variant with + | `Full_upgrade -> true + | `Nay_for_promotion -> false + in List_sequential.iter keys_and_daemons ~f:(fun (acc, client, _) -> Tezos_client.successful_client_cmd state ~client [ "submit"; "ballot"; "for" ; Tezos_protocol.Account.name acc - ; new_protocol_hash; "yea" ] + ; new_protocol_hash + ; (if protocol_switch_will_happen then "yea" else "nay") ] >>= fun _ -> Console.sayf state Fmt.( @@ -271,6 +277,10 @@ let run state ~protocol ~size ~base_port ~no_daemons_for ?external_peer_ports Tezos_client.successful_client_cmd state ~client:client_0 ["show"; "voting"; "period"] >>= fun res -> + let protocol_to_wait_for = + if protocol_switch_will_happen then new_protocol_hash + else protocol.Tezos_protocol.hash + in Helpers.wait_for state ~attempts:3 ~seconds:4. (fun _ -> Console.say state EF.(wf "Checking actual protocol transition") >>= fun () -> @@ -280,22 +290,32 @@ let run state ~protocol ~size ~base_port ~no_daemons_for ?external_peer_ports ( try Jqo.field ~k:"protocol" json |> Jqo.get_string |> return with e -> failf "Cannot parse metadata: %s" (Printexc.to_string e) ) >>= fun proto_hash -> - if proto_hash <> new_protocol_hash then + if proto_hash <> protocol_to_wait_for then return (`Not_done - (sprintf "Protocol not done: %s Vs %s" proto_hash new_protocol_hash)) + (sprintf "Protocol not done: %s Vs %s" proto_hash + protocol_to_wait_for)) else return (`Done ()) ) >>= fun () -> Interactive_test.Pauser.generic state EF. [ wf "Test finished, protocol is now %s, things should keep baking." - new_protocol_hash + protocol_to_wait_for ; markdown_verbatim (String.concat ~sep:"\n" res#out) ] ~force:true let cmd ~pp_error () = let open Cmdliner in let open Term in + let variants = + [ ( "full-upgrade" + , `Full_upgrade + , "Go through the whole voting process and do the protocol change." ) + ; ( "nay-for-promotion" + , `Nay_for_promotion + , "Go through the whole voting process but vote Nay at the last period \ + and hence stay on the same protocol." ) ] + in Test_command_line.Run_command.make ~pp_error ( pure (fun size @@ -314,6 +334,7 @@ let cmd ~pp_error () = second_accuser_exec (`Protocol_path new_protocol_path) generate_kiln_config + test_variant state -> let actual_test = @@ -321,7 +342,7 @@ let cmd ~pp_error () = ~first_baker_exec ~first_endorser_exec ~first_accuser_exec ~second_baker_exec ~second_endorser_exec ~second_accuser_exec ~admin_exec ?generate_kiln_config ~external_peer_ports - ~no_daemons_for ~new_protocol_path + ~no_daemons_for ~new_protocol_path test_variant in (state, Interactive_test.Pauser.run_test ~pp_error state actual_test) ) @@ -360,6 +381,17 @@ let cmd ~pp_error () = (info [] ~doc:"The protocol to inject and vote on." ~docv:"PROTOCOL-PATH"))) $ Kiln.Configuration_directory.cli_term () + $ Arg.( + let doc = + sprintf "Which variant of the test to run (one of {%s})" + ( List.map ~f:(fun (n, _, _) -> n) variants + |> String.concat ~sep:", " ) + in + value + (opt + (enum (List.map variants ~f:(fun (n, v, _) -> (n, v)))) + `Full_upgrade + (info ["test-variant"] ~doc))) $ Test_command_line.cli_state ~name:"daemons-upgrade" () ) (let doc = "Vote and Protocol-upgrade with bakers, endorsers, and accusers." @@ -369,6 +401,13 @@ let cmd ~pp_error () = ; `P "This test builds and runs a sandbox network to do a full voting \ round followed by a protocol change while all the daemons." + ; `P + (sprintf + "There are for now %d variants (see option `--test-variant`):" + (List.length variants)) + ; `Blocks + (List.concat_map variants ~f:(fun (n, _, desc) -> + [`Noblank; `P (sprintf "* `%s`: %s" n desc)] )) ; `P "The test is interactive-only:" ; `Blocks (List.concat_mapi @@ -382,8 +421,9 @@ let cmd ~pp_error () = full voting round happens with a single proposal: the one at \ `PROTOCOL-PATH` (which should be the one understood by the \ `--second-*` executables)." - ; "Once the protocol switch has happened (and been verified), \ - the test re-enters an interactive prompt to let the user \ - play with the new protocol." ]) ] + ; "Once the potential protocol switch has happened (and been \ + verified), the test re-enters an interactive prompt to let \ + the user play with the protocol (the first or second one, \ + depending on the `--test-variant` option)." ]) ] in info "daemons-upgrade" ~man ~doc) -- GitLab From d6be655750e8649258b619f161193a7d0b864f09 Mon Sep 17 00:00:00 2001 From: Sebastien Mondet Date: Thu, 16 May 2019 16:50:20 -0400 Subject: [PATCH 02/12] Flextesa: improve the protocol's `Cmdliner.Term.t` --- src/lib_network_sandbox/tezos_protocol.ml | 62 +++++++++++++---------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/src/lib_network_sandbox/tezos_protocol.ml b/src/lib_network_sandbox/tezos_protocol.ml index 4af00cc56278..2ded9e698b14 100644 --- a/src/lib_network_sandbox/tezos_protocol.ml +++ b/src/lib_network_sandbox/tezos_protocol.ml @@ -311,62 +311,72 @@ let ensure t ~config = let cli_term () = let open Cmdliner in let open Term in + let def = default () in + let docs = "PROTOCOL OPTIONS" in pure (fun remove_default_bas - (`Blocks_per_voting_period bpvp) - (`Protocol_hash hashopt) - (`Time_between_blocks tbb) + (`Blocks_per_voting_period blocks_per_voting_period) + (`Protocol_hash hash) + (`Time_between_blocks time_between_blocks) + (`Blocks_per_cycle blocks_per_cycle) + (`Preserved_cycles preserved_cycles) add_bootstraps -> - let d = default () in - let id = - if add_bootstraps = [] && remove_default_bas = false then d.id - else "default-and-command-line" - in - let time_between_blocks = - Option.value tbb ~default:d.time_between_blocks - in + let id = "default-and-command-line" in let bootstrap_accounts = add_bootstraps - @ if remove_default_bas then [] else d.bootstrap_accounts + @ if remove_default_bas then [] else def.bootstrap_accounts in - let blocks_per_voting_period = - match bpvp with Some v -> v | None -> d.blocks_per_voting_period - in - let hash = Option.value hashopt ~default:d.hash in - { d with + { def with id + ; blocks_per_cycle ; hash ; bootstrap_accounts ; time_between_blocks + ; preserved_cycles ; blocks_per_voting_period } ) $ Arg.( value (flag (info ~doc:"Do not create any of the default bootstrap accounts." + ~docs ["remove-default-bootstrap-accounts"]))) $ Arg.( pure (fun x -> `Blocks_per_voting_period x) $ value - (opt (some int) None - (info + (opt int def.blocks_per_voting_period + (info ~docs ["blocks-per-voting-period"] - ~doc:"Set the length of voting periods"))) + ~doc:"Set the length of voting periods."))) $ Arg.( pure (fun x -> `Protocol_hash x) $ value - (opt (some string) None - (info ["protocol-hash"] ~doc:"Set the (starting) protocol hash."))) + (opt string def.hash + (info ["protocol-hash"] ~docs + ~doc:"Set the (initial) protocol hash."))) $ Arg.( pure (fun x -> `Time_between_blocks x) $ value - (opt - (some (list ~sep:',' int)) - None + (opt (list ~sep:',' int) def.time_between_blocks (info ["time-between-blocks"] ~docv:"COMMA-SEPARATED-SECONDS" + ~docs ~doc: "Set the time between blocks bootstrap-parameter, e.g. \ `2,3,2`."))) + $ Arg.( + pure (fun x -> `Blocks_per_cycle x) + $ value + (opt int def.blocks_per_cycle + (info ["blocks-per-cycle"] ~docv:"NUMBER" ~docs + ~doc:"Number of blocks per cycle."))) + $ Arg.( + pure (fun x -> `Preserved_cycles x) + $ value + (opt int def.preserved_cycles + (info ["preserved-cycles"] ~docv:"NUMBER" ~docs + ~doc: + "Base constant for baking rights (search for \ + `PRESERVED_CYCLES` in the white paper)."))) $ Arg.( pure (fun l -> List.map l ~f:(fun ((name, pubkey, pubkey_hash, private_key), tez) -> @@ -376,7 +386,7 @@ let cli_term () = (opt_all (pair ~sep:'@' (t4 ~sep:',' string string string string) int64) [] - (info ["add-bootstrap-account"] + (info ["add-bootstrap-account"] ~docs ~docv:"NAME,PUBKEY,PUBKEY-HASH,PRIVATE-URI@MUTEZ-AMOUNT" ~doc: "Add a custom bootstrap account, e.g. \ -- GitLab From 92cb399776025d25585ae2af79e7db02138e9f64 Mon Sep 17 00:00:00 2001 From: Sebastien Mondet Date: Thu, 23 May 2019 11:50:19 -0400 Subject: [PATCH 03/12] Flextesa: add `--waiting-attempts` (daemons-upgr.) --- .../command_daemons_protocol_change.ml | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/bin_flextesa/command_daemons_protocol_change.ml b/src/bin_flextesa/command_daemons_protocol_change.ml index 42dd8092e509..f4e25a332cfd 100644 --- a/src/bin_flextesa/command_daemons_protocol_change.ml +++ b/src/bin_flextesa/command_daemons_protocol_change.ml @@ -50,7 +50,7 @@ let run state ~protocol ~size ~base_port ~no_daemons_for ?external_peer_ports ?generate_kiln_config ~node_exec ~client_exec ~first_baker_exec ~first_endorser_exec ~first_accuser_exec ~second_baker_exec ~second_endorser_exec ~second_accuser_exec ~admin_exec ~new_protocol_path - test_variant () = + ~waiting_attempts test_variant () = Helpers.System_dependencies.precheck state `Or_fail ~executables: [ node_exec; client_exec; first_baker_exec; first_endorser_exec @@ -142,8 +142,8 @@ let run state ~protocol ~size ~base_port ~no_daemons_for ?external_peer_ports (List.map nodes ~f:(Tezos_client.of_node ~exec:client_exec)) ; arbitrary_command_on_clients state ~command_names:["c0"; "client-0"] ~make_admin ~clients:[client_0] ]) ; - Test_scenario.Queries.wait_for_all_levels_to_be state ~attempts:50 - ~seconds:10. nodes + Test_scenario.Queries.wait_for_all_levels_to_be state + ~attempts:waiting_attempts ~seconds:10. nodes (* TODO: wait for /chains/main/blocks/head/votes/listings to be non-empty instead of counting blocks *) (`At_least protocol.Tezos_protocol.blocks_per_voting_period) @@ -220,8 +220,8 @@ let run state ~protocol ~size ~base_port ~no_daemons_for ?external_peer_ports ; wf "Please type `q` to start a voting/protocol-change period." ] ~force:true >>= fun () -> - wait_for_voting_period state ~client:client_0 ~attempts:10 Proposal - ~level_withing_period:3 + wait_for_voting_period state ~client:client_0 ~attempts:waiting_attempts + Proposal ~level_withing_period:3 >>= fun _ -> List_sequential.iter keys_and_daemons ~f:(fun (acc, client, _) -> Tezos_client.successful_client_cmd state ~client @@ -236,7 +236,8 @@ let run state ~protocol ~size ~base_port ~no_daemons_for ?external_peer_ports (Tezos_protocol.Account.name acc) new_protocol_hash) ) >>= fun () -> - wait_for_voting_period state ~client:client_0 ~attempts:50 Testing_vote + wait_for_voting_period state ~client:client_0 ~attempts:waiting_attempts + Testing_vote >>= fun _ -> List_sequential.iter keys_and_daemons ~f:(fun (acc, client, _) -> Tezos_client.successful_client_cmd state ~client @@ -251,7 +252,8 @@ let run state ~protocol ~size ~base_port ~no_daemons_for ?external_peer_ports (Tezos_protocol.Account.name acc) new_protocol_hash) ) >>= fun () -> - wait_for_voting_period state ~client:client_0 ~attempts:50 Promotion_vote + wait_for_voting_period state ~client:client_0 ~attempts:waiting_attempts + Promotion_vote >>= fun _ -> let protocol_switch_will_happen = match test_variant with @@ -272,7 +274,8 @@ let run state ~protocol ~size ~base_port ~no_daemons_for ?external_peer_ports (Tezos_protocol.Account.name acc) new_protocol_hash) ) >>= fun () -> - wait_for_voting_period state ~client:client_0 ~attempts:50 Proposal + wait_for_voting_period state ~client:client_0 ~attempts:waiting_attempts + Proposal >>= fun _ -> Tezos_client.successful_client_cmd state ~client:client_0 ["show"; "voting"; "period"] @@ -281,7 +284,7 @@ let run state ~protocol ~size ~base_port ~no_daemons_for ?external_peer_ports if protocol_switch_will_happen then new_protocol_hash else protocol.Tezos_protocol.hash in - Helpers.wait_for state ~attempts:3 ~seconds:4. (fun _ -> + Helpers.wait_for state ~attempts:waiting_attempts ~seconds:4. (fun _ -> Console.say state EF.(wf "Checking actual protocol transition") >>= fun () -> Tezos_client.rpc state ~client:client_0 `Get @@ -320,6 +323,7 @@ let cmd ~pp_error () = ( pure (fun size base_port + (`Attempts waiting_attempts) (`External_peers external_peer_ports) (`No_daemons_for no_daemons_for) protocol @@ -342,7 +346,7 @@ let cmd ~pp_error () = ~first_baker_exec ~first_endorser_exec ~first_accuser_exec ~second_baker_exec ~second_endorser_exec ~second_accuser_exec ~admin_exec ?generate_kiln_config ~external_peer_ports - ~no_daemons_for ~new_protocol_path test_variant + ~no_daemons_for ~new_protocol_path test_variant ~waiting_attempts in (state, Interactive_test.Pauser.run_test ~pp_error state actual_test) ) @@ -352,6 +356,13 @@ let cmd ~pp_error () = $ Arg.( value & opt int 20_000 & info ["base-port"; "P"] ~doc:"Base port number to build upon.") + $ Arg.( + pure (fun n -> `Attempts n) + $ value + (opt int 60 + (info ["waiting-attempts"] + ~doc: + "Number of attempts done while waiting for voting periods"))) $ Arg.( pure (fun l -> `External_peers l) $ value -- GitLab From 94b298f5349b26557b9f2bc12fad092ae9b57ad3 Mon Sep 17 00:00:00 2001 From: Sebastien Mondet Date: Thu, 23 May 2019 13:12:24 -0400 Subject: [PATCH 04/12] Flextesa: fix bug with `--pause-{at-end,on-error}` --- src/lib_network_sandbox/interactive_test.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib_network_sandbox/interactive_test.ml b/src/lib_network_sandbox/interactive_test.ml index fa3bcc4c65ac..12ce180abb0d 100644 --- a/src/lib_network_sandbox/interactive_test.ml +++ b/src/lib_network_sandbox/interactive_test.ml @@ -397,7 +397,7 @@ module Interactivity = struct match (interactive, pause_end, pause_error) with | true, _, _ -> `Full | false, true, _ -> `At_end - | false, false, true -> `At_end + | false, false, true -> `On_error | false, false, false -> `None ) $ Arg.( value -- GitLab From 8d11955b860e044b4eb69db218da8d23ad143bd5 Mon Sep 17 00:00:00 2001 From: Sebastien Mondet Date: Thu, 23 May 2019 13:14:45 -0400 Subject: [PATCH 05/12] Flextesa: improve `--help` of voting test --- src/bin_flextesa/command_voting.ml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/bin_flextesa/command_voting.ml b/src/bin_flextesa/command_voting.ml index e8e8f4479a1f..56bf78f83a14 100644 --- a/src/bin_flextesa/command_voting.ml +++ b/src/bin_flextesa/command_voting.ml @@ -50,7 +50,8 @@ let transfer state ~client ~src ~dst ~amount = let register state ~client ~dst = Tezos_client.successful_client_cmd state ~client - [ "--wait"; "none"; "register"; "key" ; dst ; "as" ; "delegate" ; "--fee"; "0.05" ] + [ "--wait"; "none"; "register"; "key"; dst; "as"; "delegate"; "--fee" + ; "0.05" ] let bake_until_voting_period ?keep_alive_delegate state ~baker ~attempts period = @@ -63,8 +64,7 @@ let bake_until_voting_period ?keep_alive_delegate state ~baker ~attempts period | `String p when p = period_name -> return (`Done (nth - 1)) | other -> Asynchronous_result.map_option keep_alive_delegate ~f:(fun dst -> - register state ~client ~dst - >>= fun res -> return () ) + register state ~client ~dst >>= fun res -> return () ) >>= fun _ -> ksprintf (Tezos_client.Keyed.bake state baker) @@ -611,10 +611,12 @@ let cmd ~pp_error () = pure Filename.dirname $ required (pos 1 (some string) None - (info [] ~docv:"LOOSER-PROTOCOL-PATH" + (info [] ~docv:"LOSER-PROTOCOL-PATH" ~doc: "The protocol to inject and down-vote, e.g. \ - `./src/bin_client/test/proto_test_injection/TEZOS_PROTOCOL`."))) + `./src/bin_client/test/proto_test_injection/TEZOS_PROTOCOL` \ + (if same as `WINNER-PROTOCOL-PATH` the scenario will \ + make them automatically & artificially different)."))) $ Tezos_executable.cli_term `Node "current" $ Tezos_executable.cli_term `Client "current" $ Tezos_executable.cli_term `Admin "current" -- GitLab From 934e5e98e5ecbb237203e2aa391a77c11786a2e7 Mon Sep 17 00:00:00 2001 From: Sebastien Mondet Date: Thu, 23 May 2019 17:34:21 -0400 Subject: [PATCH 06/12] Flextesa: fix non-closed file --- src/lib_network_sandbox/running_processes.ml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lib_network_sandbox/running_processes.ml b/src/lib_network_sandbox/running_processes.ml index 1e34f13e7687..5a95e76abe2e 100644 --- a/src/lib_network_sandbox/running_processes.ml +++ b/src/lib_network_sandbox/running_processes.ml @@ -240,12 +240,13 @@ let fresh_id _state prefix ~seed = let run_cmdf state fmt = let get_file path = Lwt_exception.catch - Lwt.Infix.( + Lwt.( fun () -> Lwt_io.open_file ~mode:Lwt_io.input path >>= fun inchan -> let stream = Lwt_io.read_lines inchan in - Lwt_stream.to_list stream) + Lwt_stream.to_list stream + >>= fun l -> Lwt_io.close inchan >>= fun () -> return l) () in ksprintf -- GitLab From 72a113fbef3007c6d960c157f33195b5c0241d16 Mon Sep 17 00:00:00 2001 From: Sebastien Mondet Date: Thu, 23 May 2019 18:01:34 -0400 Subject: [PATCH 07/12] Flextesa: add option to include dummy proposals --- .../command_daemons_protocol_change.ml | 50 ++++++++++++++----- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/src/bin_flextesa/command_daemons_protocol_change.ml b/src/bin_flextesa/command_daemons_protocol_change.ml index f4e25a332cfd..e2ca9ae5ae9f 100644 --- a/src/bin_flextesa/command_daemons_protocol_change.ml +++ b/src/bin_flextesa/command_daemons_protocol_change.ml @@ -50,7 +50,7 @@ let run state ~protocol ~size ~base_port ~no_daemons_for ?external_peer_ports ?generate_kiln_config ~node_exec ~client_exec ~first_baker_exec ~first_endorser_exec ~first_accuser_exec ~second_baker_exec ~second_endorser_exec ~second_accuser_exec ~admin_exec ~new_protocol_path - ~waiting_attempts test_variant () = + ~extra_dummy_proposals ~waiting_attempts test_variant () = Helpers.System_dependencies.precheck state `Or_fail ~executables: [ node_exec; client_exec; first_baker_exec; first_endorser_exec @@ -223,18 +223,36 @@ let run state ~protocol ~size ~base_port ~no_daemons_for ?external_peer_ports wait_for_voting_period state ~client:client_0 ~attempts:waiting_attempts Proposal ~level_withing_period:3 >>= fun _ -> + let submit_prop acc client hash = + Tezos_client.successful_client_cmd state ~client + [ "submit"; "proposals"; "for" + ; Tezos_protocol.Account.name acc + ; hash; "--force" ] + >>= fun _ -> + Console.sayf state + Fmt.( + fun ppf () -> + pf ppf "%s voted for %s" (Tezos_protocol.Account.name acc) hash) + in List_sequential.iter keys_and_daemons ~f:(fun (acc, client, _) -> - Tezos_client.successful_client_cmd state ~client - [ "submit"; "proposals"; "for" - ; Tezos_protocol.Account.name acc - ; new_protocol_hash ] - >>= fun _ -> - Console.sayf state - Fmt.( - fun ppf () -> - pf ppf "%s voted for %s" - (Tezos_protocol.Account.name acc) - new_protocol_hash) ) + submit_prop acc client new_protocol_hash ) + >>= fun () -> + let extra_dummy_protocol_hashes = + List.map + (List.init extra_dummy_proposals ~f:(fun s -> sprintf "proto-%d" s)) + ~f:(fun s -> Tezos_crypto.Protocol_hash.(hash_string [s] |> to_b58check)) + in + Console.say state + EF.( + wf "Going to also vote for %s" + (String.concat ~sep:", " extra_dummy_protocol_hashes)) + >>= fun () -> + List_sequential.iteri extra_dummy_protocol_hashes ~f:(fun nth proto_hash -> + match List.nth keys_and_daemons (nth / 19) with + | Some (acc, client, _) -> submit_prop acc client proto_hash + | None -> + failf "Too many dummy protocols Vs available voting power (%d)" nth + ) >>= fun () -> wait_for_voting_period state ~client:client_0 ~attempts:waiting_attempts Testing_vote @@ -337,6 +355,7 @@ let cmd ~pp_error () = second_endorser_exec second_accuser_exec (`Protocol_path new_protocol_path) + (`Extra_dummy_proposals extra_dummy_proposals) generate_kiln_config test_variant state @@ -347,6 +366,7 @@ let cmd ~pp_error () = ~second_baker_exec ~second_endorser_exec ~second_accuser_exec ~admin_exec ?generate_kiln_config ~external_peer_ports ~no_daemons_for ~new_protocol_path test_variant ~waiting_attempts + ~extra_dummy_proposals in (state, Interactive_test.Pauser.run_test ~pp_error state actual_test) ) @@ -391,6 +411,12 @@ let cmd ~pp_error () = (pos 0 (some string) None (info [] ~doc:"The protocol to inject and vote on." ~docv:"PROTOCOL-PATH"))) + $ Arg.( + pure (fun l -> `Extra_dummy_proposals l) + $ value + (opt int 0 + (info ["extra-dummy-proposals"] ~docv:"NUMBER" + ~doc:"Submit $(docv) extra proposals."))) $ Kiln.Configuration_directory.cli_term () $ Arg.( let doc = -- GitLab From 06b60da351d45cedf54ca42342e6a06bc58c89bc Mon Sep 17 00:00:00 2001 From: Sebastien Mondet Date: Fri, 24 May 2019 16:39:33 -0400 Subject: [PATCH 08/12] Flextesa: config kiln earlier in daemons-upgrade --- .../command_daemons_protocol_change.ml | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/bin_flextesa/command_daemons_protocol_change.ml b/src/bin_flextesa/command_daemons_protocol_change.ml index e2ca9ae5ae9f..f0663a6c2259 100644 --- a/src/bin_flextesa/command_daemons_protocol_change.ml +++ b/src/bin_flextesa/command_daemons_protocol_change.ml @@ -142,12 +142,6 @@ let run state ~protocol ~size ~base_port ~no_daemons_for ?external_peer_ports (List.map nodes ~f:(Tezos_client.of_node ~exec:client_exec)) ; arbitrary_command_on_clients state ~command_names:["c0"; "client-0"] ~make_admin ~clients:[client_0] ]) ; - Test_scenario.Queries.wait_for_all_levels_to_be state - ~attempts:waiting_attempts ~seconds:10. nodes - (* TODO: wait for /chains/main/blocks/head/votes/listings to be - non-empty instead of counting blocks *) - (`At_least protocol.Tezos_protocol.blocks_per_voting_period) - >>= fun () -> (* For each node we try to see if the node knows about the protocol, if it does we're good, if not we inject it. @@ -211,8 +205,20 @@ let run state ~protocol ~size ~base_port ~no_daemons_for ?external_peer_ports , first_endorser_exec ) ; (new_protocol_hash, second_baker_exec, second_endorser_exec) ] >>= fun () -> - return EF.(wf "Kiln was configured at `%s`" kiln_config.path) ) + let msg = + EF.( + desc + (shout "Kiln-Configuration DONE") + (wf "Kiln was configured at `%s`" kiln_config.path)) + in + Console.say state msg >>= fun () -> return msg ) >>= fun kiln_info_opt -> + Test_scenario.Queries.wait_for_all_levels_to_be state + ~attempts:waiting_attempts ~seconds:10. nodes + (* TODO: wait for /chains/main/blocks/head/votes/listings to be + non-empty instead of counting blocks *) + (`At_least protocol.Tezos_protocol.blocks_per_voting_period) + >>= fun () -> Interactive_test.Pauser.generic state EF. [ wf "Test becomes interactive." -- GitLab From 52c925e44846f6b26bba8c8d91bad813063b1317 Mon Sep 17 00:00:00 2001 From: Sebastien Mondet Date: Fri, 24 May 2019 17:31:39 -0400 Subject: [PATCH 09/12] Flextesa: fix check for protocol path --- src/bin_flextesa/command_daemons_protocol_change.ml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/bin_flextesa/command_daemons_protocol_change.ml b/src/bin_flextesa/command_daemons_protocol_change.ml index f0663a6c2259..7834dd1c46e2 100644 --- a/src/bin_flextesa/command_daemons_protocol_change.ml +++ b/src/bin_flextesa/command_daemons_protocol_change.ml @@ -52,6 +52,7 @@ let run state ~protocol ~size ~base_port ~no_daemons_for ?external_peer_ports ~second_endorser_exec ~second_accuser_exec ~admin_exec ~new_protocol_path ~extra_dummy_proposals ~waiting_attempts test_variant () = Helpers.System_dependencies.precheck state `Or_fail + ~protocol_paths:[new_protocol_path] ~executables: [ node_exec; client_exec; first_baker_exec; first_endorser_exec ; first_accuser_exec; second_baker_exec; second_endorser_exec -- GitLab From c71785636fc8797f301e846c2b6b3be14a417dbd Mon Sep 17 00:00:00 2001 From: Sebastien Mondet Date: Fri, 24 May 2019 17:32:14 -0400 Subject: [PATCH 10/12] Flextesa: improve error display --- src/lib_network_sandbox/interactive_test.ml | 5 ++- .../internal_pervasives.ml | 39 +++++++++++++++---- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/lib_network_sandbox/interactive_test.ml b/src/lib_network_sandbox/interactive_test.ml index 12ce180abb0d..c5632997241e 100644 --- a/src/lib_network_sandbox/interactive_test.ml +++ b/src/lib_network_sandbox/interactive_test.ml @@ -486,7 +486,10 @@ module Pauser = struct ~force:(Interactivity.pause_on_error state) EF. [ haf "Last pause before the test will Kill 'Em All and Quit." - ; desc (shout "Error:") (af "%a" pp_error error_value) ] + ; desc (shout "Error:") + (af "%a" + (fun ppf c -> Attached_result.pp ppf c ~pp_error) + result) ] >>= fun () -> finish () >>= fun () -> fail error_value ~attach:result.attachments ) end diff --git a/src/lib_network_sandbox/internal_pervasives.ml b/src/lib_network_sandbox/internal_pervasives.ml index bf876287b454..095e8a3311f5 100644 --- a/src/lib_network_sandbox/internal_pervasives.ml +++ b/src/lib_network_sandbox/internal_pervasives.ml @@ -87,7 +87,8 @@ end (** An “decorated result type” based on polymorphic variants *) module Attached_result = struct - type content = [`Text of string | `String_value of string] + type content = + [`Text of string | `String_value of string | `Verbatim of string list] type ('ok, 'error) t = {result: ('ok, 'error) result; attachments: (string * content) list} @@ -98,6 +99,7 @@ module Attached_result = struct let pp ppf ?pp_ok ?pp_error {result; attachments} = let open Format in + pp_open_hovbox ppf 4 ; ( match result with | Ok o -> pp_open_hvbox ppf 2 ; @@ -115,18 +117,30 @@ module Attached_result = struct pp_close_tag ppf () ; Option.iter pp_error ~f:(fun pp -> pp ppf e) ; pp_close_box ppf () ) ; - match attachments with + ( match attachments with | [] -> () | more -> - pp_print_newline ppf () ; - pp_open_hovbox ppf 4 ; + pp_open_vbox ppf 4 ; List.iter more ~f:(fun (k, v) -> - pp_print_if_newline ppf () ; + pp_print_cut ppf () ; + pp_open_hovbox ppf 2 ; pp_print_string ppf "* " ; fprintf ppf "%s:@ " k ; - match v with + ( match v with | `Text s -> pp_print_text ppf s - | `String_value s -> fprintf ppf "%S" s ) + | `String_value s -> fprintf ppf "%S" s + | `Verbatim lines -> + pp_open_vbox ppf 0 ; + pp_print_cut ppf () ; + fprintf ppf "```````````````" ; + List.iter lines ~f:(fun s -> + pp_print_cut ppf () ; pp_print_string ppf s ) ; + pp_print_cut ppf () ; + fprintf ppf "```````````````" ; + pp_close_box ppf () ) ; + pp_close_box ppf () ) ; + pp_close_box ppf () ) ; + pp_close_box ppf () end (** A wrapper around [('ok, 'a Error.t) result Lwt.t]. *) @@ -172,7 +186,9 @@ module Asynchronous_result = struct | {result= Error e; attachments= attach} as res -> f ~result:res e >>= fun {result; attachments} -> - Lwt.return {result; attachments= attachments @ attach} + Lwt.return + { result + ; attachments= List.dedup_and_sort ~compare (attachments @ attach) } let transform_error o ~f = let open Lwt.Infix in @@ -182,6 +198,13 @@ module Asynchronous_result = struct | {result= Error e; attachments} -> Lwt.return {result= Error (f e); attachments} + let enrich : attachment:(string * content) list -> 'a -> ('b, 'c) t = + fun ~attachment x -> + bind_on_error x ~f:(fun ~result _ -> + Lwt.return + Attached_result. + {result with attachments= result.attachments @ attachment} ) + let bind_all : ('ok, 'error) t -> f:(('ok, 'error) Attached_result.t -> ('ok2, 'error2) t) -- GitLab From cfafed8ac652de094fc7c241e3caed2e0abe84e9 Mon Sep 17 00:00:00 2001 From: Alexandre Esteves Date: Mon, 15 Jul 2019 09:04:16 +0100 Subject: [PATCH 11/12] Flextesa: disable obsidian node in Kiln config --- src/bin_flextesa/command_daemons_protocol_change.ml | 12 ++++++------ src/lib_network_sandbox/kiln.ml | 3 +++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/bin_flextesa/command_daemons_protocol_change.ml b/src/bin_flextesa/command_daemons_protocol_change.ml index 7834dd1c46e2..41b95202ecff 100644 --- a/src/bin_flextesa/command_daemons_protocol_change.ml +++ b/src/bin_flextesa/command_daemons_protocol_change.ml @@ -4,18 +4,18 @@ open Console let failf fmt = ksprintf (fun s -> fail (`Scenario_error s)) fmt -let wait_for_voting_period ?level_withing_period state ~client ~attempts period +let wait_for_voting_period ?level_within_period state ~client ~attempts period = let period_name = Tezos_protocol.Voting_period.to_string period in let message = sprintf "Waiting for voting period: `%s`%s" period_name - (Option.value_map level_withing_period ~default:"" - ~f:(sprintf " (and level-within-period ≤ %d)")) + (Option.value_map level_within_period ~default:"" + ~f:(sprintf " (and level-within-period ≥ %d)")) in Console.say state EF.(wf "%s" message) >>= fun () -> Helpers.wait_for state ~attempts ~seconds:10. (fun nth -> - Asynchronous_result.map_option level_withing_period ~f:(fun lvl -> + Asynchronous_result.map_option level_within_period ~f:(fun lvl -> Tezos_client.rpc state ~client `Get ~path:"/chains/main/blocks/head/metadata" >>= fun json -> @@ -25,7 +25,7 @@ let wait_for_voting_period ?level_withing_period state ~client ~attempts period |> Jqo.field ~k:"voting_period_position" |> Jqo.get_int in - return (voting_period_position <= lvl) + return (voting_period_position >= lvl) with e -> failf "Cannot get level.voting_period_position: %s" (Printexc.to_string e) ) @@ -228,7 +228,7 @@ let run state ~protocol ~size ~base_port ~no_daemons_for ?external_peer_ports ~force:true >>= fun () -> wait_for_voting_period state ~client:client_0 ~attempts:waiting_attempts - Proposal ~level_withing_period:3 + Proposal ~level_within_period:3 >>= fun _ -> let submit_prop acc client hash = Tezos_client.successful_client_cmd state ~client diff --git a/src/lib_network_sandbox/kiln.ml b/src/lib_network_sandbox/kiln.ml index 492b4f3b7d6c..82c1043c3a10 100644 --- a/src/lib_network_sandbox/kiln.ml +++ b/src/lib_network_sandbox/kiln.ml @@ -66,6 +66,9 @@ module Configuration_directory = struct System.write_file state ~perm:0o777 (path // "network") ~content:network_string >>= fun () -> + System.write_file state ~perm:0o777 (path // "enable-obsidian-node") + ~content:(sprintf "%b" false) + >>= fun () -> System.write_file state ~perm:0o777 (path // "binary-paths") ~content: Ezjsonm.( -- GitLab From 6f5fd95836e12d81da72e52e057c616a4eed259e Mon Sep 17 00:00:00 2001 From: Alexandre Esteves Date: Mon, 15 Jul 2019 11:13:41 +0100 Subject: [PATCH 12/12] Flextesa: allow controlling timing of proposals --- .../command_daemons_protocol_change.ml | 51 ++++++++++++++----- src/lib_network_sandbox/kiln.ml | 3 +- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/src/bin_flextesa/command_daemons_protocol_change.ml b/src/bin_flextesa/command_daemons_protocol_change.ml index 41b95202ecff..b13a10f6c6b3 100644 --- a/src/bin_flextesa/command_daemons_protocol_change.ml +++ b/src/bin_flextesa/command_daemons_protocol_change.ml @@ -50,7 +50,8 @@ let run state ~protocol ~size ~base_port ~no_daemons_for ?external_peer_ports ?generate_kiln_config ~node_exec ~client_exec ~first_baker_exec ~first_endorser_exec ~first_accuser_exec ~second_baker_exec ~second_endorser_exec ~second_accuser_exec ~admin_exec ~new_protocol_path - ~extra_dummy_proposals ~waiting_attempts test_variant () = + ~extra_dummy_proposals_batch_size ~extra_dummy_proposals_batch_levels + ~waiting_attempts test_variant () = Helpers.System_dependencies.precheck state `Or_fail ~protocol_paths:[new_protocol_path] ~executables: @@ -244,22 +245,31 @@ let run state ~protocol ~size ~base_port ~no_daemons_for ?external_peer_ports List_sequential.iter keys_and_daemons ~f:(fun (acc, client, _) -> submit_prop acc client new_protocol_hash ) >>= fun () -> - let extra_dummy_protocol_hashes = + let make_dummy_protocol_hashes t tag = List.map - (List.init extra_dummy_proposals ~f:(fun s -> sprintf "proto-%d" s)) - ~f:(fun s -> Tezos_crypto.Protocol_hash.(hash_string [s] |> to_b58check)) + (List.init extra_dummy_proposals_batch_size ~f:(fun s -> + sprintf "proto-%s-%d" tag s )) + ~f:(fun s -> + (t, Tezos_crypto.Protocol_hash.(hash_string [s] |> to_b58check)) ) + in + let extra_dummy_protocols = + List.bind extra_dummy_proposals_batch_levels ~f:(fun l -> + make_dummy_protocol_hashes l (sprintf "%d" l) ) in Console.say state EF.( wf "Going to also vote for %s" - (String.concat ~sep:", " extra_dummy_protocol_hashes)) + (String.concat ~sep:", " (List.map extra_dummy_protocols ~f:snd))) >>= fun () -> - List_sequential.iteri extra_dummy_protocol_hashes ~f:(fun nth proto_hash -> + List_sequential.iteri extra_dummy_protocols + ~f:(fun nth (level, proto_hash) -> match List.nth keys_and_daemons (nth / 19) with - | Some (acc, client, _) -> submit_prop acc client proto_hash | None -> failf "Too many dummy protocols Vs available voting power (%d)" nth - ) + | Some (acc, client, _) -> + wait_for_voting_period state ~client:client_0 + ~attempts:waiting_attempts Proposal ~level_within_period:level + >>= fun _ -> submit_prop acc client proto_hash ) >>= fun () -> wait_for_voting_period state ~client:client_0 ~attempts:waiting_attempts Testing_vote @@ -362,7 +372,9 @@ let cmd ~pp_error () = second_endorser_exec second_accuser_exec (`Protocol_path new_protocol_path) - (`Extra_dummy_proposals extra_dummy_proposals) + (`Extra_dummy_proposals_batch_size extra_dummy_proposals_batch_size) + (`Extra_dummy_proposals_batch_levels + extra_dummy_proposals_batch_levels) generate_kiln_config test_variant state @@ -373,7 +385,8 @@ let cmd ~pp_error () = ~second_baker_exec ~second_endorser_exec ~second_accuser_exec ~admin_exec ?generate_kiln_config ~external_peer_ports ~no_daemons_for ~new_protocol_path test_variant ~waiting_attempts - ~extra_dummy_proposals + ~extra_dummy_proposals_batch_size + ~extra_dummy_proposals_batch_levels in (state, Interactive_test.Pauser.run_test ~pp_error state actual_test) ) @@ -419,11 +432,23 @@ let cmd ~pp_error () = (info [] ~doc:"The protocol to inject and vote on." ~docv:"PROTOCOL-PATH"))) $ Arg.( - pure (fun l -> `Extra_dummy_proposals l) + pure (fun l -> `Extra_dummy_proposals_batch_size l) $ value (opt int 0 - (info ["extra-dummy-proposals"] ~docv:"NUMBER" - ~doc:"Submit $(docv) extra proposals."))) + (info + ["extra-dummy-proposals-batch-size"] + ~docv:"NUMBER" + ~doc:"Submit $(docv) extra proposals per batch."))) + $ Arg.( + pure (fun x -> `Extra_dummy_proposals_batch_levels x) + $ value + (opt (list ~sep:',' int) [] + (info + ["extra-dummy-proposals-batch-levels"] + ~docv:"NUMBER" + ~doc: + "Set the levels within the proposal period where batches \ + of extra proposals appear, e.g. `3,5,7`."))) $ Kiln.Configuration_directory.cli_term () $ Arg.( let doc = diff --git a/src/lib_network_sandbox/kiln.ml b/src/lib_network_sandbox/kiln.ml index 82c1043c3a10..d32e8ab99e2d 100644 --- a/src/lib_network_sandbox/kiln.ml +++ b/src/lib_network_sandbox/kiln.ml @@ -66,7 +66,8 @@ module Configuration_directory = struct System.write_file state ~perm:0o777 (path // "network") ~content:network_string >>= fun () -> - System.write_file state ~perm:0o777 (path // "enable-obsidian-node") + System.write_file state ~perm:0o777 + (path // "enable-obsidian-node") ~content:(sprintf "%b" false) >>= fun () -> System.write_file state ~perm:0o777 (path // "binary-paths") -- GitLab