improve getStateField compile checks (#2889)
The current `getStateField` implementation fails at run-time when called on a post-Altair state. This is improved by replacing the `if` structure with a `case` expression, which is checked for exhaustive coverage at compile time. Care is taken to preserve the `unsafeAddr` optimization.
This commit is contained in:
parent
4491259c52
commit
c95d4f31ed
|
@ -122,11 +122,15 @@ func assign*(tgt: var ForkedHashedBeaconState, src: ForkedHashedBeaconState) =
|
||||||
# with nimOldCaseObjects. This is infrequent.
|
# with nimOldCaseObjects. This is infrequent.
|
||||||
tgt = src
|
tgt = src
|
||||||
|
|
||||||
macro getStateField*(s, y: untyped): untyped =
|
template getStateField*(x, y: untyped): untyped =
|
||||||
result = quote do:
|
# The use of `unsafeAddr` avoids excessive copying in certain situations, e.g.,
|
||||||
(if `s`.beaconStateFork == forkPhase0:
|
# ```
|
||||||
unsafeAddr (`s`.hbsPhase0.data.`y`) else:
|
# for index, validator in getStateField(stateData.data, validators).pairs():
|
||||||
unsafeAddr (`s`.hbsAltair.data.`y`))[]
|
# ```
|
||||||
|
# Without `unsafeAddr`, the `validators` list would be copied to a temporary variable.
|
||||||
|
(case x.beaconStateFork
|
||||||
|
of forkPhase0: unsafeAddr (x.hbsPhase0.data.y)
|
||||||
|
of forkAltair: unsafeAddr (x.hbsAltair.data.y))[]
|
||||||
|
|
||||||
template getStateRoot*(x: ForkedHashedBeaconState): Eth2Digest =
|
template getStateRoot*(x: ForkedHashedBeaconState): Eth2Digest =
|
||||||
case x.beaconStateFork:
|
case x.beaconStateFork:
|
||||||
|
|
Loading…
Reference in New Issue