Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,14 @@ if(LANTERN_BUILD_TESTS)
)
add_test(NAME lantern_client_pending COMMAND lantern_client_pending_test)

add_executable(lantern_client_gossip_test tests/unit/test_client_gossip.c)
target_link_libraries(lantern_client_gossip_test PRIVATE lantern)
add_test(NAME lantern_client_gossip COMMAND lantern_client_gossip_test)

add_executable(lantern_genesis_anchor_test tests/unit/test_genesis_anchor.c)
target_link_libraries(lantern_genesis_anchor_test PRIVATE lantern)
add_test(NAME lantern_genesis_anchor COMMAND lantern_genesis_anchor_test)

add_executable(lantern_genesis_bootstrap_test tests/unit/test_genesis_bootstrap.c)
target_link_libraries(lantern_genesis_bootstrap_test PRIVATE lantern)
target_compile_definitions(
Expand Down Expand Up @@ -335,6 +343,7 @@ if(LANTERN_BUILD_TESTS)
set(_lantern_ctest_targets
lantern_client_vote
lantern_client_pending
lantern_genesis_anchor
lantern_genesis_bootstrap
lantern_validator_selection
lantern_rlp
Expand Down
23 changes: 22 additions & 1 deletion include/lantern/core/client.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ struct lantern_client_options {
const char *validator_registry_path;
const char *nodes_path;
const char *genesis_state_path;
bool use_genesis_state;
const char *validator_config_path;
const char *node_id;
const char *node_key_hex;
Expand All @@ -83,13 +84,14 @@ struct lantern_client_options {
struct libp2p_subscription;
struct libp2p_protocol_server;
struct lantern_peer_status_entry;
struct lantern_active_blocks_request;
struct lantern_pending_block {
LanternSignedBlock block;
LanternRoot root;
LanternRoot parent_root;
char peer_text[128];
bool parent_requested;
uint32_t parent_request_failures;
uint64_t parent_requested_ms;
uint64_t received_ms;
uint32_t backfill_depth;
};
Expand All @@ -114,6 +116,14 @@ struct lantern_pending_block_list {
struct lantern_pending_parent_index parent_index;
};

struct lantern_active_blocks_request {
uint64_t request_id;
char peer_id[128];
uint64_t started_ms;
uint64_t deadline_ms;
bool timeout_recorded;
};

struct lantern_agg_proof_cache_entry {
LanternRoot data_root;
LanternAggregatedSignatureProof proof;
Expand Down Expand Up @@ -237,6 +247,10 @@ struct lantern_client {
struct lantern_peer_status_entry *peer_status_entries;
size_t peer_status_count;
size_t peer_status_capacity;
struct lantern_active_blocks_request *active_blocks_requests;
size_t active_blocks_request_count;
size_t active_blocks_request_capacity;
uint64_t next_blocks_request_id;
pthread_mutex_t status_lock;
bool status_lock_initialized;
bool debug_disable_block_requests;
Expand Down Expand Up @@ -314,6 +328,13 @@ int lantern_client_debug_record_vote(
const LanternSignedVote *vote,
const char *peer_id_text);

int lantern_client_debug_gossip_block(
struct lantern_client *client,
const LanternSignedBlock *block);
int lantern_client_debug_gossip_vote(
struct lantern_client *client,
const LanternSignedVote *vote);

int lantern_client_debug_import_block(
struct lantern_client *client,
const LanternSignedBlock *block,
Expand Down
62 changes: 21 additions & 41 deletions src/core/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,8 @@ void lantern_client_options_init(struct lantern_client_options *options)
options->genesis_config_path = LANTERN_DEFAULT_GENESIS_CONFIG;
options->validator_registry_path = LANTERN_DEFAULT_VALIDATOR_REGISTRY;
options->nodes_path = LANTERN_DEFAULT_NODES_FILE;
options->genesis_state_path = LANTERN_DEFAULT_GENESIS_STATE;
options->genesis_state_path = NULL;
options->use_genesis_state = false;
options->validator_config_path = LANTERN_DEFAULT_VALIDATOR_CONFIG;
options->node_id = LANTERN_DEFAULT_NODE_ID;
options->node_key_hex = NULL;
Expand Down Expand Up @@ -788,43 +789,11 @@ static bool client_try_genesis_from_pubkeys(struct lantern_client *client)
}


/**
* @brief Attempt genesis creation from an SSZ state snapshot.
*
* Decodes the serialized genesis state if provided in the configuration.
*
* @param client Client with loaded genesis artifacts
*
* @return true on success, false if snapshot is missing or decode fails
*
* @note Thread safety: Must run before concurrent access to the state.
*/
static bool client_try_genesis_from_ssz(struct lantern_client *client)
{
if (!client->genesis.state_bytes || client->genesis.state_size == 0)
{
return false;
}

if (lantern_ssz_decode_state(
&client->state,
client->genesis.state_bytes,
client->genesis.state_size)
!= 0)
{
return false;
}

client->genesis_fallback_used = false;
return true;
}


/**
* @brief Attempt genesis creation from the validator registry file.
*
* Builds the genesis state using pubkeys sourced from the registry when the
* explicit pubkey array or SSZ snapshot is unavailable.
* explicit pubkey array is unavailable.
*
* @param client Client with loaded genesis registry
*
Expand Down Expand Up @@ -1143,8 +1112,9 @@ static lantern_client_error client_finalize_genesis_state(struct lantern_client
/**
* @brief Build genesis state using the available artifact priority order.
*
* Tries embedded pubkeys first, then SSZ snapshot, and finally the validator
* registry. On success, finalizes validator vote structures.
* Tries embedded pubkeys first and then the validator registry. Lantern no
* longer decodes local genesis.ssz for bootstrap so replay/state roots remain
* deterministic from config/registry inputs.
*
* @param client Client being initialized
*
Expand All @@ -1160,11 +1130,6 @@ static lantern_client_error client_generate_state_from_genesis(struct lantern_cl
return client_finalize_genesis_state(client);
}

if (client_try_genesis_from_ssz(client))
{
return client_finalize_genesis_state(client);
}

if (client_try_genesis_from_registry(client))
{
return client_finalize_genesis_state(client);
Expand Down Expand Up @@ -1746,6 +1711,11 @@ static void shutdown_peer_tracking(struct lantern_client *client)
client->peer_status_entries = NULL;
client->peer_status_count = 0;
client->peer_status_capacity = 0;
free(client->active_blocks_requests);
client->active_blocks_requests = NULL;
client->active_blocks_request_count = 0;
client->active_blocks_request_capacity = 0;
client->next_blocks_request_id = 0;
pthread_mutex_unlock(&client->status_lock);
}
else
Expand All @@ -1754,6 +1724,11 @@ static void shutdown_peer_tracking(struct lantern_client *client)
client->peer_status_entries = NULL;
client->peer_status_count = 0;
client->peer_status_capacity = 0;
free(client->active_blocks_requests);
client->active_blocks_requests = NULL;
client->active_blocks_request_count = 0;
client->active_blocks_request_capacity = 0;
client->next_blocks_request_id = 0;
}
pthread_mutex_destroy(&client->status_lock);
client->status_lock_initialized = false;
Expand All @@ -1764,6 +1739,11 @@ static void shutdown_peer_tracking(struct lantern_client *client)
client->peer_status_entries = NULL;
client->peer_status_count = 0;
client->peer_status_capacity = 0;
free(client->active_blocks_requests);
client->active_blocks_requests = NULL;
client->active_blocks_request_count = 0;
client->active_blocks_request_capacity = 0;
client->next_blocks_request_id = 0;
}

if (client->peer_vote_lock_initialized)
Expand Down
22 changes: 22 additions & 0 deletions src/core/client_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,28 @@ int lantern_client_debug_record_vote(
return LANTERN_CLIENT_OK;
}

int lantern_client_debug_gossip_block(
struct lantern_client *client,
const LanternSignedBlock *block)
{
if (!client || !block)
{
return LANTERN_CLIENT_ERR_INVALID_PARAM;
}
return gossip_block_handler(block, NULL, client);
}

int lantern_client_debug_gossip_vote(
struct lantern_client *client,
const LanternSignedVote *vote)
{
if (!client || !vote)
{
return LANTERN_CLIENT_ERR_INVALID_PARAM;
}
return gossip_vote_handler(vote, NULL, client);
}


/**
* Debug API: Import a block for testing.
Expand Down
4 changes: 0 additions & 4 deletions src/core/client_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,6 @@ int copy_genesis_paths(
{
return -1;
}
if (set_owned_string(&paths->state_path, options->genesis_state_path) != 0)
{
return -1;
}
if (set_owned_string(&paths->validator_config_path, options->validator_config_path) != 0)
{
return -1;
Expand Down
5 changes: 2 additions & 3 deletions src/core/client_network_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ extern "C" {
#define LANTERN_PEER_DIAL_INTERVAL_SECONDS 5u

/** Maximum concurrent blocks requests per peer */
#define LANTERN_MAX_BLOCKS_REQUESTS_PER_PEER 2u
#define LANTERN_MAX_BLOCKS_REQUESTS_PER_PEER 1u

/** Peer dial timeout in milliseconds */
#define LANTERN_PEER_DIAL_TIMEOUT_MS 4000
Expand Down Expand Up @@ -85,10 +85,8 @@ struct lantern_peer_status_entry
LanternStatusMessage status; /**< Latest status message from peer */
bool has_status; /**< True if status has been received */
uint64_t last_status_ms; /**< Timestamp of last status message */
uint32_t blocks_requests_inflight; /**< Count of in-flight block requests */
bool status_request_inflight; /**< True if status request is pending */
bool reqresp_legacy_len; /**< True if peer uses legacy reqresp length framing */
uint64_t last_blocks_request_ms; /**< Timestamp of last blocks request */
uint32_t consecutive_blocks_failures; /**< Count of consecutive request failures */
uint32_t outstanding_status_requests; /**< Number of outstanding status requests */
uint32_t consecutive_ping_failures; /**< Count of consecutive ping failures */
Expand All @@ -102,6 +100,7 @@ struct lantern_peer_status_entry
struct block_request_ctx
{
struct lantern_client *client; /**< Client instance */
uint64_t request_id; /**< Internal request tracking ID */
peer_id_t peer_id; /**< Peer ID structure */
char peer_text[128]; /**< Peer ID as text */
LanternRoot *roots; /**< Roots being requested */
Expand Down
2 changes: 1 addition & 1 deletion src/core/client_pending.c
Original file line number Diff line number Diff line change
Expand Up @@ -774,7 +774,7 @@ struct lantern_pending_block *pending_block_list_append(
entry->parent_root = *parent_root;
entry->peer_text[0] = '\0';
entry->parent_requested = false;
entry->parent_request_failures = 0;
entry->parent_requested_ms = 0;
entry->received_ms = monotonic_millis();
entry->backfill_depth = backfill_depth;

Expand Down
Loading