Skip to content

Commit

Permalink
Separated changes not related to the peerbook
Browse files Browse the repository at this point in the history
  • Loading branch information
rodrigo-o committed Oct 2, 2024
1 parent 0458c17 commit 4d4bc34
Show file tree
Hide file tree
Showing 9 changed files with 35 additions and 74 deletions.
13 changes: 1 addition & 12 deletions lib/lambda_ethereum_consensus/beacon/checkpoint_sync.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ defmodule LambdaEthereumConsensus.Beacon.CheckpointSync do
def get_finalized_block_and_state(url, genesis_validators_root) do
tasks = [Task.async(__MODULE__, :get_state, [url]), Task.async(__MODULE__, :get_block, [url])]

case Task.await_many(tasks, 600_000) do
case Task.await_many(tasks, 60_000) do
[{:ok, state}, {:ok, block}] ->
if state.genesis_validators_root == genesis_validators_root do
check_match(url, state, block)
Expand Down Expand Up @@ -47,33 +47,22 @@ defmodule LambdaEthereumConsensus.Beacon.CheckpointSync do
"""
@spec get_state(String.t()) :: {:ok, BeaconState.t()} | {:error, any()}
def get_state(url) do
start_time = System.monotonic_time()
with {:error, err} <-
get_ssz_from_url(url, "/eth/v2/debug/beacon/states/finalized", BeaconState) do
Logger.error("There has been an error retrieving the last finalized state")
{:error, err}
else
{:ok, state} ->
Logger.info("Retrieved the last finalized state in #{(System.monotonic_time() - start_time) / 1_000_000_000} s")
{:ok, state}
end

end

@doc """
Retrieves the last finalized block
"""
@spec get_block(String.t()) :: {:ok, SignedBeaconBlock.t()} | {:error, any()}
def get_block(url, id \\ "finalized") do
start_time = System.monotonic_time()
with {:error, err} <-
get_ssz_from_url(url, "/eth/v2/beacon/blocks/#{id}", SignedBeaconBlock) do
Logger.error("There has been an error retrieving the last finalized block")
{:error, err}
else
{:ok, block} ->
Logger.info("Retrieved the last finalized block in #{(System.monotonic_time() - start_time) / 1_000_000_000} s")
{:ok, block}
end
end

Expand Down
46 changes: 8 additions & 38 deletions lib/lambda_ethereum_consensus/fork_choice/fork_choice.ex
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ defmodule LambdaEthereumConsensus.ForkChoice do

store = Handlers.on_tick(store, time)

:telemetry.execute([:sync, :store], %{slot: get_current_slot(store)})
:telemetry.execute([:sync, :store], %{slot: Store.get_current_slot(store)})
:telemetry.execute([:sync, :on_block], %{slot: head_slot})

Metrics.block_status(head_root, head_slot, :transitioned)
Expand Down Expand Up @@ -111,37 +111,13 @@ defmodule LambdaEthereumConsensus.ForkChoice do
|> tap(&StoreDb.persist_store/1)
end

@spec get_current_slot(Types.Store.t()) :: Types.slot()
def get_current_slot(%Types.Store{} = store),
do: compute_current_slot(store.time, store.genesis_time)

@spec get_current_slot(Types.uint64(), Types.uint64()) :: Types.slot()
def get_current_slot(time, genesis_time),
do: compute_current_slot(time, genesis_time)

# TODO: Some parts of the code calculate the current slot using the previous function given a time
# specifically from the store (this was previously in the Store type module). This one calculates
# it using the system time, we might need to unify.
@spec get_current_chain_slot() :: Types.slot()
def get_current_chain_slot() do
time = :os.system_time(:second)
genesis_time = StoreDb.fetch_genesis_time!()
compute_current_slot(time, genesis_time)
end

@doc """
Check if a slot is in the future with respect to the current time.
"""
@spec future_slot?(Types.slot()) :: boolean()
def future_slot?(slot) do
time = :os.system_time(:second)
genesis_time = StoreDb.fetch_genesis_time!()

time
|> compute_currents_slots_within_disparity(genesis_time)
|> Enum.all?(fn possible_slot -> possible_slot < slot end)
end

@spec get_finalized_checkpoint() :: Types.Checkpoint.t()
def get_finalized_checkpoint() do
%{finalized_checkpoint: finalized} = fetch_store!()
Expand Down Expand Up @@ -197,7 +173,6 @@ defmodule LambdaEthereumConsensus.ForkChoice do
new_finalized_epoch = store.finalized_checkpoint.epoch

if last_finalized_epoch < new_finalized_epoch do

Logger.info("Pruning states before slot #{new_finalized_epoch}")

new_finalized_slot =
Expand All @@ -217,11 +192,9 @@ defmodule LambdaEthereumConsensus.ForkChoice do
PruneBlobsSupervisor,
fn -> BlobDb.prune_old_blobs(new_finalized_slot) end
)

Store.prune(store)
else
store
end

Store.prune(store)
end

def apply_handler(iter, state, handler) do
Expand Down Expand Up @@ -306,7 +279,11 @@ defmodule LambdaEthereumConsensus.ForkChoice do

Logger.debug("[Fork choice] Updated fork choice cache", slot: slot)

Store.update_head_info(store, slot, head_root)
%{
store
| head_root: head_root,
head_slot: slot
}
end

defp fetch_store!() do
Expand All @@ -317,13 +294,6 @@ defmodule LambdaEthereumConsensus.ForkChoice do
defp compute_current_slot(time, genesis_time),
do: div(time - genesis_time, ChainSpec.get("SECONDS_PER_SLOT"))

defp compute_currents_slots_within_disparity(time, genesis_time) do
[
compute_current_slot(time - ChainSpec.get("MAXIMUM_GOSSIP_CLOCK_DISPARITY"), genesis_time),
compute_current_slot(time + ChainSpec.get("MAXIMUM_GOSSIP_CLOCK_DISPARITY"), genesis_time)
]
end

defp compute_fork_digest(slot, genesis_validators_root) do
Misc.compute_epoch_at_slot(slot)
|> ChainSpec.get_fork_version_for_epoch()
Expand Down
18 changes: 8 additions & 10 deletions lib/lambda_ethereum_consensus/fork_choice/handlers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ defmodule LambdaEthereumConsensus.ForkChoice.Handlers do
"""
require Logger

