Skip to content

Commit

Permalink
Moved sync_status to Libp2p and made sync blocks depend on the store
Browse files Browse the repository at this point in the history
  • Loading branch information
rodrigo-o committed Oct 16, 2024
1 parent 85aa3f6 commit 192ac92
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 47 deletions.
10 changes: 5 additions & 5 deletions assertoor-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ participants:
count: 1
cl_max_mem: 4096
keymanager_enabled: true
additional_services:
- assertoor
assertoor_params:
run_stability_check: true
run_block_proposal_check: false
# additional_services:
# - assertoor
# assertoor_params:
# run_stability_check: true
# run_block_proposal_check: false
16 changes: 8 additions & 8 deletions lib/beacon_api/controllers/v1/node_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ defmodule BeaconApi.V1.NodeController do

alias BeaconApi.ApiSpec
alias BeaconApi.Utils
alias LambdaEthereumConsensus.Beacon.SyncBlocks
alias LambdaEthereumConsensus.Libp2pPort
alias LambdaEthereumConsensus.P2P.Metadata

Expand All @@ -27,9 +26,10 @@ defmodule BeaconApi.V1.NodeController do
do: ApiSpec.spec().paths["/eth/v1/node/peers"].get

@spec health(Plug.Conn.t(), any) :: Plug.Conn.t()
def health(conn, _params) do
%{is_syncing: syncing?} = SyncBlocks.status()
syncing_status = if syncing?, do: 206, else: 200
def health(conn, params) do
%{syncing?: syncing?} = Libp2pPort.sync_status()

syncing_status = if syncing?, do: Map.get(params, :syncing_status, 206), else: 200

send_resp(conn, syncing_status, "")
rescue
Expand Down Expand Up @@ -75,12 +75,12 @@ defmodule BeaconApi.V1.NodeController do
@spec syncing(Plug.Conn.t(), any) :: Plug.Conn.t()
def syncing(conn, _params) do
%{
is_syncing: is_syncing,
is_optimistic: is_optimistic,
el_offline: el_offline,
syncing?: is_syncing,
optimistic?: is_optimistic,
el_offline?: el_offline,
head_slot: head_slot,
sync_distance: sync_distance
} = SyncBlocks.status()
} = Libp2pPort.sync_status()

