Closed JustinDrake closed 5 years ago
Naming 1. Use the get_ prefix exclusively for functions that read state. (E.g. rename get_initial_beacon_state, get_domain, get_fork_version to something else.)
IMO the get_
prefix implies that “this function won’t mutate anything”. For the functions that are used for generating a new object, it can be named with a prefix create_
or generate_
.
It may make sense for me and/or @djrtwo to do the work when there are no open PRs to avoid merge conflict hell.
I’d support that we make it into several small PRs instead of a huge one. 😃
get_ancestor
It won’t be 100% complete since the object store
is only abstractly described as the data storage interface that design by the clients, which I think it’s fine, but we can add more notes on that.
Very in favor of this in general :)
I'm a little torn on removing the explicit params from the get_
functions and changing just to passing in state
. In practice, it is really nice when these pure functions specify the explicit subset of state required so that they can really easily be tested in isolation. That said, this is a spec so we need to find the balance. It might make sense to just pass in state but be more verbose in the header comment. Thinking.
I'd like to take a stab at [1] maybe right after we merge in #374 (reviewing now!)
What's helpful in general is minimizing order-dependence of the various parts of the spec - a concrete example of this would be what https://github.com/ethereum/eth2.0-specs/issues/348 points out - there's a dependency there on state.slot
that complicates processing, testing, etc. This is also the main advantage of passing in all relevant state explicitly - it declares these dependencies and makes them visible - but as long as the property itself is maintained, the difference is kind of cosmetic.
As far as implementation goes, the direction we're heading in is to do as much validation work as possible up front ("validate that there are at most X attestations") before making any state changes - this to minimize the cost of discarding faulty blocks (including costly state rewinds) - that's made harder if validation depends on partial state updates, because we then have to rewrite the validation code with as-if
logic that pulls us further from the spec text.
Generally looks good to me!
- Use the get_ prefix exclusively for functions that read state. (E.g. rename get_initial_beacon_state, get_domain, get_fork_version to something else.)
I think get
for pure functions that take things other than the state as input is fine too; the important thing is not using get
for impure functions.
- Replace pseudocode bulletpoints (e.g. in "Per-block processing") with functions. Both cleaner and more precise. For example add verify_proposer_signature, process_randao, ...
I think there's a balance here. The absolute extreme is that the spec is literally just a highly commented python implementation. It's probably worth thinking on a case-by-case basis, and also where we remove English text outside the python, add it back inside the python via comments.
Another thing is that whereas some functions as "utility" functions that are used throughout the spec, others are highly specialized to a specific task. Those functions should probably NOT go at the top of the spec; they should go inline in whatever the relevant section is. We shouldn't be requiring readers to constantly jump back and forth between different parts of the page as much as possible.
Closing for now as the focus is on content (e.g. fixing bugs) rather than presentation. A presentational overhaul will come in the "Transparent Paper" after the spec is finalised.
Anyone keen to do the cleanups feel free to reopen :)
Global organisation
hash
,hash_tree_root
,repeat_hash
,integer_squareroot
,shuffle
,split
,merkle_root
,verify_merkle_branch
, etc.state
:get_active_validator_indices
,get_shuffling
,get_shard_committees_at_slot
,get_block_root
,get_beacon_proposer_index
,get_attestation_participants
,get_effective_balance
, etc.state
:process_deposit
,process_ejections
,process_penalties_and_exits
,activate_validator
,initiate_validator_exit
,exit_validator
, etc.state: BeaconState
as the first argument.state
where possible to minimise the number of inputs. For exampleget_active_validator_indices
is currently givenvalidators: [ValidatorRecord], slot: int
when it suffices to passstate: BeaconState
.verify_proposer_signature
,process_randao
, ...get_ancestor
,repeat_hash
).process_deposit
has 8 inputs (state
,pubkey
,amount
,proof_of_possession
,withdrawal_credentials
,randao_commitment
,poc_commitment
) where the last 7 inputs can be replaced with a singleDepositData
object.Naming
get_
prefix exclusively for functions that readstate
. (E.g. renameget_initial_beacon_state
,get_domain
,get_fork_version
to something else.)validate_proof_of_possession
,verify_slashable_vote_data
should both use "validate" or "verify").prepare_validator_for_withdrawal
toinitiate_validator_withdrawal
for consistency withinitiate_validator_exit
.Local cleanups
@djrtwo, @hwwhww, @vbuterin Open to add/remove cleanup items from the above. It may make sense for me and/or @djrtwo to do the work when there are no open PRs to avoid merge conflict hell.