alias LambdaEthereumConsensus.ForkChoice
alias LambdaEthereumConsensus.Execution.ExecutionClient
alias LambdaEthereumConsensus.StateTransition
alias LambdaEthereumConsensus.StateTransition.Accessors
Expand Down Expand Up @@ -39,7 +38,7 @@ defmodule LambdaEthereumConsensus.ForkChoice.Handlers do
# to ensure that every previous slot is processed with ``on_tick_per_slot``
seconds_per_slot = ChainSpec.get("SECONDS_PER_SLOT")
tick_slot = div(time - store.genesis_time, seconds_per_slot)
current_slot = ForkChoice.get_current_slot(store)
current_slot = Store.get_current_slot(store)
next_slot_start = (current_slot + 1) * seconds_per_slot
last_slot_start = tick_slot * seconds_per_slot

Expand Down Expand Up @@ -70,7 +69,7 @@ defmodule LambdaEthereumConsensus.ForkChoice.Handlers do

# Blocks cannot be in the future. If they are, their
# consideration must be delayed until they are in the past.
ForkChoice.future_slot?(block.slot) ->
Store.get_current_slot(store) < block.slot ->
# TODO: handle this error somehow
{:error, "block is from the future"}

Expand Down Expand Up @@ -236,8 +235,8 @@ defmodule LambdaEthereumConsensus.ForkChoice.Handlers do
)

is_first_block = new_store.proposer_boost_root == <<0::256>>
# TODO: store block timeliness data? we might need to take MAXIMUM_GOSSIP_CLOCK_DISPARITY into account
is_timely = ForkChoice.get_current_slot(new_store) == block.slot and is_before_attesting_interval
# TODO: store block timeliness data?
is_timely = Store.get_current_slot(new_store) == block.slot and is_before_attesting_interval

state = new_state_info.beacon_state

Expand Down Expand Up @@ -284,13 +283,12 @@ defmodule LambdaEthereumConsensus.ForkChoice.Handlers do
end

defp on_tick_per_slot(%Store{} = store, time) do
previous_slot = ForkChoice.get_current_slot(store)
previous_slot = Store.get_current_slot(store)

# Update store time
store = %Store{store | time: time}

# Why is this needed? the previous line shoud be immediate.
current_slot = ForkChoice.get_current_slot(store)
current_slot = Store.get_current_slot(store)

store
# If this is a new slot, reset store.proposer_boost_root
Expand Down Expand Up @@ -396,10 +394,10 @@ defmodule LambdaEthereumConsensus.ForkChoice.Handlers do
target.root != Store.get_checkpoint_block(store, block_root, target.epoch) ->
{:error, "mismatched head and target blocks"}

# Attestations can only affect the fork choice of subsequent slots (that's why the - 1).
# Attestations can only affect the fork choice of subsequent slots.
# Delay consideration in the fork choice until their slot is in the past.
# TODO: delay consideration
ForkChoice.future_slot?(attestation.data.slot - 1) ->
Store.get_current_slot(store) <= attestation.data.slot ->
{:error, "attestation is for a future slot"}

