Skip to content

Commit 3da8c9e

Browse files
authored
feat: added randao utility module (#691)
1 parent cd52d83 commit 3da8c9e

File tree

6 files changed

+39
-23
lines changed

6 files changed

+39
-23
lines changed

lib/lambda_ethereum_consensus/state_transition/accessors.ex

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ defmodule LambdaEthereumConsensus.StateTransition.Accessors do
66
alias LambdaEthereumConsensus.SszEx
77
alias LambdaEthereumConsensus.StateTransition.{Cache, Math, Misc, Predicates}
88
alias LambdaEthereumConsensus.Utils
9+
alias LambdaEthereumConsensus.Utils.Randao
910
alias Types.{Attestation, BeaconState, IndexedAttestation, SyncCommittee, Validator}
1011

1112
@max_random_byte 2 ** 8 - 1
@@ -174,15 +175,6 @@ defmodule LambdaEthereumConsensus.StateTransition.Accessors do
174175
end
175176
end
176177

177-
@doc """
178-
Return the randao mix at a recent ``epoch``.
179-
"""
180-
@spec get_randao_mix(BeaconState.t(), Types.epoch()) :: Types.bytes32()
181-
def get_randao_mix(%BeaconState{randao_mixes: randao_mixes}, epoch) do
182-
epochs_per_historical_vector = ChainSpec.get("EPOCHS_PER_HISTORICAL_VECTOR")
183-
Enum.fetch!(randao_mixes, rem(epoch, epochs_per_historical_vector))
184-
end
185-
186178
@doc """
187179
Return the combined effective balance of the active validators.
188180
Note: ``get_total_balance`` returns ``EFFECTIVE_BALANCE_INCREMENT`` Gwei minimum to avoid divisions by zero.
@@ -437,7 +429,7 @@ defmodule LambdaEthereumConsensus.StateTransition.Accessors do
437429
epoch + ChainSpec.get("EPOCHS_PER_HISTORICAL_VECTOR") -
438430
ChainSpec.get("MIN_SEED_LOOKAHEAD") - 1
439431

440-
mix = get_randao_mix(state, future_epoch)
432+
mix = Randao.get_randao_mix(state.randao_mixes, future_epoch)
441433

442434
SszEx.hash(domain_type <> Misc.uint64_to_bytes(epoch) <> mix)
443435
end

lib/lambda_ethereum_consensus/state_transition/epoch_processing.ex

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ defmodule LambdaEthereumConsensus.StateTransition.EpochProcessing do
55

66
alias LambdaEthereumConsensus.StateTransition.{Accessors, Misc, Mutators, Predicates}
77
alias LambdaEthereumConsensus.Utils.BitVector
8+
alias LambdaEthereumConsensus.Utils.Randao
89
alias Types.{BeaconState, HistoricalSummary, Validator}
910

1011
@spec process_sync_committee_updates(BeaconState.t()) ::
@@ -91,10 +92,8 @@ defmodule LambdaEthereumConsensus.StateTransition.EpochProcessing do
9192
def process_randao_mixes_reset(%BeaconState{randao_mixes: randao_mixes} = state) do
9293
current_epoch = Accessors.get_current_epoch(state)
9394
next_epoch = current_epoch + 1
94-
epochs_per_historical_vector = ChainSpec.get("EPOCHS_PER_HISTORICAL_VECTOR")
95-
randao_mix = Accessors.get_randao_mix(state, current_epoch)
96-
index = rem(next_epoch, epochs_per_historical_vector)
97-
new_randao_mixes = List.replace_at(randao_mixes, index, randao_mix)
95+
randao_mix = Randao.get_randao_mix(randao_mixes, current_epoch)
96+
new_randao_mixes = Randao.replace_randao_mix(randao_mixes, next_epoch, randao_mix)
9897
new_state = %BeaconState{state | randao_mixes: new_randao_mixes}
9998
{:ok, new_state}
10099
end

lib/lambda_ethereum_consensus/state_transition/operations.ex

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ defmodule LambdaEthereumConsensus.StateTransition.Operations do
88
alias LambdaEthereumConsensus.Utils
99
alias LambdaEthereumConsensus.Utils.BitList
1010
alias LambdaEthereumConsensus.Utils.BitVector
11+
alias LambdaEthereumConsensus.Utils.Randao
1112

1213
alias Types.{
1314
Attestation,
@@ -228,7 +229,8 @@ defmodule LambdaEthereumConsensus.StateTransition.Operations do
228229
{:error, "Inconsistency in parent hash"}
229230

230231
# Verify prev_randao
231-
payload.prev_randao != Accessors.get_randao_mix(state, Accessors.get_current_epoch(state)) ->
232+
payload.prev_randao !=
233+
Randao.get_randao_mix(state.randao_mixes, Accessors.get_current_epoch(state)) ->
232234
{:error, "Prev_randao verification failed"}
233235

234236
# Verify timestamp
@@ -766,18 +768,13 @@ defmodule LambdaEthereumConsensus.StateTransition.Operations do
766768
signing_root = Misc.compute_signing_root(epoch, Types.Epoch, domain)
767769

768770
if Bls.valid?(proposer.pubkey, signing_root, randao_reveal) do
769-
randao_mix = Accessors.get_randao_mix(state, epoch)
771+
randao_mix = Randao.get_randao_mix(state.randao_mixes, epoch)
770772
hash = SszEx.hash(randao_reveal)
771773

772774
# Mix in RANDAO reveal
773775
mix = :crypto.exor(randao_mix, hash)
774776

775-
updated_randao_mixes =
776-
List.replace_at(
777-
state.randao_mixes,
778-
rem(epoch, ChainSpec.get("EPOCHS_PER_HISTORICAL_VECTOR")),
779-
mix
780-
)
777+
updated_randao_mixes = Randao.replace_randao_mix(state.randao_mixes, epoch, mix)
781778

782779
{:ok,
783780
%BeaconState{

lib/types/beacon_chain/beacon_state.ex

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ defmodule Types.BeaconState do
6767
balances: Aja.Vector.t(Types.gwei()),
6868
# Randomness
6969
# size EPOCHS_PER_HISTORICAL_VECTOR 65_536
70-
randao_mixes: list(Types.bytes32()),
70+
randao_mixes: Aja.Vector.t(Types.bytes32()),
7171
# Slashings
7272
# Per-epoch sums of slashed effective balances
7373
# size EPOCHS_PER_SLASHINGS_VECTOR 8192
@@ -110,6 +110,7 @@ defmodule Types.BeaconState do
110110
map
111111
|> Map.update!(:validators, &Aja.Vector.to_list/1)
112112
|> Map.update!(:balances, &Aja.Vector.to_list/1)
113+
|> Map.update!(:randao_mixes, &Aja.Vector.to_list/1)
113114
|> Map.update!(:previous_epoch_participation, &Aja.Vector.to_list/1)
114115
|> Map.update!(:current_epoch_participation, &Aja.Vector.to_list/1)
115116
|> Map.update!(:latest_execution_payload_header, &Types.ExecutionPayloadHeader.encode/1)
@@ -119,6 +120,7 @@ defmodule Types.BeaconState do
119120
map
120121
|> Map.update!(:validators, &Aja.Vector.new/1)
121122
|> Map.update!(:balances, &Aja.Vector.new/1)
123+
|> Map.update!(:randao_mixes, &Aja.Vector.new/1)
122124
|> Map.update!(:previous_epoch_participation, &Aja.Vector.new/1)
123125
|> Map.update!(:current_epoch_participation, &Aja.Vector.new/1)
124126
|> Map.update!(:latest_execution_payload_header, &Types.ExecutionPayloadHeader.decode/1)

lib/utils/randao.ex

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
defmodule LambdaEthereumConsensus.Utils.Randao do
2+
@moduledoc """
3+
This module provides utility functions for randao mixes
4+
"""
5+
6+
@spec get_randao_mix_index(Types.epoch()) :: Types.epoch()
7+
defp get_randao_mix_index(epoch), do: rem(epoch, ChainSpec.get("EPOCHS_PER_HISTORICAL_VECTOR"))
8+
9+
@doc """
10+
Replaces the randao mix with a new one at the given epoch.
11+
"""
12+
@spec replace_randao_mix(Aja.Vector.t(Types.bytes32()), Types.epoch(), Types.bytes32()) ::
13+
Aja.Vector.t(Types.bytes32())
14+
def replace_randao_mix(randao_mixes, epoch, randao_mix),
15+
do: Aja.Vector.replace_at!(randao_mixes, get_randao_mix_index(epoch), randao_mix)
16+
17+
@doc """
18+
Return the randao mix at a recent ``epoch``.
19+
"""
20+
@spec get_randao_mix(Aja.Vector.t(Types.bytes32()), Types.epoch()) :: Types.bytes32()
21+
def get_randao_mix(randao_mixes, epoch) do
22+
index = get_randao_mix_index(epoch)
23+
Aja.Vector.at!(randao_mixes, index)
24+
end
25+
end

test/spec/utils.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ defmodule SpecTestUtils do
88
@vector_keys [
99
"validators",
1010
"balances",
11+
"randao_mixes",
1112
"previous_epoch_participation",
1213
"current_epoch_participation"
1314
]

0 commit comments

Comments
 (0)