diff --git a/external/c-libp2p b/external/c-libp2p index 94f4a76..4fc9241 160000 --- a/external/c-libp2p +++ b/external/c-libp2p @@ -1 +1 @@ -Subproject commit 94f4a766eddeff935944c8fc83fdbe3226de4cf3 +Subproject commit 4fc92412b47c3ca19144c57f78b172073ff2b361 diff --git a/src/consensus/slot_clock.c b/src/consensus/slot_clock.c index 3d800e1..cf98694 100644 --- a/src/consensus/slot_clock.c +++ b/src/consensus/slot_clock.c @@ -290,20 +290,3 @@ int lantern_slot_clock_compute( out_timepoint->phase = interval_to_phase(interval_index); return 0; } - -const char *lantern_duty_phase_name(enum lantern_duty_phase phase) { - switch (phase) { - case LANTERN_DUTY_PHASE_PROPOSAL: - return "proposal"; - case LANTERN_DUTY_PHASE_VOTE: - return "vote"; - case LANTERN_DUTY_PHASE_AGGREGATE: - return "aggregate"; - case LANTERN_DUTY_PHASE_SAFE_TARGET: - return "safe-target"; - case LANTERN_DUTY_PHASE_VOTE_ACCEPT: - return "vote-accept"; - default: - return "unknown"; - } -} diff --git a/src/consensus/store.c b/src/consensus/store.c index e79ba58..b00de4f 100644 --- a/src/consensus/store.c +++ b/src/consensus/store.c @@ -346,6 +346,30 @@ static void attestation_data_by_root_remove_index( cache->length -= 1u; } +static void attestation_data_by_root_shrink_to_fit( + struct lantern_attestation_data_by_root *cache) { + if (!cache) { + return; + } + if (cache->length == cache->capacity) { + return; + } + if (cache->length == 0u) { + free(cache->entries); + cache->entries = NULL; + cache->capacity = 0u; + return; + } + + struct lantern_attestation_data_by_root_entry *entries = + realloc(cache->entries, cache->length * sizeof(*entries)); + if (!entries) { + return; + } + cache->entries = entries; + cache->capacity = cache->length; +} + static int attestation_data_by_root_add( struct lantern_attestation_data_by_root *cache, const LanternRoot *data_root, @@ -760,6 +784,7 @@ size_t lantern_store_prune_finalized_attestation_material( } data_index += 1u; } + attestation_data_by_root_shrink_to_fit(data_cache); size_t signature_index = 0u; while (signature_index < store->gossip_signatures.length) { diff --git a/src/core/client_internal.h b/src/core/client_internal.h index c984e4c..d02b30e 100644 --- a/src/core/client_internal.h +++ b/src/core/client_internal.h @@ -393,25 +393,6 @@ bool lantern_client_lock_pending(struct lantern_client *client); */ void lantern_client_unlock_pending(struct lantern_client *client, bool locked); - -/* ============================================================================ - * Validator Record Functions - * ============================================================================ */ - -/** - * Get a validator record from the genesis registry. - * - * @param client Client instance - * @param global_index Validator global index - * @return Pointer to validator record, or NULL if not found - * - * @note Thread safety: This function is thread-safe (read-only access) - */ -const struct lantern_validator_record *lantern_client_get_validator_record( - const struct lantern_client *client, - uint64_t global_index); - - #ifdef __cplusplus } #endif diff --git a/src/core/client_services_internal.h b/src/core/client_services_internal.h index aa6571e..6853de8 100644 --- a/src/core/client_services_internal.h +++ b/src/core/client_services_internal.h @@ -61,24 +61,6 @@ extern "C" { void validator_duty_state_reset(struct lantern_validator_duty_state *state); -/** - * Compute wall-clock time for a vote slot. - * - * @spec subspecs/slot/slot_clock.py - slot timing - * - * @param client Client instance - * @param vote_slot Slot number - * @param out_seconds Output for computed time in seconds - * @return true on success, false on failure - * - * @note Thread safety: This function is thread-safe - */ -bool lantern_client_vote_time_seconds( - const struct lantern_client *client, - uint64_t vote_slot, - uint64_t *out_seconds); - - /** * Check if the validator service should run. * diff --git a/src/core/client_sync.c b/src/core/client_sync.c index 0e2fd99..93671dc 100644 --- a/src/core/client_sync.c +++ b/src/core/client_sync.c @@ -44,42 +44,6 @@ enum VALIDATOR_PUBKEY_HEX_BUFFER_LEN = (LANTERN_VALIDATOR_PUBKEY_SIZE * 2u) + 3u, }; - -/* ============================================================================ - * Validator Record Access - * ============================================================================ */ - -/** - * Get validator record from genesis registry. - * - * @spec subspecs/containers/validator.py - Validator container - * - * Retrieves a validator record from the genesis registry by index. - * The registry is populated during genesis initialization and remains - * immutable after that. - * - * @param client Client instance - * @param validator_id Validator index - * @return Validator record or NULL if not found - * - * @note Thread safety: Assumes registry is immutable after init - */ -const struct lantern_validator_record *lantern_client_get_validator_record( - const struct lantern_client *client, - uint64_t validator_id) -{ - if (!client || !client->genesis.validator_registry.records) - { - return NULL; - } - if (validator_id >= client->genesis.validator_registry.count) - { - return NULL; - } - return &client->genesis.validator_registry.records[validator_id]; -} - - /* ============================================================================ * Enabled Validator Count * ============================================================================ */ diff --git a/src/core/client_sync_internal.h b/src/core/client_sync_internal.h index 1d762d2..54e7fb2 100644 --- a/src/core/client_sync_internal.h +++ b/src/core/client_sync_internal.h @@ -214,13 +214,6 @@ bool lantern_client_find_missing_state_root_locked( const LanternRoot *root, LanternRoot *out_missing_root); -/** - * Return the active attestation committee count for sync/validator cache logic. - * - * Respects debug overrides used by tests and falls back to the protocol default. - */ -size_t lantern_client_attestation_committee_count(const struct lantern_client *client); - /** * Determine whether this node should retain an attestation signature locally. * diff --git a/src/core/client_sync_votes.c b/src/core/client_sync_votes.c index c6c4d48..ebada63 100644 --- a/src/core/client_sync_votes.c +++ b/src/core/client_sync_votes.c @@ -272,14 +272,6 @@ static bool validate_vote_cache_state( return true; } -size_t lantern_client_attestation_committee_count(const struct lantern_client *client) -{ - if (client && client->debug_attestation_committee_count > 0) { - return client->debug_attestation_committee_count; - } - return DEFAULT_SYNC_ATTESTATION_COMMITTEE_COUNT; -} - bool lantern_client_should_cache_attestation_signature_locked( const struct lantern_client *client, const LanternVote *vote) diff --git a/src/core/client_validator.c b/src/core/client_validator.c index fe632f9..be32692 100644 --- a/src/core/client_validator.c +++ b/src/core/client_validator.c @@ -471,12 +471,12 @@ static int aggregation_group_append( { return -1; } + group->validator_ids = ids; LanternSignature *sigs = realloc(group->signatures, new_capacity * sizeof(*sigs)); if (!sigs) { return -1; } - group->validator_ids = ids; group->signatures = sigs; group->capacity = new_capacity; } @@ -1232,75 +1232,6 @@ void validator_duty_state_reset(struct lantern_validator_duty_state *state) memset(state, 0, sizeof(*state)); } - -/* ============================================================================ - * Vote Time Utilities - * ============================================================================ */ - -/** - * Compute wall-clock time for a vote slot. - * - * Calculates the Unix timestamp (in seconds) at which the given vote slot - * begins, based on genesis time and seconds per slot configuration. - * - * @param client Client instance (must have fork_choice initialized) - * @param vote_slot Slot number to compute time for - * @param out_seconds Output for computed time in seconds (Unix timestamp) - * - * @return true on success - * @return false if client is NULL, fork_choice not initialized, out_seconds - * is NULL, or computed time overflows uint64_t - * - * @note Thread safety: This function is thread-safe - */ -bool lantern_client_vote_time_seconds( - const struct lantern_client *client, - uint64_t vote_slot, - uint64_t *out_seconds) -{ - if (!client || !client->has_fork_choice || !out_seconds) - { - return false; - } - uint32_t seconds_per_slot = client->fork_choice.seconds_per_slot; - if (seconds_per_slot == 0) - { - seconds_per_slot = 1; - } - uint64_t slot_for_time = vote_slot; - if (slot_for_time != UINT64_MAX) - { - slot_for_time += 1u; - } - -#if defined(__SIZEOF_INT128__) - __uint128_t slot_offset = (__uint128_t)slot_for_time * (uint64_t)seconds_per_slot; - __uint128_t result = slot_offset + (__uint128_t)client->fork_choice.config.genesis_time; - if (result > UINT64_MAX) - { - return false; - } - *out_seconds = (uint64_t)result; -#else - /* Fallback for platforms without 128-bit integers */ - uint64_t genesis_time = client->fork_choice.config.genesis_time; - /* Check for overflow in multiplication */ - if (seconds_per_slot != 0 && slot_for_time > UINT64_MAX / seconds_per_slot) - { - return false; - } - uint64_t slot_offset = slot_for_time * (uint64_t)seconds_per_slot; - /* Check for overflow in addition */ - if (slot_offset > UINT64_MAX - genesis_time) - { - return false; - } - *out_seconds = slot_offset + genesis_time; -#endif - return true; -} - - /* ============================================================================ * Validator Service Checks * ============================================================================ */ diff --git a/src/networking/gossipsub_service.c b/src/networking/gossipsub_service.c index 20d114f..e654421 100644 --- a/src/networking/gossipsub_service.c +++ b/src/networking/gossipsub_service.c @@ -20,20 +20,13 @@ #include "protocol/gossipsub/gossipsub.h" #include "../../external/c-libp2p/src/protocol/gossipsub/proto/gen/gossipsub_rpc.pb.h" -#ifdef __cplusplus -extern "C" { -#endif libp2p_err_t libp2p_gossipsub_rpc_decode_frame( const uint8_t *frame, size_t frame_len, libp2p_gossipsub_RPC **out_rpc); -#ifdef __cplusplus -} -#endif #define LANTERN_GOSSIPSUB_TOPIC_CAP 128u #define LANTERN_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) -#define LANTERN_GOSSIPSUB_PROTOCOL "/meshsub/1.0.0" #define LANTERN_GOSSIPSUB_HEARTBEAT_INTERVAL_MS 700u #define LANTERN_GOSSIPSUB_FANOUT_TTL_MS 60000u #define LANTERN_GOSSIPSUB_MESH_D 8 @@ -46,10 +39,8 @@ libp2p_err_t libp2p_gossipsub_rpc_decode_frame( #define LANTERN_LEANSPEC_JUSTIFICATION_LOOKBACK 3u #define LANTERN_LEANSPEC_SEEN_TTL_FACTOR 2u -/* Accept both raw 1.0.0 and libp2p's stacked identifiers (prefix/1.1.0) */ static const char *const k_leanspec_gossipsub_protocols[] = { "/meshsub/1.1.0", - "/meshsub/1.0.0/1.1.0", "/meshsub/1.0.0", }; diff --git a/src/support/log.c b/src/support/log.c index e55624e..41f7470 100644 --- a/src/support/log.c +++ b/src/support/log.c @@ -6,15 +6,6 @@ #include #include #include -#if defined(_WIN32) -#include -#define lantern_isatty _isatty -#define lantern_fileno _fileno -#else -#include -#define lantern_isatty isatty -#define lantern_fileno fileno -#endif static char g_node_id[96] = {0}; static enum LanternLogLevel g_min_level = LANTERN_LOG_LEVEL_INFO; @@ -34,22 +25,12 @@ static enum lantern_log_color_mode g_color_mode = LANTERN_LOG_COLOR_AUTO; /* ANSI color codes */ #define ANSI_RESET "\x1b[0m" -#define ANSI_BOLD "\x1b[1m" #define ANSI_DIM "\x1b[2m" -#define ANSI_BLACK "\x1b[30m" -#define ANSI_RED "\x1b[31m" #define ANSI_GREEN "\x1b[32m" #define ANSI_YELLOW "\x1b[33m" -#define ANSI_BLUE "\x1b[34m" -#define ANSI_MAGENTA "\x1b[35m" #define ANSI_CYAN "\x1b[36m" -#define ANSI_WHITE "\x1b[37m" #define ANSI_BRIGHT_BLACK "\x1b[90m" #define ANSI_BRIGHT_RED "\x1b[91m" -#define ANSI_BRIGHT_GREEN "\x1b[92m" -#define ANSI_BRIGHT_YELLOW "\x1b[93m" -#define ANSI_BRIGHT_BLUE "\x1b[94m" -#define ANSI_BRIGHT_CYAN "\x1b[96m" /* Level badge colors and symbols */ static const char *level_to_color(enum LanternLogLevel level) { diff --git a/tests/integration/consensus_fixture_runner.c b/tests/integration/consensus_fixture_runner.c index d96ab7e..425538e 100644 --- a/tests/integration/consensus_fixture_runner.c +++ b/tests/integration/consensus_fixture_runner.c @@ -21,10 +21,6 @@ #include -#ifndef LANTERN_TEST_FIXTURE_DIR -#error "LANTERN_TEST_FIXTURE_DIR must be defined" -#endif - #define LABEL_MAX_LENGTH 64 #define MAX_LABELS 128 diff --git a/tests/integration/test_validator_duties.c b/tests/integration/test_validator_duties.c index 99a3978..ece3e1d 100644 --- a/tests/integration/test_validator_duties.c +++ b/tests/integration/test_validator_duties.c @@ -29,14 +29,6 @@ static int init_range_assignment( return 0; } -#define EXPECT_ZERO(expr, label) \ - do { \ - if ((expr) != 0) { \ - fprintf(stderr, "%s failed\n", label); \ - return 1; \ - } \ - } while (0) - #define EXPECT_EQ(actual, expected, label) \ do { \ if ((actual) != (expected)) { \ diff --git a/tests/integration/test_verify_signatures_vectors.c b/tests/integration/test_verify_signatures_vectors.c index 36158b0..3d580f8 100644 --- a/tests/integration/test_verify_signatures_vectors.c +++ b/tests/integration/test_verify_signatures_vectors.c @@ -16,10 +16,6 @@ #include "lantern/consensus/state.h" #include "lantern/support/log.h" -#ifndef LANTERN_TEST_FIXTURE_DIR -#error "LANTERN_TEST_FIXTURE_DIR must be defined" -#endif - static void configure_logging(void) { const char *env_level = getenv("LANTERN_LOG_LEVEL"); if (env_level && env_level[0] != '\0') { diff --git a/tests/support/fixture_loader.c b/tests/support/fixture_loader.c index eeff29e..71800b5 100644 --- a/tests/support/fixture_loader.c +++ b/tests/support/fixture_loader.c @@ -767,30 +767,6 @@ static int lantern_fixture_parse_aggregated_attestation( return 0; } -static int lantern_fixture_wrap_vote_as_aggregated( - const LanternSignedVote *vote, - LanternAggregatedAttestation *out_attestation) { - if (!vote || !out_attestation) { - return -1; - } - uint64_t validator_id = vote->data.validator_id; - if (validator_id >= LANTERN_VALIDATOR_REGISTRY_LIMIT) { - return -1; - } - if (lantern_bitlist_resize(&out_attestation->aggregation_bits, (size_t)validator_id + 1u) != 0) { - return -1; - } - size_t byte_len = ((size_t)validator_id + 1u + 7u) / 8u; - if (byte_len > 0 && out_attestation->aggregation_bits.bytes) { - memset(out_attestation->aggregation_bits.bytes, 0, byte_len); - size_t byte_index = (size_t)validator_id / 8u; - size_t bit_index = (size_t)validator_id % 8u; - out_attestation->aggregation_bits.bytes[byte_index] |= (uint8_t)(1u << bit_index); - } - out_attestation->data = vote->data.data; - return 0; -} - static int lantern_fixture_parse_signature_proof( const struct lantern_fixture_document *doc, int proof_idx, diff --git a/tests/unit/client_test_helpers.c b/tests/unit/client_test_helpers.c index eecb278..1ddbb34 100644 --- a/tests/unit/client_test_helpers.c +++ b/tests/unit/client_test_helpers.c @@ -15,10 +15,6 @@ #include "lantern/crypto/xmss.h" #include "lantern/support/time.h" -#ifndef LANTERN_TEST_FIXTURE_DIR -#error "LANTERN_TEST_FIXTURE_DIR must be defined for client test helpers" -#endif - static int client_test_load_fixture_genesis_time(uint64_t *out_time); static int load_precomputed_keys( @@ -91,23 +87,6 @@ int client_test_slot_for_root(struct lantern_client *client, const LanternRoot * return 0; } -int client_test_advance_fork_choice_intervals(LanternForkChoice *store, size_t count, bool has_proposal) { - if (!store || store->milliseconds_per_interval == 0) { - return -1; - } - for (size_t i = 0; i < count; ++i) { - uint64_t next_interval = store->time_intervals + 1u; - uint64_t now = (store->config.genesis_time * 1000u) + (next_interval * store->milliseconds_per_interval); - if (now < (store->config.genesis_time * 1000u)) { - return -1; - } - if (lantern_fork_choice_advance_time(store, now, has_proposal) != 0) { - return -1; - } - } - return 0; -} - bool client_test_pending_contains_root(const struct lantern_client *client, const LanternRoot *root) { if (!client || !root) { return false; diff --git a/tests/unit/client_test_helpers.h b/tests/unit/client_test_helpers.h index 54bfdde..fbaf576 100644 --- a/tests/unit/client_test_helpers.h +++ b/tests/unit/client_test_helpers.h @@ -14,7 +14,6 @@ void client_test_fill_root(LanternRoot *root, uint8_t seed); void client_test_fill_root_with_index(LanternRoot *root, uint32_t index); int client_test_slot_for_root(struct lantern_client *client, const LanternRoot *root, uint64_t *out_slot); -int client_test_advance_fork_choice_intervals(LanternForkChoice *store, size_t count, bool has_proposal); bool client_test_pending_contains_root(const struct lantern_client *client, const LanternRoot *root); int client_test_setup_vote_validation_client( diff --git a/tests/unit/test_genesis_bootstrap.c b/tests/unit/test_genesis_bootstrap.c index 0d7ab7e..5412750 100644 --- a/tests/unit/test_genesis_bootstrap.c +++ b/tests/unit/test_genesis_bootstrap.c @@ -7,10 +7,6 @@ #include "lantern/genesis/genesis.h" -#ifndef LANTERN_TEST_FIXTURE_DIR -#error "LANTERN_TEST_FIXTURE_DIR must be defined" -#endif - static int write_temp_nodes_file(char *buffer, size_t length) { if (!buffer || length == 0) { return -1; diff --git a/tests/unit/test_gossip_block_dump_decode.c b/tests/unit/test_gossip_block_dump_decode.c index 3c9c297..46b1a4e 100644 --- a/tests/unit/test_gossip_block_dump_decode.c +++ b/tests/unit/test_gossip_block_dump_decode.c @@ -12,10 +12,6 @@ #include "lantern/encoding/snappy.h" #include "lantern/networking/gossip_payloads.h" -#ifndef LANTERN_PROJECT_SOURCE_DIR -#define LANTERN_PROJECT_SOURCE_DIR "." -#endif - static const char *k_default_glob = LANTERN_PROJECT_SOURCE_DIR "/internal-docs/pending-issues/devnet-3-issue-3/*.ssz"; diff --git a/tests/unit/test_networking_messages.c b/tests/unit/test_networking_messages.c index c62d87d..2cb2fd2 100644 --- a/tests/unit/test_networking_messages.c +++ b/tests/unit/test_networking_messages.c @@ -21,10 +21,6 @@ #include "tests/support/fixture_loader.h" #include "ssz_constants.h" -#ifndef LANTERN_TEST_FIXTURE_DIR -#error "LANTERN_TEST_FIXTURE_DIR must be defined" -#endif - #define CHECK(cond) \ do { \ if (!(cond)) { \ @@ -217,15 +213,6 @@ static void check_signature_proof_equal( CHECK(memcmp(expected->proof_data.data, actual->proof_data.data, expected->proof_data.length) == 0); } -static void check_signed_aggregated_attestation_equal( - const LanternSignedAggregatedAttestation *expected, - const LanternSignedAggregatedAttestation *actual) { - CHECK(expected != NULL); - CHECK(actual != NULL); - check_attestation_data_equal(&expected->data, &actual->data); - check_signature_proof_equal(&expected->proof, &actual->proof); -} - static void expect_vote_view( const LanternVote *vote, uint64_t validator_id, @@ -391,20 +378,6 @@ static void expect_signed_block_fixture(const LanternSignedBlock *block) { expect_signature_proof_seed(&block->signatures.attestation_signatures.data[1], 10, 0xC7, 8); } -static uint64_t le_bytes_to_u64(const uint8_t *src, size_t len) { - if (!src) { - return 0; - } - if (len > sizeof(uint64_t)) { - len = sizeof(uint64_t); - } - uint64_t value = 0; - for (size_t i = 0; i < len; ++i) { - value |= ((uint64_t)src[i]) << (8u * i); - } - return value; -} - static uint32_t rng_state = UINT32_C(0x6ac1e39d); static uint32_t rng_next(void) { @@ -637,32 +610,6 @@ static int load_signed_block_fixture(const struct block_fixture_case *spec, Lant return status; } -static int parse_hex_bytes(const char *hex, uint8_t *out, size_t expected_len) { - if (!hex || !out) { - return -1; - } - if (hex[0] == '0' && (hex[1] == 'x' || hex[1] == 'X')) { - hex += 2; - } - size_t hex_len = strlen(hex); - if (hex_len != expected_len * 2u) { - return -1; - } - for (size_t i = 0; i < expected_len; ++i) { - char buf[3]; - buf[0] = hex[(i * 2u)]; - buf[1] = hex[(i * 2u) + 1u]; - buf[2] = '\0'; - char *end = NULL; - unsigned long value = strtoul(buf, &end, 16); - if (!end || *end != '\0') { - return -1; - } - out[i] = (uint8_t)value; - } - return 0; -} - static void normalize_attestation_data_for_gossip_sanity(LanternAttestationData *data) { if (!data) { return; diff --git a/tests/unit/test_state.c b/tests/unit/test_state.c index 2979b77..9639206 100644 --- a/tests/unit/test_state.c +++ b/tests/unit/test_state.c @@ -22,20 +22,6 @@ static void expect_zero(int rc, const char *label) { } } -static void expect_nonzero_root(const LanternRoot *root, const char *label) { - bool all_zero = true; - for (size_t i = 0; i < LANTERN_ROOT_SIZE; ++i) { - if (root->bytes[i] != 0) { - all_zero = false; - break; - } - } - if (all_zero) { - fprintf(stderr, "%s still zero\n", label); - exit(EXIT_FAILURE); - } -} - static void fill_root(LanternRoot *root, uint8_t value) { if (!root) { return; diff --git a/tests/unit/test_validator_selection.c b/tests/unit/test_validator_selection.c index 037877a..e5633c3 100644 --- a/tests/unit/test_validator_selection.c +++ b/tests/unit/test_validator_selection.c @@ -6,10 +6,6 @@ #include "lantern/genesis/genesis.h" -#ifndef LANTERN_TEST_FIXTURE_DIR -#error "LANTERN_TEST_FIXTURE_DIR must be defined" -#endif - static void build_fixture_path(char *buffer, size_t length, const char *relative) { if (!buffer || length == 0 || !relative) { return; diff --git a/tools/fixtures/generate_networking_ssz.py b/tools/fixtures/generate_networking_ssz.py index f1283ed..7909317 100755 --- a/tools/fixtures/generate_networking_ssz.py +++ b/tools/fixtures/generate_networking_ssz.py @@ -294,7 +294,7 @@ def main() -> None: vote_attestation = make_gossip_attestation(seed=0x33, validator_id=9, vote_slot=96) vote_fixture = SignedAttestation( validator_id=vote_attestation.validator_id, - message=vote_attestation.data, + data=vote_attestation.data, signature=make_signature(0xE1), ) vote_bytes = vote_fixture.encode_bytes() @@ -304,7 +304,7 @@ def main() -> None: "Gossip signed vote", [ f"validator={int(vote_fixture.validator_id)}", - f"slot={int(vote_fixture.message.slot)}", + f"slot={int(vote_fixture.data.slot)}", f"bytes={len(vote_bytes)}", ], ) diff --git a/tools/leanSpec b/tools/leanSpec index 8b7636b..be85318 160000 --- a/tools/leanSpec +++ b/tools/leanSpec @@ -1 +1 @@ -Subproject commit 8b7636bb8a95fe4bec414cc4c24e74079e6256b6 +Subproject commit be853180d21aa36d6401b8c1541aa6fcaad5008d