Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Part 1 of 2] Constants loader and Config loader #16186

Merged
merged 7 commits into from
Oct 20, 2024

Conversation

martyall
Copy link
Member

@martyall martyall commented Oct 4, 2024

NOTE to reviewer

All of the important changes in this PR are in runtime_config.ml and genesis_ledger_helper.ml, start there. You will see that all other changes are switching an executable to use these new load methods, and it always looks the same.

Background

In previous work we removed all/as much direct access to *_constants.Compiled.t as possible throughout the codebase (with the exception being the For_unit_tests variant). We were able to push those all the way to the various executable entrypoints, but we were still using the compiled config directly

The problem

  • Invoking the compile config directly across many files doesn't provide an easy transition to json-only config
  • Mina_cli_entrypoint and a few other executables allow you to take a --config-file parameter and apply the json config to the compile time constants. Most executables do not allow this.
  • We have (at least) two different implicit kinds of config (i.e. you will not find these types anywhere, but they are implied):
(* Common in exectuables that we use as tests, benchmarks, etc *)
type constants = 
  { genesis_constants : Genesis_constants.t
  ; constraint_constants : Genesis_constants.Constraint_constants.t
  ; proof_level : Genesis_constants.Proof_level.t
  ; compile_config : Mina_compile_config.t
(* less commonly required, e.g. you find in it `Mina_cli_entrypoint`, `Archive.Archive_cli`, things that aren't tests or tools *)
type config = 
  { constants : constants
  ; daemon : Runtime_ledger.Daemon.t (* has overlap with compile_config *)
  ; ledger : Runtime_config.Ledger.t
  ; epoch_data : Runtime_config.Epoch_data.t
  }

Most executables only requires the constants config, so we don't want to require the above config type in places where no ledger is required. We need to separate these cases in the type system.

The Solution

  • Introduce a Runtime_config.Constants module to manage the constants type above and manage loading and applying the json config file for these values.
  • Introduce a Genesis_ledger_helper.Config_loader module to manage loading runtime config that is needed for the ledger.
  • Require that code in src/lib and Mina_cli_executable uses these new loaders exclusively.
  • Add a --config-file option to CLI contexts, or create this context it if it didn't exist before

@martyall martyall changed the title build minimal set with constants and config loader Constans loader and Config loader Oct 4, 2024
@martyall martyall changed the title Constans loader and Config loader Constants loader and Config loader Oct 4, 2024
@martyall
Copy link
Member Author

martyall commented Oct 4, 2024

!ci-nightly-me

@martyall
Copy link
Member Author

martyall commented Oct 4, 2024

!ci-nightly-me

@martyall
Copy link
Member Author

martyall commented Oct 4, 2024

all important tests passing on nightlies
https://buildkite.com/o-1-labs-2/mina-end-to-end-nightlies/builds/2666

@martyall martyall marked this pull request as ready for review October 4, 2024 16:25
@martyall martyall requested review from a team as code owners October 4, 2024 16:25
@martyall martyall changed the title Constants loader and Config loader [Part 1 of 2] Constants loader and Config loader Oct 5, 2024
@martyall martyall force-pushed the martin/create-constants-loader-part-1 branch from 16119d1 to 6d10813 Compare October 7, 2024 21:01
Base automatically changed from martin/unify-json-config-loading to compatible October 8, 2024 19:36
src/lib/runtime_config/runtime_config.ml Outdated Show resolved Hide resolved
src/lib/runtime_config/runtime_config.ml Outdated Show resolved Hide resolved
src/lib/runtime_config/runtime_config.ml Outdated Show resolved Hide resolved
src/lib/runtime_config/runtime_config.ml Outdated Show resolved Hide resolved
src/lib/runtime_config/runtime_config.ml Outdated Show resolved Hide resolved
src/lib/cli_lib/commands.ml Show resolved Hide resolved
src/app/archive/lib/processor.ml Outdated Show resolved Hide resolved
src/app/archive/cli/archive_cli.ml Outdated Show resolved Hide resolved
src/app/cli/src/cli_entrypoint/mina_cli_entrypoint.ml Outdated Show resolved Hide resolved
Runtime_config.Constants.compile_config conf
in
let fee =
Option.value ~default:compile_config.default_transaction_fee fee
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks a bit odd to me: we're adding a config file parameter just to extract a single number.

I reviewed usages of default_transaction_fee in the codebase and it seems right to do the following:

  1. Remove default_transaction_fee from node config, compile config and everywhere else
  2. For CLI flag defaults (only place where the values is used) just specify manual default 0.25 (this value is in devnet and mainnet, and dev profile isn't really used for running CLI tools)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or we could place 0.25 to unconfigurable constants

Copy link
Member Author

@martyall martyall Oct 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

specify manual default 0.25

I am noticing that in practice you can get away with a lot less: https://minascan.io/mainnet/txs/pending-txs
IMO the default fee should be based on what's in the mempool, and neither the old solution, my solution, nor suggested solutions stand out as amazing.

Can I suggest that we just leave it? Loading a config file is not a super high barrier at this point, and we can always use "sensible defaults" as part of the json parser.

Or we could place 0.25 to unconfigurable constants

These are eventually configurable anyway

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO the default fee should be based on what's in the mempool, and neither the old solution, my solution, nor suggested solutions stand out as amazing.

This is definitely for future.

Neither solution stands out as amazing, but hardcoding 0.25 as the default seems still better. It feels awkward to have a config file parameter to take only default fee for a command that has a fee argument as well. And no other command uses this default transaction fee value from the config.

So, I'm removing default transaction fee from all configs and hardcode the existing value.

@martyall martyall force-pushed the martin/create-constants-loader-part-1 branch from ec99eb0 to 48603df Compare October 9, 2024 04:20
@martyall
Copy link
Member Author

martyall commented Oct 9, 2024

!ci-build-me

@martyall
Copy link
Member Author

martyall commented Oct 9, 2024

!ci-nightly-me

@martyall
Copy link
Member Author

martyall commented Oct 9, 2024

@martyall martyall requested a review from georgeee October 9, 2024 05:25
@coveralls
Copy link

coveralls commented Oct 9, 2024

Coverage Status

coverage: 33.042% (-28.0%) from 61.035%
when pulling 48603df on martin/create-constants-loader-part-1
into 0b12932 on compatible.

Value is only used in two CLI commands to supply the default value for
transaction creation. Value is always 0.25 MINA (in lightnet, devnet,
mainnet).

It makes no sense to supply this value from config (fee can be set
directly, so it was simply hardcoded to preserve existing behavior.
@georgeee georgeee requested a review from a team as a code owner October 17, 2024 19:52
@dkijania
Copy link
Member

Remove default_transaction_fee from node config looks goood

@georgeee
Copy link
Member

!ci-build-me

@georgeee
Copy link
Member

!ci-nightly-me

1 similar comment
@georgeee
Copy link
Member

!ci-nightly-me

Copy link
Member

@volhovm volhovm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK on the crypto side (not much crypto). The mappend/combine function is the most tricky one in my previous experience to get right. Eventually this should be tested by time, it's a bit hard to be fully convinced mentally that everything is OK when you do a merger of dozens of fields. Cool!

@@ -4,6 +4,10 @@ open Signature_lib
open Mina_base
open Mina_transaction

(* TODO consider a better way of setting a default transaction fee than
a fixed compile-time value *)
let default_transaction_fee = Currency.Fee.of_nanomina_int_exn 250000000
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this change was reviewed before by someone else (I see a previous discussion). Not crypto related.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, @dkijania reviewed this one specifically

{ Genesis_constants.protocol =
{ k =
Option.value ~default:a.genesis_constants.protocol.k
Option.(b.genesis >>= fun g -> g.k)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not fmap though. fmap f x is equivalent to x >>= return . f, wherease here we don't have return

But yes, it's simply map in OCaml parlance


let compile_config t = t.compile_config

let combine (a : constants) (b : t) : constants =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will not block this PR because of the writing style, but couldn't this at least be left and right? conf_a and conf_b even? Our codebase has too much non-descriptive names.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd go for combine_constants or mappend to make it more precise that this is an associative overriding operation. It is associative, right?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here t and constants are different types, so no associativity.

As for name/docs: probably constants and conf would be better names, I'll make a short follow-up PR for the matter


let compile_config t = t.compile_config

let combine (a : constants) (b : t) : constants =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now, serious ocaml noob type of question: what is t in the function type (b:t)? I don't see any t defined in scope, I assume it's also constants... isn't it? Is it just an open polymorphic type of "anything that has fields that we access within combine"?.....

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Type t is defined further above in the file, wasn't touched by the PR. Se line 1477


val compile_config : constants -> Mina_compile_config.t

val magic_for_unit_tests : t -> constants
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can .... this have a documentation please? Or a more descriptive name?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do

@georgeee
Copy link
Member

This is quite unexpected, but libp2p unit tests gets timed out on the nightly when run against this PR. This doesn't happen for the compatible.

This PR seemingly doesn't change anything that affects libp2p unit tests (only Go code and scripts could've affected that). So I'm not sure why does this happen.

@georgeee
Copy link
Member

I was able to reproduce failure of libp2p unit tests on pure compatible. Nightly of compatible is suspiciously passing, but the point is that there is evidence that this PR is not responsible for the failure of libp2p unit tests job.

I'll make a separate PR to alter timeouts in libp2p unit tests to ensure tests pass.

@georgeee georgeee merged commit e130ac7 into compatible Oct 20, 2024
46 checks passed
@georgeee georgeee deleted the martin/create-constants-loader-part-1 branch October 20, 2024 15:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants