-
Notifications
You must be signed in to change notification settings - Fork 146
Avoid unnecessary clamp on previous_epoch
by genesis_epoch
#398
Avoid unnecessary clamp on previous_epoch
by genesis_epoch
#398
Conversation
84b6913
to
d8a230e
Compare
@@ -142,16 +140,25 @@ def get_winning_root( | |||
def get_epoch_boundary_attester_indices( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like @hwwhww and @ChihChengLiang were involved here -- would love your input on this...
don't exactly like getting the block root inside this function (mainly bc we then have to monkeypatch
it later to test it) but the way the spec is written we don't want to call this function unless there are some attestations in attestations
.
open to changing this bit if we can think of a nicer/cleaner way.... i'll update if i think of something i like better
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't want to call this function again and again for every attestations, either.
Maybe something like:
if len(attestations)>0:
root = helpers.get_block_root(...)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ChihChengLiang i don't follow -- given that we are iterating over attestations
then we only call helpers.get_block_root
if len(attestations)>0
so that condition would always be true....
i think what will be nicer is if I trace up the call stack here and just avoid calling this entirely -- it seems like there is only one place it is being called in the function that determines if the various epochs are even justifiable.
@hwwhww @ChihChengLiang this became more involved than the spec change would suggest (surprise!) but is ready for review -- i called attention to the part i'm not super excited about and would love to hear any thoughts! |
Ok, I took advantage of some fresh helpers from spec version I deleted the prior test for the function that no longer explicitly exists, with the understanding that it is only used by the function that gets the balances for the given boundary attestations which is already tested (if there is a bug in this covered function then it will fail the wrapping function's tests) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some suggestions of the type hintings, the rest of the refactorings/spec sync look good to me. 👍
slot, | ||
config.LATEST_BLOCK_ROOTS_LENGTH | ||
) | ||
] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we would try to avoid returning mutable List
.
state: 'BeaconState', | ||
config: 'BeaconConfig') -> Tuple[Gwei, Gwei]: | ||
|
||
config: 'BeaconConfig') -> Sequence[PendingAttestationRecord]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As https://github.com/ethereum/snake-charmers-tactical-manual/blob/master/style-guide.md#function-variance mentioned, we should narrow down the scope of return type:
- Normally, use
Sequence
for the input parameters. - If it returns known tuple, use
Tuple
for the return type. - If there's
@to_tuple
+yield
for output, useIterable
for the return type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good call -- as long as Tuple
is a subtype of Sequence
here then I'm happy w/ it :)
i don't know mypy
well enough to answer this question but I suspect the subtyping relation holds...
config.MAX_DEPOSIT_AMOUNT, | ||
def _get_previous_epoch_boundary_attestations( | ||
state: 'BeaconState', | ||
config: 'BeaconConfig') -> Sequence[PendingAttestationRecord]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
slot = get_epoch_start_slot(epoch, config.SLOTS_PER_EPOCH) | ||
return [ | ||
a for a in attestations | ||
if a.data.epoch_boundary_root == get_block_root( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can compute the epoch boundary root beforehand.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you are referring to the call to get_block_root
i started having the same thought but then i remembered why i was doing this in the first place.... and it was because we end up w/ a call to this function for essentially slots before the genesis epoch (where get_block_root
will explode)
we purposefully put the call inside the conditional so that it is lazily evaluated.... if this becomes a hotspot perf-wise then we can do something like
slot = # ....
if len(attestations) != 0:
block_root = get_block_root(...)
return tuple(
a for a in ... # rest of expression
)
or even just add some memoization to this function.... tbh i don't expect we will need to do this in this case :)
@hwwhww would love your thoughts on what I did here 03d3ddf to satisfy mypy... i feel like the |
03d3ddf
to
56c2f84
Compare
@ralexstokes (sorry for the late reply!) /cc @pipermerriam any other trade-off here? |
this got out of date -- i'll rebase and then merge this in |
Prior to this commit, block roots would be fetched for slots prior to the genesis and would fail
Uses some helper functions from the latest version of the spec The main thing we get is a Pythonic way to lazily compute block roots as eager computation was blowing up when finding the block roots before genesis in an earlier commit.
56c2f84
to
3931060
Compare
Closing in favor of #469. |
What was wrong?
Fixes #382.
How was it fixed?
Updated the calculation hanging off the
BeaconState
.Cute Animal Picture