true ->
Expand Down
2 changes: 1 addition & 1 deletion lib/lambda_ethereum_consensus/fork_choice/head.ex
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ defmodule LambdaEthereumConsensus.ForkChoice.Head do
{true, Map.put(new_blocks, block_root, block)}

not Enum.empty?(children) ->
{false, blocks}
{false, new_blocks}

true ->
filter_leaf_block(store, block_root, block, blocks)
Expand Down
2 changes: 1 addition & 1 deletion lib/lambda_ethereum_consensus/fork_choice/simple_tree.ex
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ defmodule LambdaEthereumConsensus.ForkChoice.Simple.Tree do
def get_children!(tree, parent_id) do
case get_children(tree, parent_id) do
{:error, :not_found} -> raise "Parent #{Base.encode16(parent_id)} not found in tree"
{:ok, res} -> res |> IO.inspect(label: "Children of #{Base.encode16(parent_id)}")
{:ok, res} -> res
end
end

Expand Down
11 changes: 6 additions & 5 deletions lib/lambda_ethereum_consensus/p2p/gossip/beacon_block.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ defmodule LambdaEthereumConsensus.P2P.Gossip.BeaconBlock do

@impl true
def handle_gossip_message(store, _topic, msg_id, message) do
slot = ForkChoice.get_current_chain_slot()

with {:ok, uncompressed} <- :snappyer.decompress(message),
{:ok, signed_block} <- Ssz.from_ssz(uncompressed, SignedBeaconBlock),
:ok <- validate(signed_block) do
:ok <- validate(signed_block, slot) do
Logger.info("[Gossip] Block received, block.slot: #{signed_block.message.slot}.")
Libp2pPort.validate_message(msg_id, :accept)
PendingBlocks.add_block(store, signed_block)
Expand Down Expand Up @@ -61,9 +63,8 @@ defmodule LambdaEthereumConsensus.P2P.Gossip.BeaconBlock do
### Private functions
##########################

@spec validate(SignedBeaconBlock.t()) :: :ok | {:ignore, String.t()}
defp validate(%SignedBeaconBlock{message: block}) do
current_slot = ForkChoice.get_current_chain_slot()
@spec validate(SignedBeaconBlock.t(), Types.slot()) :: :ok | {:ignore, String.t()}
defp validate(%SignedBeaconBlock{message: block}, current_slot) do
min_slot = current_slot - ChainSpec.get("SLOTS_PER_EPOCH")

cond do
Expand All @@ -72,7 +73,7 @@ defmodule LambdaEthereumConsensus.P2P.Gossip.BeaconBlock do
{:ignore,
"Block too old: block.slot=#{block.slot}. Current slot: #{current_slot}. Minimum expected slot: #{min_slot}"}

ForkChoice.future_slot?(block.slot) ->
block.slot > current_slot ->
{:ignore,
"Block is from the future: block.slot=#{block.slot}. Current slot: #{current_slot}."}

Expand Down
1 change: 0 additions & 1 deletion lib/lambda_ethereum_consensus/store/state_db.ex
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ defmodule LambdaEthereumConsensus.Store.StateDb do

result =
BlockRootBySlot.fold_keys(slot, 0, fn slot, acc ->
Logger.info("[StateDb] Pruning state for slot #{slot}.")
case BlockRootBySlot.get(slot) do
{:ok, _block_root} ->
remove_state_by_slot(slot)
Expand Down
8 changes: 6 additions & 2 deletions lib/types/store.ex
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,13 @@ defmodule Types.Store do
end
end

# We probably want to move this to a more appropriate module
def get_current_slot(%__MODULE__{time: time, genesis_time: genesis_time}) do
# NOTE: this assumes GENESIS_SLOT == 0
div(time - genesis_time, ChainSpec.get("SECONDS_PER_SLOT"))
end

def get_current_epoch(store) do
store |> ForkChoice.get_current_slot() |> Misc.compute_epoch_at_slot()
store |> get_current_slot() |> Misc.compute_epoch_at_slot()
end

def get_ancestor(%__MODULE__{} = store, root, slot) do
Expand Down
8 changes: 4 additions & 4 deletions network_params.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ participants:
- el_type: geth
cl_type: lighthouse
count: 2
validator_count: 5
validator_count: 32
- el_type: geth
cl_type: lambda
cl_image: lambda_ethereum_consensus:latest
use_separate_vc: false
count: 1
validator_count: 54
validator_count: 32
cl_max_mem: 4096
keymanager_enabled: true
# network_params:
# preset: minimal
network_params:
preset: minimal

0 comments on commit 4d4bc34

Please sign in to comment.