Skip to content

Commit c95d4f3

Browse files
authored
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.
1 parent 4491259 commit c95d4f3

File tree

1 file changed

+9
-5
lines changed

1 file changed

+9
-5
lines changed

beacon_chain/spec/forks.nim

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,15 @@ func assign*(tgt: var ForkedHashedBeaconState, src: ForkedHashedBeaconState) =
122122
# with nimOldCaseObjects. This is infrequent.
123123
tgt = src
124124

125-
macro getStateField*(s, y: untyped): untyped =
126-
result = quote do:
127-
(if `s`.beaconStateFork == forkPhase0:
128-
unsafeAddr (`s`.hbsPhase0.data.`y`) else:
129-
unsafeAddr (`s`.hbsAltair.data.`y`))[]
125+
template getStateField*(x, y: untyped): untyped =
126+
# The use of `unsafeAddr` avoids excessive copying in certain situations, e.g.,
127+
# ```
128+
# for index, validator in getStateField(stateData.data, validators).pairs():
129+
# ```
130+
# Without `unsafeAddr`, the `validators` list would be copied to a temporary variable.
131+
(case x.beaconStateFork
132+
of forkPhase0: unsafeAddr (x.hbsPhase0.data.y)
133+
of forkAltair: unsafeAddr (x.hbsAltair.data.y))[]
130134

131135
template getStateRoot*(x: ForkedHashedBeaconState): Eth2Digest =
132136
case x.beaconStateFork:

0 commit comments

Comments
 (0)