diff --git a/src/app/cli/src/cli_entrypoint/mina_cli_entrypoint.ml b/src/app/cli/src/cli_entrypoint/mina_cli_entrypoint.ml index b93e13fd0da..02a4839b549 100644 --- a/src/app/cli/src/cli_entrypoint/mina_cli_entrypoint.ml +++ b/src/app/cli/src/cli_entrypoint/mina_cli_entrypoint.ml @@ -572,14 +572,12 @@ let setup_daemon logger ~itn_features ~default_snark_worker_fee = let to_pubsub_topic_mode_option = let open Gossip_net.Libp2p in function - | `String "ro" -> + | "ro" -> Some RO - | `String "rw" -> + | "rw" -> Some RW - | `String "none" -> + | "none" -> Some N - | `Null -> - None | _ -> raise (Error.to_exn (Error.of_string "Invalid pubsub topic mode")) in @@ -787,75 +785,74 @@ let setup_daemon logger ~itn_features ~default_snark_worker_fee = constraint_constants.block_window_duration_ms |> Float.of_int |> Time.Span.of_ms |> Mina_metrics.initialize_all ; + (* We reverse the list because we want to find the "most relevant" value, i.e. the + last time it was declared in the list of supplied config files + *) let rev_daemon_configs = List.rev_filter_map config_jsons ~f:(fun (config_file, config_json) -> - Option.map - YJ.Util.( - to_option Fn.id (YJ.Util.member "daemon" config_json)) - ~f:(fun daemon_config -> (config_file, daemon_config)) ) - in - let maybe_from_config (type a) (f : YJ.t -> a option) - (keyname : string) (actual_value : a option) : a option = - let open Option.Let_syntax in - let open YJ.Util in - match actual_value with - | Some v -> - Some v - | None -> - (* Load value from the latest config file that both - * has the key we are looking for, and - * has the key in a format that [f] can parse. - *) - let%map config_file, data = - List.find_map rev_daemon_configs - ~f:(fun (config_file, daemon_config) -> - let%bind json_val = - to_option Fn.id (member keyname daemon_config) - in - let%map data = f json_val in - (config_file, data) ) - in - [%log debug] "Key $key being used from config file $config_file" - ~metadata: - [ ("key", `String keyname) - ; ("config_file", `String config_file) - ] ; - data + Yojson.Safe.Util.member "daemon" config_json + |> fun x -> + Runtime_config.Daemon.of_yojson x + |> Result.ok + |> Option.map ~f:(fun daemon_config -> + (config_file, daemon_config) ) ) in - let or_from_config map keyname actual_value ~default = - match maybe_from_config map keyname actual_value with - | Some x -> - x - | None -> - [%log trace] - "Key '$key' not found in the config file, using default" - ~metadata:[ ("key", `String keyname) ] ; - default + + let module DC = Runtime_config.Daemon in + (* The explicit typing here is necessary to prevent type inference from specializing according + to the first usage. + *) + let maybe_from_config (type a) : + getter:(DC.t -> a option) + -> keyname:string + -> preferred_value:a option + -> a option = + fun ~getter ~keyname ~preferred_value -> + Runtime_config.Config_loader.maybe_from_config ~logger + ~configs:rev_daemon_configs ~getter ~keyname ~preferred_value + in + let or_from_config (type a) : + getter:(DC.t -> a option) + -> keyname:string + -> preferred_value:a option + -> default:a + -> a = + fun ~getter ~keyname ~preferred_value ~default -> + Runtime_config.Config_loader.or_from_config ~logger + ~configs:rev_daemon_configs ~getter ~keyname ~preferred_value + ~default in - let get_port { Flag.Types.value; default; name } = - or_from_config YJ.Util.to_int_option name ~default value + + let libp2p_port = + or_from_config ~keyname:"libp2p-port" ~getter:DC.libp2p_port + ~preferred_value:libp2p_port.value ~default:libp2p_port.default in - let libp2p_port = get_port libp2p_port in - let rest_server_port = get_port rest_server_port in - let limited_graphql_port = - let ({ value; name } : int option Flag.Types.with_name) = - limited_graphql_port - in - maybe_from_config YJ.Util.to_int_option name value + let rest_server_port = + or_from_config ~keyname:"rest-port" ~getter:DC.rest_port + ~preferred_value:rest_server_port.value + ~default:rest_server_port.default in - let client_port = get_port client_port in - let snark_work_fee_flag = - let json_to_currency_fee_option json = - YJ.Util.to_int_option json - |> Option.map ~f:Currency.Fee.of_nanomina_int_exn - in - or_from_config json_to_currency_fee_option "snark-worker-fee" - ~default:compile_config.default_snark_worker_fee snark_work_fee + let limited_graphql_port = + maybe_from_config ~keyname:"limited-graphql-port" + ~getter:DC.graphql_port + ~preferred_value:limited_graphql_port.value + in + let client_port = + or_from_config ~keyname:"client-port" ~getter:DC.client_port + ~preferred_value:client_port.value ~default:client_port.default + in + let snark_work_fee = + or_from_config ~keyname:"snark-worker-fee" + ~getter:(fun x -> + DC.snark_worker_fee x + |> Option.map ~f:Currency.Fee.of_nanomina_int_exn ) + ~preferred_value:snark_work_fee + ~default:compile_config.default_snark_worker_fee in let node_status_url = - maybe_from_config YJ.Util.to_string_option "node-status-url" - node_status_url + maybe_from_config ~keyname:"node-status-url" + ~getter:DC.node_status_url ~preferred_value:node_status_url in (* FIXME #4095: pass this through to Gossip_net.Libp2p *) let _max_concurrent_connections = @@ -867,29 +864,33 @@ let setup_daemon logger ~itn_features ~default_snark_worker_fee = None in let work_selection_method = - or_from_config - (Fn.compose Option.return - (Fn.compose work_selection_method_val YJ.Util.to_string) ) - "work-selection" + or_from_config ~keyname:"work-selection" + ~getter:(fun x -> + DC.work_selection x + |> Option.map ~f:Cli_lib.Arg_type.work_selection_method_val ) + ~preferred_value:work_selection_method_flag ~default:Cli_lib.Arg_type.Work_selection_method.Random - work_selection_method_flag in let work_reassignment_wait = - or_from_config YJ.Util.to_int_option "work-reassignment-wait" + or_from_config ~keyname:"work-reassignment-wait" + ~getter:DC.work_reassignment_wait + ~preferred_value:work_reassignment_wait ~default:Cli_lib.Default.work_reassignment_wait - work_reassignment_wait in let log_received_snark_pool_diff = - or_from_config YJ.Util.to_bool_option "log-snark-work-gossip" - ~default:false log_received_snark_pool_diff + or_from_config ~keyname:"log-snark-work-gossip" + ~getter:DC.log_snark_work_gossip + ~preferred_value:log_received_snark_pool_diff ~default:false in let log_transaction_pool_diff = - or_from_config YJ.Util.to_bool_option "log-txn-pool-gossip" - ~default:false log_transaction_pool_diff + or_from_config ~keyname:"log-txn-pool-gossip" + ~getter:DC.log_txn_pool_gossip + ~preferred_value:log_transaction_pool_diff ~default:false in let log_block_creation = - or_from_config YJ.Util.to_bool_option "log-block-creation" - ~default:true log_block_creation + or_from_config ~keyname:"log-block-creation" + ~getter:DC.log_block_creation ~preferred_value:log_block_creation + ~default:true in let log_gossip_heard = { Mina_networking.Config.snark_pool_diff = @@ -898,42 +899,51 @@ let setup_daemon logger ~itn_features ~default_snark_worker_fee = ; new_state = true } in - let json_to_publickey_compressed_option which json = - YJ.Util.to_string_option json - |> Option.bind ~f:(fun pk_str -> - match Public_key.Compressed.of_base58_check pk_str with - | Ok key -> ( - match Public_key.decompress key with - | None -> - Mina_user_error.raisef - ~where:"decompressing a public key" - "The %s public key %s could not be decompressed." - which pk_str - | Some _ -> - Some key ) - | Error _e -> - Mina_user_error.raisef ~where:"decoding a public key" - "The %s public key %s could not be decoded." which - pk_str ) + let to_publickey_compressed_option which pk_str = + match Public_key.Compressed.of_base58_check pk_str with + | Ok key -> ( + match Public_key.decompress key with + | None -> + Mina_user_error.raisef ~where:"decompressing a public key" + "The %s public key %s could not be decompressed." which + pk_str + | Some _ -> + Some key ) + | Error _e -> + Mina_user_error.raisef ~where:"decoding a public key" + "The %s public key %s could not be decoded." which pk_str in let run_snark_worker_flag = - maybe_from_config - (json_to_publickey_compressed_option "snark worker") - "run-snark-worker" run_snark_worker_flag + maybe_from_config ~keyname:"run-snark-worker" + ~getter: + Option.( + fun x -> + DC.run_snark_worker x + >>= to_publickey_compressed_option "snark_worker") + ~preferred_value:run_snark_worker_flag in let run_snark_coordinator_flag = - maybe_from_config - (json_to_publickey_compressed_option "snark coordinator") - "run-snark-coordinator" run_snark_coordinator_flag + maybe_from_config ~keyname:"run-snark-coordinator" + ~getter: + Option.( + fun x -> + DC.run_snark_coordinator x + >>= to_publickey_compressed_option "snark_coordinator") + ~preferred_value:run_snark_coordinator_flag in let snark_worker_parallelism_flag = - maybe_from_config YJ.Util.to_int_option "snark-worker-parallelism" - snark_worker_parallelism_flag + maybe_from_config ~keyname:"snark-worker-parallelism" + ~getter:DC.snark_worker_parallelism + ~preferred_value:snark_worker_parallelism_flag in let coinbase_receiver_flag = - maybe_from_config - (json_to_publickey_compressed_option "coinbase receiver") - "coinbase-receiver" coinbase_receiver_flag + maybe_from_config ~keyname:"coinbase-receiver" + ~getter: + Option.( + fun x -> + DC.coinbase_receiver x + >>= to_publickey_compressed_option "coinbase_receiver") + ~preferred_value:coinbase_receiver_flag in let%bind external_ip = match external_ip_opt with @@ -950,17 +960,23 @@ let setup_daemon logger ~itn_features ~default_snark_worker_fee = { external_ip; bind_ip; peer = None; client_port; libp2p_port } in let block_production_key = - maybe_from_config YJ.Util.to_string_option "block-producer-key" - block_production_key + maybe_from_config ~keyname:"block-producer-key" + ~getter:DC.block_producer_key + ~preferred_value:block_production_key in let block_production_pubkey = - maybe_from_config - (json_to_publickey_compressed_option "block producer") - "block-producer-pubkey" block_production_pubkey + maybe_from_config ~keyname:"block-producer-pubkey" + ~getter: + Option.( + fun x -> + DC.block_producer_pubkey x + >>= to_publickey_compressed_option "block_producer") + ~preferred_value:block_production_pubkey in let block_production_password = - maybe_from_config YJ.Util.to_string_option "block-producer-password" - block_production_password + maybe_from_config ~keyname:"block-producer-password" + ~getter:DC.block_producer_password + ~preferred_value:block_production_password in Option.iter ~f:(fun password -> @@ -1187,26 +1203,28 @@ let setup_daemon logger ~itn_features ~default_snark_worker_fee = /ip4/IPADDR/tcp/PORT/p2p/PEERID)" raw_peer ) ; let initial_peers = + let peers = + or_from_config ~keyname:"peers" ~getter:DC.peers + ~preferred_value:None ~default:[] + in List.concat [ List.map ~f:Mina_net2.Multiaddr.of_string libp2p_peers_raw ; peer_list_file_contents_or_empty - ; List.map ~f:Mina_net2.Multiaddr.of_string - @@ or_from_config - (Fn.compose Option.some - (YJ.Util.convert_each YJ.Util.to_string) ) - "peers" None ~default:[] + ; List.map ~f:Mina_net2.Multiaddr.of_string @@ peers ] in let direct_peers = List.map ~f:Mina_net2.Multiaddr.of_string direct_peers_raw in let min_connections = - or_from_config YJ.Util.to_int_option "min-connections" - ~default:Cli_lib.Default.min_connections min_connections + or_from_config ~keyname:"min-connections" ~getter:DC.min_connections + ~preferred_value:min_connections + ~default:Cli_lib.Default.min_connections in let max_connections = - or_from_config YJ.Util.to_int_option "max-connections" - ~default:Cli_lib.Default.max_connections max_connections + or_from_config ~keyname:"max-connections" ~getter:DC.max_connections + ~preferred_value:max_connections + ~default:Cli_lib.Default.max_connections in let pubsub_v1 = Gossip_net.Libp2p.N in (* TODO uncomment after introducing Bitswap-based block retrieval *) @@ -1215,17 +1233,21 @@ let setup_daemon logger ~itn_features ~default_snark_worker_fee = ~default:Cli_lib.Default.pubsub_v1 pubsub_v1 in *) let pubsub_v0 = - or_from_config to_pubsub_topic_mode_option "pubsub-v0" - ~default:Cli_lib.Default.pubsub_v0 None + or_from_config ~keyname:"pubsub-v0" + ~getter: + Option.(fun x -> DC.pubsub_v0 x >>= to_pubsub_topic_mode_option) + ~preferred_value:None ~default:Cli_lib.Default.pubsub_v0 in + let validation_queue_size = - or_from_config YJ.Util.to_int_option "validation-queue-size" + or_from_config ~keyname:"validation-queue-size" + ~getter:DC.validation_queue_size + ~preferred_value:validation_queue_size ~default:Cli_lib.Default.validation_queue_size - validation_queue_size in let stop_time = - or_from_config YJ.Util.to_int_option "stop-time" - ~default:Cli_lib.Default.stop_time stop_time + or_from_config ~keyname:"stop-time" ~getter:DC.stop_time + ~preferred_value:stop_time ~default:Cli_lib.Default.stop_time in if enable_tracing then Mina_tracing.start conf_dir |> don't_wait_for ; let%bind () = @@ -1397,16 +1419,16 @@ Pass one of -peer, -peer-list-file, -seed, -peer-list-url.|} ; ~wallets_disk_location:(conf_dir ^/ "wallets") ~persistent_root_location:(conf_dir ^/ "root") ~persistent_frontier_location:(conf_dir ^/ "frontier") - ~epoch_ledger_location ~snark_work_fee:snark_work_fee_flag - ~time_controller ~block_production_keypairs ~monitor - ~consensus_local_state ~is_archive_rocksdb - ~work_reassignment_wait ~archive_process_location - ~log_block_creation ~precomputed_values ~start_time - ?precomputed_blocks_path ~log_precomputed_blocks - ~start_filtered_logs ~upload_blocks_to_gcloud - ~block_reward_threshold ~uptime_url ~uptime_submitter_keypair - ~uptime_send_node_commit ~stop_time ~node_status_url - ~graphql_control_port:itn_graphql_port ~simplified_node_stats + ~epoch_ledger_location ~snark_work_fee ~time_controller + ~block_production_keypairs ~monitor ~consensus_local_state + ~is_archive_rocksdb ~work_reassignment_wait + ~archive_process_location ~log_block_creation + ~precomputed_values ~start_time ?precomputed_blocks_path + ~log_precomputed_blocks ~start_filtered_logs + ~upload_blocks_to_gcloud ~block_reward_threshold ~uptime_url + ~uptime_submitter_keypair ~uptime_send_node_commit ~stop_time + ~node_status_url ~graphql_control_port:itn_graphql_port + ~simplified_node_stats ~zkapp_cmd_limit:(ref compile_config.zkapp_cmd_limit) ~compile_config () ) in diff --git a/src/lib/integration_test_cloud_engine/mina_automation.ml b/src/lib/integration_test_cloud_engine/mina_automation.ml index 5a5491d4ac2..5615ea158de 100644 --- a/src/lib/integration_test_cloud_engine/mina_automation.ml +++ b/src/lib/integration_test_cloud_engine/mina_automation.ml @@ -233,18 +233,10 @@ module Network_config = struct let runtime_config = { Runtime_config.daemon = Some - { txpool_max_size = Some txpool_max_size - ; peer_list_url = None - ; zkapp_proof_update_cost = None - ; zkapp_signed_single_update_cost = None - ; zkapp_signed_pair_update_cost = None - ; zkapp_transaction_cost_limit = None - ; max_event_elements = None - ; max_action_elements = None - ; zkapp_cmd_limit_hardcap = None + { Runtime_config.Daemon.default with + txpool_max_size = Some txpool_max_size ; slot_tx_end ; slot_chain_end - ; minimum_user_command_fee = None ; network_id } ; genesis = diff --git a/src/lib/integration_test_local_engine/mina_docker.ml b/src/lib/integration_test_local_engine/mina_docker.ml index f0f15c20b7e..6784194c4ab 100644 --- a/src/lib/integration_test_local_engine/mina_docker.ml +++ b/src/lib/integration_test_local_engine/mina_docker.ml @@ -156,7 +156,8 @@ module Network_config = struct let runtime_config = { Runtime_config.daemon = Some - { txpool_max_size = Some txpool_max_size + { Runtime_config.Daemon.default with + txpool_max_size = Some txpool_max_size ; peer_list_url = None ; zkapp_proof_update_cost = Some 10.26 ; zkapp_signed_single_update_cost = Some 9.140000000000001 diff --git a/src/lib/runtime_config/dune b/src/lib/runtime_config/dune index f7f5ff7d3ce..41e498ec504 100644 --- a/src/lib/runtime_config/dune +++ b/src/lib/runtime_config/dune @@ -43,4 +43,4 @@ ) (instrumentation (backend bisect_ppx)) (preprocess (pps ppx_custom_printf ppx_sexp_conv ppx_let ppx_deriving_yojson - ppx_fields_conv ppx_version ppx_compare ppx_here))) + ppx_fields_conv ppx_version ppx_compare ppx_here ppx_mina))) diff --git a/src/lib/runtime_config/runtime_config.ml b/src/lib/runtime_config/runtime_config.ml index e8786cbec4c..9001c2792ac 100644 --- a/src/lib/runtime_config/runtime_config.ml +++ b/src/lib/runtime_config/runtime_config.ml @@ -9,14 +9,6 @@ module Fork_config = struct ; global_slot_since_genesis : int (* global slot since genesis *) } [@@deriving yojson, bin_io_unversioned] - - let gen = - let open Quickcheck.Generator.Let_syntax in - let%bind global_slot_since_genesis = Int.gen_incl 0 1_000_000 in - let%bind blockchain_length = Int.gen_incl 0 global_slot_since_genesis in - let%map state_hash = Mina_base.State_hash.gen in - let state_hash = Mina_base.State_hash.to_base58_check state_hash in - { state_hash; blockchain_length; global_slot_since_genesis } end let yojson_strip_fields ~keep_fields = function @@ -475,6 +467,42 @@ module Json_layout = struct ; slot_chain_end : int option [@default None] ; minimum_user_command_fee : Currency.Fee.t option [@default None] ; network_id : string option [@default None] + ; client_port : int option [@default None] [@key "client-port"] + ; libp2p_port : int option [@default None] [@key "libp2p-port"] + ; rest_port : int option [@default None] [@key "rest-port"] + ; graphql_port : int option [@default None] [@key "limited-graphql-port"] + ; node_status_url : string option [@default None] [@key "node-status-url"] + ; block_producer_key : string option + [@default None] [@key "block-producer-key"] + ; block_producer_pubkey : string option + [@default None] [@key "block-producer-pubkey"] + ; block_producer_password : string option + [@default None] [@key "block-producer-password"] + ; coinbase_receiver : string option + [@default None] [@key "coinbase-receiver"] + ; run_snark_worker : string option + [@default None] [@key "run-snark-worker"] + ; run_snark_coordinator : string option + [@default None] [@key "run-snark-coordinator"] + ; snark_worker_fee : int option [@default None] [@key "snark-worker-fee"] + ; snark_worker_parallelism : int option + [@default None] [@key "snark-worker-parallelism"] + ; work_selection : string option [@default None] [@key "work-selection"] + ; work_reassignment_wait : int option + [@default None] [@key "work-reassignment-wait"] + ; log_txn_pool_gossip : bool option + [@default None] [@key "log-txn-pool-gossip"] + ; log_snark_work_gossip : bool option + [@default None] [@key "log-snark-work-gossip"] + ; log_block_creation : bool option + [@default None] [@key "log-block-creation"] + ; min_connections : int option [@default None] [@key "min-connections"] + ; max_connections : int option [@default None] [@key "max-connections"] + ; pubsub_v0 : string option [@default None] [@key "pubsub-v0"] + ; validation_queue_size : int option + [@default None] [@key "validation-queue-size"] + ; stop_time : int option [@default None] [@key "stop-time"] + ; peers : string list option [@default None] [@key "peers"] } [@@deriving yojson, fields] @@ -770,11 +798,6 @@ module Accounts = struct ; permissions ; zkapp = Option.map ~f:mk_zkapp a.zkapp } - - let gen = - Quickcheck.Generator.map Mina_base.Account.gen ~f:(fun a -> - (* This will never fail with a proper account generator. *) - of_account a |> Result.ok_or_failwith ) end type single = Single.t = @@ -912,29 +935,6 @@ module Ledger = struct let of_yojson json = Result.bind ~f:of_json_layout (Json_layout.Ledger.of_yojson json) - - let gen = - let open Quickcheck in - let open Generator.Let_syntax in - let%bind accounts = Generator.list Accounts.Single.gen in - let num_accounts = List.length accounts in - let balances = - List.mapi accounts ~f:(fun number a -> (number, a.balance)) - in - let%bind hash = - Mina_base.Ledger_hash.(Generator.map ~f:to_base58_check gen) - |> Option.quickcheck_generator - in - let%bind name = String.gen_nonempty in - let%map add_genesis_winner = Bool.quickcheck_generator in - { base = Accounts accounts - ; num_accounts = Some num_accounts - ; balances - ; hash - ; s3_data_hash = None - ; name = Some name - ; add_genesis_winner = Some add_genesis_winner - } end module Proof_keys = struct @@ -976,8 +976,6 @@ module Proof_keys = struct Error "Runtime_config.Proof_keys.Level.of_json_layout: Expected the \ field 'level' to contain a string" - - let gen = Quickcheck.Generator.of_list [ Full; Check; No_check ] end module Transaction_capacity = struct @@ -1011,16 +1009,6 @@ module Proof_keys = struct Result.bind ~f:of_json_layout (Json_layout.Proof_keys.Transaction_capacity.of_yojson json) - let gen = - let open Quickcheck in - let log_2_gen = - Generator.map ~f:(fun i -> Log_2 i) @@ Int.gen_incl 0 10 - in - let txns_per_second_x10_gen = - Generator.map ~f:(fun i -> Txns_per_second_x10 i) @@ Int.gen_incl 0 1000 - in - Generator.union [ log_2_gen; txns_per_second_x10_gen ] - let small : t = Log_2 2 let medium : t = Log_2 3 @@ -1135,37 +1123,6 @@ module Proof_keys = struct opt_fallthrough ~default:t1.account_creation_fee t2.account_creation_fee ; fork = opt_fallthrough ~default:t1.fork t2.fork } - - let gen = - let open Quickcheck.Generator.Let_syntax in - let%bind level = Level.gen in - let%bind sub_windows_per_window = Int.gen_incl 0 1000 in - let%bind ledger_depth = Int.gen_incl 0 64 in - let%bind work_delay = Int.gen_incl 0 1000 in - let%bind block_window_duration_ms = Int.gen_incl 1_000 360_000 in - let%bind transaction_capacity = Transaction_capacity.gen in - let%bind coinbase_amount = - Currency.Amount.(gen_incl zero (of_mina_int_exn 1)) - in - let%bind supercharged_coinbase_factor = Int.gen_incl 0 100 in - let%bind account_creation_fee = - Currency.Fee.(gen_incl one (of_mina_int_exn 10)) - in - let%map fork = - let open Quickcheck.Generator in - union [ map ~f:Option.some Fork_config.gen; return None ] - in - { level = Some level - ; sub_windows_per_window = Some sub_windows_per_window - ; ledger_depth = Some ledger_depth - ; work_delay = Some work_delay - ; block_window_duration_ms = Some block_window_duration_ms - ; transaction_capacity = Some transaction_capacity - ; coinbase_amount = Some coinbase_amount - ; supercharged_coinbase_factor = Some supercharged_coinbase_factor - ; account_creation_fee = Some account_creation_fee - ; fork - } end module Genesis = struct @@ -1202,30 +1159,6 @@ module Genesis = struct opt_fallthrough ~default:t1.genesis_state_timestamp t2.genesis_state_timestamp } - - let gen = - let open Quickcheck.Generator.Let_syntax in - let%bind k = Int.gen_incl 0 1000 in - let%bind delta = Int.gen_incl 0 1000 in - let%bind slots_per_epoch = Int.gen_incl 1 1_000_000 in - let%bind slots_per_sub_window = Int.gen_incl 1 1_000 in - let%bind grace_period_slots = - Quickcheck.Generator.union - [ return None - ; Quickcheck.Generator.map ~f:Option.some @@ Int.gen_incl 0 1000 - ] - in - let%map genesis_state_timestamp = - Time.(gen_incl epoch (of_string "2050-01-01 00:00:00Z")) - |> Quickcheck.Generator.map ~f:Time.to_string - in - { k = Some k - ; delta = Some delta - ; slots_per_epoch = Some slots_per_epoch - ; slots_per_sub_window = Some slots_per_sub_window - ; grace_period_slots - ; genesis_state_timestamp = Some genesis_state_timestamp - } end module Daemon = struct @@ -1247,8 +1180,72 @@ module Daemon = struct ; minimum_user_command_fee : Currency.Fee.Stable.Latest.t option [@default None] ; network_id : string option [@default None] + ; client_port : int option [@default None] + ; libp2p_port : int option [@default None] + ; rest_port : int option [@default None] + ; graphql_port : int option [@default None] + ; node_status_url : string option [@default None] + ; block_producer_key : string option [@default None] + ; block_producer_pubkey : string option [@default None] + ; block_producer_password : string option [@default None] + ; coinbase_receiver : string option [@default None] + ; run_snark_worker : string option [@default None] + ; run_snark_coordinator : string option [@default None] + ; snark_worker_fee : int option [@default None] + ; snark_worker_parallelism : int option [@default None] + ; work_selection : string option [@default None] + ; work_reassignment_wait : int option [@default None] + ; log_txn_pool_gossip : bool option [@default None] + ; log_snark_work_gossip : bool option [@default None] + ; log_block_creation : bool option [@default None] + ; min_connections : int option [@default None] + ; max_connections : int option [@default None] + ; pubsub_v0 : string option [@default None] + ; validation_queue_size : int option [@default None] + ; stop_time : int option [@default None] + ; peers : string list option [@default None] + } + [@@deriving bin_io_unversioned, fields] + + let default : t = + { txpool_max_size = None + ; peer_list_url = None + ; zkapp_proof_update_cost = None + ; zkapp_signed_single_update_cost = None + ; zkapp_signed_pair_update_cost = None + ; zkapp_transaction_cost_limit = None + ; max_event_elements = None + ; max_action_elements = None + ; zkapp_cmd_limit_hardcap = None + ; slot_tx_end = None + ; slot_chain_end = None + ; minimum_user_command_fee = None + ; network_id = None + ; client_port = None + ; libp2p_port = None + ; rest_port = None + ; graphql_port = None + ; node_status_url = None + ; block_producer_key = None + ; block_producer_pubkey = None + ; block_producer_password = None + ; coinbase_receiver = None + ; run_snark_worker = None + ; run_snark_coordinator = None + ; snark_worker_fee = None + ; snark_worker_parallelism = None + ; work_selection = None + ; work_reassignment_wait = None + ; log_txn_pool_gossip = None + ; log_snark_work_gossip = None + ; log_block_creation = None + ; min_connections = None + ; max_connections = None + ; pubsub_v0 = None + ; validation_queue_size = None + ; stop_time = None + ; peers = None } - [@@deriving bin_io_unversioned] let to_json_layout : t -> Json_layout.Daemon.t = Fn.id @@ -1290,34 +1287,54 @@ module Daemon = struct opt_fallthrough ~default:t1.minimum_user_command_fee t2.minimum_user_command_fee ; network_id = opt_fallthrough ~default:t1.network_id t2.network_id - } - - let gen = - let open Quickcheck.Generator.Let_syntax in - let%bind txpool_max_size = Int.gen_incl 0 1000 in - let%bind zkapp_proof_update_cost = Float.gen_incl 0.0 100.0 in - let%bind zkapp_signed_single_update_cost = Float.gen_incl 0.0 100.0 in - let%bind zkapp_signed_pair_update_cost = Float.gen_incl 0.0 100.0 in - let%bind zkapp_transaction_cost_limit = Float.gen_incl 0.0 100.0 in - let%bind max_event_elements = Int.gen_incl 0 100 in - let%bind zkapp_cmd_limit_hardcap = Int.gen_incl 0 1000 in - let%bind minimum_user_command_fee = - Currency.Fee.(gen_incl one (of_mina_int_exn 10)) - in - let%map max_action_elements = Int.gen_incl 0 1000 in - { txpool_max_size = Some txpool_max_size - ; peer_list_url = None - ; zkapp_proof_update_cost = Some zkapp_proof_update_cost - ; zkapp_signed_single_update_cost = Some zkapp_signed_single_update_cost - ; zkapp_signed_pair_update_cost = Some zkapp_signed_pair_update_cost - ; zkapp_transaction_cost_limit = Some zkapp_transaction_cost_limit - ; max_event_elements = Some max_event_elements - ; max_action_elements = Some max_action_elements - ; zkapp_cmd_limit_hardcap = Some zkapp_cmd_limit_hardcap - ; slot_tx_end = None - ; slot_chain_end = None - ; minimum_user_command_fee = Some minimum_user_command_fee - ; network_id = None + ; client_port = opt_fallthrough ~default:t1.client_port t2.client_port + ; libp2p_port = opt_fallthrough ~default:t1.libp2p_port t2.libp2p_port + ; rest_port = opt_fallthrough ~default:t1.rest_port t2.rest_port + ; graphql_port = opt_fallthrough ~default:t1.graphql_port t2.graphql_port + ; node_status_url = + opt_fallthrough ~default:t1.node_status_url t2.node_status_url + ; block_producer_key = + opt_fallthrough ~default:t1.block_producer_key t2.block_producer_key + ; block_producer_pubkey = + opt_fallthrough ~default:t1.block_producer_pubkey + t2.block_producer_pubkey + ; block_producer_password = + opt_fallthrough ~default:t1.block_producer_password + t2.block_producer_password + ; coinbase_receiver = + opt_fallthrough ~default:t1.coinbase_receiver t2.coinbase_receiver + ; run_snark_worker = + opt_fallthrough ~default:t1.run_snark_worker t2.run_snark_worker + ; run_snark_coordinator = + opt_fallthrough ~default:t1.run_snark_coordinator + t2.run_snark_coordinator + ; snark_worker_fee = + opt_fallthrough ~default:t1.snark_worker_fee t2.snark_worker_fee + ; snark_worker_parallelism = + opt_fallthrough ~default:t1.snark_worker_parallelism + t2.snark_worker_parallelism + ; work_selection = + opt_fallthrough ~default:t1.work_selection t2.work_selection + ; work_reassignment_wait = + opt_fallthrough ~default:t1.work_reassignment_wait + t2.work_reassignment_wait + ; log_txn_pool_gossip = + opt_fallthrough ~default:t1.log_txn_pool_gossip t2.log_txn_pool_gossip + ; log_snark_work_gossip = + opt_fallthrough ~default:t1.log_snark_work_gossip + t2.log_snark_work_gossip + ; log_block_creation = + opt_fallthrough ~default:t1.log_block_creation t2.log_block_creation + ; min_connections = + opt_fallthrough ~default:t1.min_connections t2.min_connections + ; max_connections = + opt_fallthrough ~default:t1.max_connections t2.max_connections + ; pubsub_v0 = opt_fallthrough ~default:t1.pubsub_v0 t2.pubsub_v0 + ; validation_queue_size = + opt_fallthrough ~default:t1.validation_queue_size + t2.validation_queue_size + ; stop_time = opt_fallthrough ~default:t1.stop_time t2.stop_time + ; peers = opt_fallthrough ~default:t1.peers t2.peers } end @@ -1325,12 +1342,6 @@ module Epoch_data = struct module Data = struct type t = { ledger : Ledger.t; seed : string } [@@deriving bin_io_unversioned, yojson] - - let gen = - let open Quickcheck.Generator.Let_syntax in - let%bind ledger = Ledger.gen in - let%map seed = String.gen_nonempty in - { ledger; seed } end type t = @@ -1405,12 +1416,6 @@ module Epoch_data = struct let of_yojson json = Result.bind ~f:of_json_layout (Json_layout.Epoch_data.of_yojson json) - - let gen = - let open Quickcheck.Generator.Let_syntax in - let%bind staking = Data.gen in - let%map next = Option.quickcheck_generator Data.gen in - { staking; next } end type t = @@ -1420,7 +1425,7 @@ type t = ; ledger : Ledger.t option ; epoch_data : Epoch_data.t option } -[@@deriving bin_io_unversioned] +[@@deriving bin_io_unversioned, fields] let make ?daemon ?genesis ?proof ?ledger ?epoch_data () = { daemon; genesis; proof; ledger; epoch_data } @@ -1502,20 +1507,6 @@ let combine t1 t2 = ; epoch_data = opt_fallthrough ~default:t1.epoch_data t2.epoch_data } -let gen = - let open Quickcheck.Generator.Let_syntax in - let%map daemon = Daemon.gen - and genesis = Genesis.gen - and proof = Proof_keys.gen - and ledger = Ledger.gen - and epoch_data = Epoch_data.gen in - { daemon = Some daemon - ; genesis = Some genesis - ; proof = Some proof - ; ledger = Some ledger - ; epoch_data = Some epoch_data - } - let ledger_accounts (ledger : Mina_ledger.Ledger.Any_ledger.witness) = let open Async.Deferred.Result.Let_syntax in let yield = Async_unix.Scheduler.yield_every ~n:100 |> Staged.unstage in @@ -1621,3 +1612,38 @@ let slot_tx_end, slot_chain_end = t.daemon >>= get_runtime >>| Mina_numbers.Global_slot_since_hard_fork.of_int in (f (fun d -> d.slot_tx_end), f (fun d -> d.slot_chain_end)) + +module Config_loader = struct + (* Use the prefered value if available. Otherwise, given a list of confs + find the first conf such that the getter returns a Some. + *) + let maybe_from_config (type conf a) ~(logger : Logger.t) + ~(configs : (string * conf) list) ~(getter : conf -> a option) + ~(keyname : string) ~(preferred_value : a option) : a option = + match preferred_value with + | Some v -> + Some v + | None -> + let open Option.Let_syntax in + let%map config_file, data = + List.find_map configs ~f:(fun (config_file, daemon_config) -> + let%map a = getter daemon_config in + (config_file, a) ) + in + [%log debug] "Key $key being used from config file $config_file" + ~metadata: + [ ("key", `String keyname); ("config_file", `String config_file) ] ; + data + + let or_from_config ~logger ~configs ~getter ~keyname ~preferred_value ~default + = + match + maybe_from_config ~logger ~configs ~getter ~keyname ~preferred_value + with + | Some x -> + x + | None -> + [%log trace] "Key '$key' not found in any config files, using default" + ~metadata:[ ("key", `String keyname) ] ; + default +end