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
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ if(LANTERN_BUILD_TESTS)
target_link_libraries(lantern_rlp_test PRIVATE lantern)
add_test(NAME lantern_rlp COMMAND lantern_rlp_test)


add_executable(lantern_enr_test tests/unit/test_enr.c)
target_link_libraries(lantern_enr_test PRIVATE lantern)
add_test(NAME lantern_enr COMMAND lantern_enr_test)
Expand Down Expand Up @@ -225,6 +226,7 @@ if(LANTERN_BUILD_TESTS)
target_link_libraries(lantern_snappy_test PRIVATE lantern)
add_test(NAME lantern_snappy COMMAND lantern_snappy_test)


add_executable(lantern_networking_messages_test
tests/unit/test_networking_messages.c
tests/support/fixture_loader.c
Expand Down
5 changes: 5 additions & 0 deletions include/lantern/networking/reqresp_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@
#include <stdint.h>

#include "lantern/networking/messages.h"
#include "lantern/support/string_list.h"
#include "libp2p/stream.h"
#include "peer_id/peer_id.h"

#define LANTERN_REQRESP_STATUS_PROTOCOL_SNAPPY "/leanconsensus/req/status/1/ssz_snappy"
#define LANTERN_REQRESP_STATUS_PROTOCOL_LEGACY "/leanconsensus/req/status/1/"
#define LANTERN_REQRESP_BLOCKS_BY_ROOT_PROTOCOL_SNAPPY "/leanconsensus/req/lean_blocks_by_root/1/ssz_snappy"
#define LANTERN_REQRESP_BLOCKS_BY_ROOT_PROTOCOL_LEGACY "/leanconsensus/req/blocks_by_root/1/ssz_snappy"
#define LANTERN_REQRESP_BLOCKS_BY_ROOT_PROTOCOL_BARE "/leanconsensus/req/blocks_by_root/1/"
#define LANTERN_REQRESP_STATUS_PROTOCOL LANTERN_REQRESP_STATUS_PROTOCOL_SNAPPY
#define LANTERN_REQRESP_BLOCKS_BY_ROOT_PROTOCOL LANTERN_REQRESP_BLOCKS_BY_ROOT_PROTOCOL_SNAPPY
#define LANTERN_REQRESP_STATUS_PREVIEW_BYTES 256u
Expand Down Expand Up @@ -57,6 +59,7 @@ enum lantern_reqresp_protocol_kind {
#define LANTERN_STATUS_PROTOCOL_ID_LEGACY LANTERN_REQRESP_STATUS_PROTOCOL_LEGACY
#define LANTERN_BLOCKS_BY_ROOT_PROTOCOL_ID LANTERN_REQRESP_BLOCKS_BY_ROOT_PROTOCOL
#define LANTERN_BLOCKS_BY_ROOT_PROTOCOL_ID_LEGACY LANTERN_REQRESP_BLOCKS_BY_ROOT_PROTOCOL_LEGACY
#define LANTERN_BLOCKS_BY_ROOT_PROTOCOL_ID_BARE LANTERN_REQRESP_BLOCKS_BY_ROOT_PROTOCOL_BARE
#define LANTERN_STATUS_PREVIEW_BYTES LANTERN_REQRESP_STATUS_PREVIEW_BYTES

struct libp2p_host;
Expand Down Expand Up @@ -94,9 +97,11 @@ struct lantern_reqresp_service {
struct libp2p_protocol_server *status_server_legacy;
struct libp2p_protocol_server *blocks_server;
struct libp2p_protocol_server *blocks_server_legacy;
struct libp2p_protocol_server *blocks_server_bare;
struct libp2p_subscription *event_subscription;
int lock_initialized;
pthread_mutex_t lock;
struct lantern_string_list legacy_peers;
};

#ifdef __cplusplus
Expand Down
40 changes: 30 additions & 10 deletions scripts/fixtures/generate_networking_ssz.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,8 @@
from lean_spec.subspecs.containers import (
Attestation,
AttestationData,
Block,
BlockBody,
BlockWithAttestation,
Checkpoint,
)
from lean_spec.subspecs.containers.block.types import Attestations
from lean_spec.subspecs.containers.slot import Slot
from lean_spec.types import Bytes32, Uint64
from lean_spec.types.byte_arrays import BaseBytes
Expand All @@ -35,6 +31,7 @@
# The leanSpec XMSS Signature is now a variable-length SSZ container, so we define
# a custom fixed-size byte array type for fixture generation.
LANTERN_SIGNATURE_SIZE = 3112
LANTERN_MAX_ATTESTATIONS = 4096


class LanternSignature(BaseBytes):
Expand All @@ -57,10 +54,33 @@ class LanternSignedAttestation(Container):
signature: LanternSignature


class LanternAttestations(SSZList):
"""Lantern block body attestations (per-validator, not aggregated)."""

ELEMENT_TYPE = Attestation
LIMIT = LANTERN_MAX_ATTESTATIONS


class LanternBlockBody(Container):
"""Block body matching Lantern's per-validator attestation encoding."""

attestations: LanternAttestations


class LanternBlock(Container):
"""Block container matching Lantern's SSZ layout."""

slot: Slot
proposer_index: Uint64
parent_root: Bytes32
state_root: Bytes32
body: LanternBlockBody


class LanternBlockWithAttestation(Container):
"""Block with proposer attestation for Lantern fixture generation."""

block: Block
block: LanternBlock
proposer_attestation: Attestation


Expand Down Expand Up @@ -173,15 +193,15 @@ def make_signed_block(seed: int, base_slot: int, proposer_index: int, attestatio
make_attestation(seed + (i * 5), (proposer_index + i + seed) % 16, base_slot + i + 1)
for i in range(attestation_count)
]
block = Block(
block = LanternBlock(
slot=Slot(base_slot),
proposer_index=Uint64(proposer_index),
parent_root=Bytes32(repeating_bytes(seed, 32)),
state_root=Bytes32(repeating_bytes(seed + 0x50, 32)),
body=BlockBody(attestations=Attestations(data=attestations)),
body=LanternBlockBody(attestations=LanternAttestations(data=attestations)),
)
proposer_att = make_attestation(seed + 0x80, (proposer_index + 3) % 16, base_slot + attestation_count + 4)
signatures = make_signatures(seed + 0xA0, attestation_count + 1)
signatures = make_signatures(seed + 0xA0, len(attestations) + 1)
return LanternSignedBlockWithAttestation(
message=LanternBlockWithAttestation(block=block, proposer_attestation=proposer_att),
signature=signatures,
Expand All @@ -198,12 +218,12 @@ def make_gossip_signed_block(
make_gossip_attestation(seed + (i * 5), (proposer_index + i + seed) % 16, vote_slot)
for i, vote_slot in enumerate(attestation_vote_slots)
]
block = Block(
block = LanternBlock(
slot=Slot(block_slot),
proposer_index=Uint64(proposer_index),
parent_root=Bytes32(repeating_bytes(seed, 32)),
state_root=Bytes32(repeating_bytes(seed + 0x50, 32)),
body=BlockBody(attestations=Attestations(data=list(attestations))),
body=LanternBlockBody(attestations=LanternAttestations(data=list(attestations))),
)
proposer_att = make_gossip_attestation(seed + 0x80, (proposer_index + 3) % 16, block_slot + 2)
signatures = make_signatures(seed + 0xA0, len(attestations) + 1)
Expand Down
17 changes: 4 additions & 13 deletions src/core/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -1870,24 +1870,15 @@ static void shutdown_state_and_runtime(struct lantern_client *client)
*/
static lantern_client_error client_start_apis(struct lantern_client *client)
{
struct lantern_http_server_config http_config;
memset(&http_config, 0, sizeof(http_config));
http_config.port = client->http_port;
http_config.callbacks.context = client;
http_config.callbacks.snapshot_head = http_snapshot_head;
http_config.callbacks.validator_count = http_validator_count_cb;
http_config.callbacks.validator_info = http_validator_info_cb;
http_config.callbacks.set_validator_status = http_set_validator_status_cb;
if (lantern_http_server_start(&client->http_server, &http_config) != 0)
if (client->http_port != 0)
{
lantern_log_error(
lantern_log_warn(
"client",
&(const struct lantern_log_metadata){.validator = client->node_id},
"failed to start HTTP server on port %" PRIu16,
"HTTP API disabled; ignoring --http-port %" PRIu16,
client->http_port);
return LANTERN_CLIENT_ERR_NETWORK;
}
client->http_running = true;
client->http_running = false;

struct lantern_metrics_callbacks metrics_callbacks;
memset(&metrics_callbacks, 0, sizeof(metrics_callbacks));
Expand Down
6 changes: 4 additions & 2 deletions src/core/client_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ int lantern_client_debug_import_block(
block_root,
&(const struct lantern_log_metadata){
.validator = client->node_id,
.peer = peer_id_text})
.peer = peer_id_text},
true)
? 1
: 0;
}
Expand Down Expand Up @@ -141,7 +142,8 @@ int lantern_client_debug_enqueue_pending_block(
block,
block_root,
parent_root,
peer_id_text);
peer_id_text,
false);
return LANTERN_CLIENT_OK;
}

Expand Down
20 changes: 20 additions & 0 deletions src/core/client_network.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <inttypes.h>

#include <libp2p/errors.h>
#include <protocol/gossipsub/gossipsub.h>
Expand Down Expand Up @@ -249,6 +250,25 @@ void request_status_now(struct lantern_client *client, const peer_id_t *peer, co
{
return;
}
uint64_t genesis_time = client->genesis.chain_config.genesis_time;
if (genesis_time > 0)
{
uint64_t now = validator_wall_time_now_seconds();
if (now > 0 && now < genesis_time)
{
struct lantern_log_metadata meta = {
.validator = client->node_id,
.peer = (peer_text && peer_text[0]) ? peer_text : NULL,
};
lantern_log_trace(
"reqresp",
&meta,
"skipping status request before genesis now=%" PRIu64 " genesis_time=%" PRIu64,
now,
genesis_time);
return;
}
}
char peer_buffer[128];
peer_buffer[0] = '\0';
const char *status_peer = (peer_text && peer_text[0]) ? peer_text : NULL;
Expand Down
11 changes: 11 additions & 0 deletions src/core/client_network_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,16 @@ struct lantern_peer_status_entry
uint32_t outstanding_status_requests; /**< Number of outstanding status requests */
};

/**
* Blocks-by-root protocol variants for fallback handling.
*/
enum lantern_blocks_req_variant
{
LANTERN_BLOCKS_REQ_VARIANT_PRIMARY = 0,
LANTERN_BLOCKS_REQ_VARIANT_LEGACY_SNAPPY = 1,
LANTERN_BLOCKS_REQ_VARIANT_BARE = 2,
};


/**
* Block request context for async operations.
Expand All @@ -110,6 +120,7 @@ struct block_request_ctx
LanternRoot root; /**< Block root being requested */
const char *protocol_id; /**< Protocol ID string */
bool using_legacy; /**< True if using legacy protocol */
enum lantern_blocks_req_variant variant; /**< Protocol variant */
};


Expand Down
1 change: 1 addition & 0 deletions src/core/client_reqresp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1114,6 +1114,7 @@ void lantern_client_on_blocks_request_complete(

if (outcome == LANTERN_BLOCKS_REQUEST_SUCCESS && peer_id && peer_id[0] != '\0')
{
lantern_client_request_pending_parent_after_blocks(client, peer_id, request_root);
lantern_client_request_status_after_blocks_success(client, peer_id);
}
}
Loading