Closed mrmr1993 closed 2 years ago
@Firobe You are the likely assignee of this work, and this work deemed to be of higher priority than the issues that you are currently working on, FYI. (This is because it is a blocker for other work which must start in ~2 weeks.)
@mrmr1993 I have a few questions:
Wire
submodules (or used to) but not always.Mina_wire_types.Amount.t
can ever be constructed, so values obtained through Mk_amount
won't be compatible with functions across the codebase expecting to consume/deconstruct a Mina_wire_types.Amount.t
. Maybe it would be clearer if I had an idea of how you expect such private/abstract types would be used after being separated in their own library.amount.ml
matches the one in mina_wire_types.ml
? (but then, why even have concrete types mina_wire_types.ml
with concrete types, except for documentation?).Also a small remark, in your examples as is, functions cannot be derived here
(functor (A : sig type t = Unsigned.UInt64.t end) -> struct
type t = A.t [@@deriving foo, bar]
end)
since ppx_deriving
is looking for A.pp
(for show
, for example) and isn't smart enough to follow the type equation to Unsigned.Uint64.pp
. But this can probably be worked around via other means, depending on the kind of t
.
- if I want to do this, how do I discover what types should end up here?
It would be good to start with the gossip types, which are currently Network_pool.Transaction_pool.Diff_versioned.Stable.V2.t
, Network_pool.Snark_pool.Diff_versioned.Stable.V2.t
, and Mina_block.External_transition.Raw.Stable.V2.t
(per here). Those types include most of the important data and structure in the protocol, but it would also be nice to also add RPC types, which top out as the request/response types in Mina_networking
(e.g. here).
- I understand your examples for private/abstract types but I fail to see the point of having such types in the library in the first place.
The point is, they are already private types. The idea of this library is that it will be a source of truth for types, but containing no code. Ideally, the only changes across the rest of codebase would be to add = Mina_wire_types.Foo.t
to the type declarations along the path.
In your example, no value of type
Mina_wire_types.Amount.t
can ever be constructed, so values obtained throughMk_amount
won't be compatible with functions across the codebase expecting to consume/deconstruct aMina_wire_types.Amount.t
Those functions should still live in the Currency.Amount
submodule. The intention of Mk_amount
was to allow that code to be written over UInt32.t
/UInt64.t
as before, but then using that functor to make the top type equal to Mina_wire_types.Amount.t
rather than making them opaque at the Currency.Amount
level. In practice then, any opaque type that previously had a constructor will still have one, buf the opaque type itself has been lowered to the Mina_wire_types
library.
Also a small remark, in your examples as is, functions cannot be derived here
...
since
ppx_deriving
is looking forA.pp
(forshow
, for example) and isn't smart enough to follow the type equation toUnsigned.Uint64.pp
.
Indeed, using Unsigned.Uint64.t
(or indeed Unsigned_extended.Uint64.t
) in the body of the functor is the correct way to give ppx_deriving the correct paths. The code will already be doing this, so this should only really mean wrapping it in a functor to pass to Mk_amount
and friends.
Since Currency.Amount.t
is essentially a base type in the Mina hierarchy, it probably makes sense to start with a PR attempting that as an experiment.
I've settled on a design similar to yours and got no problems unifying abstract and concrete types during experiments on a proof of concept. I'm now working on a PR for Currency.Amount
Proof of concept for Currency.Amount
is validated and now merged: https://github.com/MinaProtocol/mina/pull/11256
Now working on applying the same design to the rest of the types
Full list (for compatible) of the types needed
?: children not visited yet %: already visited children $: repeat prefix above =: directly equal to parent
Leafs only depend on native (or external) types
As discussed with Matthew, I'm restricting the scope of this issue to all types up to those defined in Mina_transaction
. I'll open a new issue for the other ones.
Continuation of this issue for gossip types in https://github.com/MinaProtocol/mina/issues/11771
Currently, the types that we send over the network and between processes are scattered across the codebase, bundled together with code that isn't necessarily useful to consumers of the type. This causes a lot of inter-dependence between libraries, and a lot of code to be linked into smaller / single-purpose executables -- in particular, the Mina signer and SnarkyJS.
We also have poor visibility into the end-to-end structure of the messages sent over the protocol, where discovering the actual data requires a lot of manual searching.
To combat these issues, we can factor out the 'over-the-wire' types into a dedicated library (e.g.
Mina_wire_types
) that contains these types only. To keep this library as minimal as possible, it would be best to avoid adding derivers to these types too, since they can be added via aliases later. For example,mina_wire_types.ml
:transaction.ml
:We also have some private/opaque types scattered about the protocol, most notably those from
Currency
. For these, it might make sense to have some kind of 'revealing' functor, e.g.mina_wire_types.ml
:mina_wire_types.mli
:amount.ml
:Currency.Amount.t
: https://github.com/MinaProtocol/mina/pull/11256 & https://github.com/MinaProtocol/mina/pull/11326Mina_transaction