json(conn, %{
"data" => %{
Expand Down
29 changes: 3 additions & 26 deletions lib/lambda_ethereum_consensus/beacon/sync_blocks.ex
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@ defmodule LambdaEthereumConsensus.Beacon.SyncBlocks do
finish, each block of those responses will be sent to libp2p port module individually using
Libp2pPort.add_block/1.
"""
@spec run() :: non_neg_integer()
def run() do
%{head_slot: head_slot} = ForkChoice.get_current_status_message()
@spec run(Types.Store.t()) :: non_neg_integer()
def run(%{head_slot: head_slot} = store) do
initial_slot = head_slot + 1
last_slot = ForkChoice.get_current_chain_slot()
last_slot = ForkChoice.get_current_slot(store)

# If we're around genesis, we consider ourselves synced
if last_slot <= 0 do
Expand Down Expand Up @@ -69,26 +68,4 @@ defmodule LambdaEthereumConsensus.Beacon.SyncBlocks do
Libp2pPort.notify_block_download_failed(range, reason)
{:ok, store}
end

@doc """
Returns the current syncing status.
TODO: (#1325) This is a semi-stub. This is not the final implementation,
just in place for start using assertoor. Probably need to be moved to Libp2pPort.
"""
def status() do
{:ok, %{head_slot: head_slot}} = StoreDb.fetch_store()
initial_slot = head_slot + 1
last_slot = ForkChoice.get_current_chain_slot()
distance = last_slot - initial_slot + 1
syncing? = distance > 0

%{
is_syncing: syncing?,
is_optimistic: syncing?,
el_offline: false,
head_slot: head_slot,
sync_distance: distance
}
end
end
3 changes: 1 addition & 2 deletions lib/lambda_ethereum_consensus/fork_choice/fork_choice.ex
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,7 @@ defmodule LambdaEthereumConsensus.ForkChoice do
@doc """
Get the current chain slot based on the system time.
There are just 2 uses of this function outside this module:
- At the begining of SyncBlocks.run/1 function, to get the head slot
There are just 1 use of this function outside this module:
- In the Helpers.block_root_by_block_id/1 function
"""
@spec get_current_chain_slot() :: Types.slot()
Expand Down
37 changes: 35 additions & 2 deletions lib/libp2p_port.ex
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,20 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
GenServer.cast(pid, {:error_downloading_chunk, range, reason})
end

@doc """
Returns the current sync status.
"""
@spec sync_status(pid | atom()) :: %{
syncing?: boolean(),
optimistic?: boolean(),
el_offline?: boolean(),
head_slot: Types.slot(),
sync_distance: non_neg_integer()
}
def sync_status(pid \\ __MODULE__) do
GenServer.call(pid, :sync_status)
end

########################
### GenServer Callbacks
########################
Expand Down Expand Up @@ -513,8 +527,8 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
end

@impl GenServer
def handle_info(:sync_blocks, state) do
blocks_to_download = SyncBlocks.run()
def handle_info(:sync_blocks, %{store: store} = state) do
blocks_to_download = SyncBlocks.run(store)

new_state =
state |> Map.put(:blocks_remaining, blocks_to_download) |> subscribe_if_no_blocks()
Expand Down Expand Up @@ -575,6 +589,25 @@ defmodule LambdaEthereumConsensus.Libp2pPort do
{:reply, :ok, %{state | validator_set: validator_set}}
end

@impl GenServer
def handle_call(:sync_status, _from, %{syncing: syncing?, store: store} = state) do
# TODO: (#1325) This is not the final implementation, we are lacking the el check,
# this is just in place for start using assertoor.
head_slot = store.head_slot
current_slot = ForkChoice.get_current_slot(store)
distance = current_slot - head_slot

result = %{
syncing?: syncing?,
optimistic?: syncing?,
el_offline?: false,
head_slot: store.head_slot,
sync_distance: distance
}

{:reply, result, state}
end

######################
### PRIVATE FUNCTIONS
######################
Expand Down
41 changes: 37 additions & 4 deletions test/unit/beacon_api/beacon_api_v1_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ defmodule Unit.BeaconApiTest.V1 do
alias BeaconApi.Router
alias BeaconApi.Utils
alias LambdaEthereumConsensus.ForkChoice
alias LambdaEthereumConsensus.Libp2pPort
alias LambdaEthereumConsensus.P2P.Metadata
alias LambdaEthereumConsensus.Store.BlockDb
alias LambdaEthereumConsensus.Store.Db
alias LambdaEthereumConsensus.Store.StoreDb
Expand Down Expand Up @@ -134,7 +136,7 @@ defmodule Unit.BeaconApiTest.V1 do
test "get genesis data" do
expected_response = %{
"data" => %{
"genesis_time" => StoreDb.fetch_genesis_time!(),
"genesis_time" => StoreDb.fetch_genesis_time!() |> Integer.to_string(),
"genesis_validators_root" =>
ChainSpec.get_genesis_validators_root() |> Utils.hex_encode(),
"genesis_fork_version" => ChainSpec.get("GENESIS_FORK_VERSION") |> Utils.hex_encode()
Expand All @@ -149,15 +151,46 @@ defmodule Unit.BeaconApiTest.V1 do
end

test "node health" do
now = :os.system_time(:second)
patch(Libp2pPort, :on_tick, fn _time, state -> state end)

start_link_supervised!(
{Libp2pPort,
genesis_time: now - 24, store: %Store{genesis_time: now - 24, time: now, head_slot: 1}}
)

conn = conn(:get, "/eth/v1/node/health", nil) |> Router.call(@opts)
assert conn.state == :sent
assert conn.status == 200
assert conn.status == 206
assert conn.resp_body == ""
end

test "node syncing" do
now = :os.system_time(:second)
patch(Libp2pPort, :on_tick, fn _time, state -> state end)

start_link_supervised!(
{Libp2pPort,
genesis_time: now - 24, store: %Store{genesis_time: now - 24, time: now, head_slot: 1}}
)

expected_response = %{
"data" => %{
"is_syncing" => true,
"is_optimistic" => true,
"el_offline" => false,
"head_slot" => "1",
"sync_distance" => "1"
}
}

conn = conn(:get, "/eth/v1/node/syncing", nil) |> Router.call(@opts)
assert conn.state == :sent
assert conn.status == 200
assert Jason.decode!(conn.resp_body) == expected_response
end

test "node identity" do
alias LambdaEthereumConsensus.Libp2pPort
alias LambdaEthereumConsensus.P2P.Metadata
patch(ForkChoice, :get_fork_version, fn -> ChainSpec.get("DENEB_FORK_VERSION") end)

start_link_supervised!({Libp2pPort, genesis_time: :os.system_time(:second), store: %Store{}})
Expand Down

0 comments on commit 192ac92

Please sign in to comment.