10950 Commits

Author SHA1 Message Date
Phil Ngo
c630c55067 fix: update default dashboards to new infra hostnames (#8726)
**Motivation**

A recent internal infrastructure change includes renaming default host
instance on our dashboards.

**Description**

This PR allows our dashboards to easily default to the new
infrastructure host instance for display.
2026-01-07 14:56:14 -05:00
twoeths
86298a43e6 refactor: move reward apis to state-transition (#8719)
**Motivation**

- the reward apis tightly couple to state-transition functions like
`beforeProcessEpoch() processBlock() processAttestationAltair()` so it
needs to be moved there

**Description**

- move api type definitions to `types` package so that it can be used
everywhere
- move reward apis implementation to `state-transition` package

Closes #8690

---------

Co-authored-by: Tuyen Nguyen <twoeths@users.noreply.github.com>
2026-01-06 08:48:58 +07:00
Nico Flaig
075956b855 refactor: use map to lookup combined beacon committee selection for duty (#8710)
https://github.com/ChainSafe/lodestar/pull/8669#discussion_r2636951039
2025-12-31 10:11:31 -05:00
Nico Flaig
ae3f082e01 fix: prevent duplicate aggregates passing validation due to race condition (#8716)
**Motivation**


https://github.com/ChainSafe/lodestar/pull/8711#pullrequestreview-3612431091

**Description**

Prevent duplicate aggregates passing gossip validation due to race
condition by checking again if we've seen the aggregate before inserting
it into op pool. This is required since we run multiple async operations
in-between first check and inserting it into op pool.


<img width="942" height="301" alt="image"
src="https://github.com/user-attachments/assets/2701a92e-7733-4de3-bf4a-ac853fd5c0b7"
/>

`AlreadyKnown` disappears since we now filter those out properly during
gossip validation which is important since we don't wanna re-gossip
those aggregates.
2025-12-31 10:09:54 -05:00
twoeths
b6bba4cb8c fix: simplify getBlockSignatureSets api (#8720)
**Motivation**

- we use the whole CachedBeaconStateAllForks to get all block
signatures, turn out we only need the validator indices of the current
SyncCommittee

**Description**

given this `getConfig` api: 
```typescript
getDomain(domainSlot: Slot, domainType: DomainType, messageSlot?: Slot): Uint8Array
```

we currently pass `state.slot` as the 1st param. However it's the same
to `block.slot` in `state-transition` and the same epoch when we verify
blocks in batch in
[beacon-node](b255111a20/packages/beacon-node/src/chain/blocks/verifyBlock.ts (L62))

- so we can just use `block.slot` instead of passing the whole
CachedBeaconStateAllForks in `getBlockSignatureSets()` api
- still have to pass in `currentSyncCommitteeIndexed` instead

part of #8650

---------

Co-authored-by: Tuyen Nguyen <twoeths@users.noreply.github.com>
2025-12-31 10:08:51 -05:00
twoeths
b255111a20 refactor: pass validators pubkey-index map from cli (#8707)
**Motivation**

- we will not be able to access `pubkey2index` or `index2pubkey` once we
switch to a native state-transition so we need to be prepared for that

**Description**

- pass `pubkey2index`, `index2pubkey` from cli instead
- in the future, we should find a way to extract them given a
BeaconState so that we don't have to depend on any implementations of
BeaconStateView, see
https://github.com/ChainSafe/lodestar/issues/8706#issue-3741320691

Closes #8652

---------

Co-authored-by: Tuyen Nguyen <twoeths@users.noreply.github.com>
2025-12-22 13:16:12 +07:00
Nico Flaig
7e9e7caf38 chore: log aggregation selection errors to debug (#8709)
These errors aren't really critical and might be common right now
because we moved from per slot to per epoch in
https://github.com/ChainSafe/lodestar/pull/8669 and not all validator
clients doing the same will cause calls to time out if signature
threshold in DVT middleware is not reached.
2025-12-19 15:44:12 -05:00
Nico Flaig
39dac0f03d fix: avoid calling committee selection apis if there are no duties (#8708)
Since https://github.com/ChainSafe/lodestar/pull/8669 we might call the
committee selection apis even if we don't have any duties which is
unnecessary and charon doesn't like it.

```
lodestar-1  | Dec-19 16:16:47.001[]                error: Error on sync committee aggregation selection slot=13278082 - JSON is not an array
lodestar-1  | Error: JSON is not an array
lodestar-1  |     at value_fromJsonArray (file:///usr/app/node_modules/@chainsafe/ssz/src/type/arrayBasic.ts:162:11)
lodestar-1  |     at ListCompositeType.fromJson (file:///usr/app/node_modules/@chainsafe/ssz/src/type/array.ts:121:12)
lodestar-1  |     at ApiResponse.value (file:///usr/app/packages/api/src/utils/client/response.ts:115:51)
lodestar-1  |     at SyncCommitteeDutiesService.runDistributedAggregationSelectionTasks (file:///usr/app/packages/validator/src/services/syncCommitteeDuties.ts:385:36)
lodestar-1  |     at processTicksAndRejections (node:internal/process/task_queues:103:5)
```
2025-12-19 19:03:16 +01:00
Nico Flaig
493cc12d2f feat: update vc to submit beacon committee selections once per epoch (#8669)
**Motivation**

Closes https://github.com/ChainSafe/lodestar/issues/8606

**Description**

This updates our implementation to be compliant with latest spec
https://github.com/ethereum/beacon-APIs/pull/368.

For sync committee aggregation selection (unchanged)
-  we call `submitSyncCommitteeSelections` at the start of the slot
- the timeout is still based on `CONTRIBUTION_DUE_BPS` into the slot (8
seconds)
-  we call the endpoint for all duties of this slot
-  logic has been moved to duties service


For attestation aggregation selection
- we call `submitBeaconCommitteeSelections` at the start of the epoch
for current and next epoch (2 separate calls)
- the timeout uses default which is based on `SLOT_DURATION_MS` (12
seconds)
- we only call `prepareBeaconCommitteeSubnet` once the above call either
resolved or failed, this should be fine as it's not that time sensitive
(one epoch lookahead)
- if duties are reorged, we will call `submitBeaconCommitteeSelections`
with duties of affected epoch
- logic has been moved to duties service


Previous PR https://github.com/ChainSafe/lodestar/pull/5344
2025-12-19 16:43:28 +01:00
Nico Flaig
84b481ddb5 chore: restore code required to perform sync through bellatrix (#8700)
**Motivation**

As noted in
https://github.com/ChainSafe/lodestar/pull/8680#discussion_r2624026653
we cannot sync through bellatrix anymore. While I don't think it's a big
deal it's simple enough to keep that functionality as that code is
pretty isolated and won't get in our way during refactors and with gloas
won't be part of the block processing pipeline anymore due to
block/payload separation.


**Description**

Restore code required to perform sync through bellatrix
- re-added `isExecutionEnabled()` and `isMergeTransitionComplete()`
checks during block processing
- enabled some spec tests again that were previously skipped
- mostly copied original code removed in
[#8680](https://github.com/ChainSafe/lodestar/pull/8680) but cleaned up
some comments and simplified a bit
2025-12-18 18:00:34 -05:00
Chiemerie Ezechukwu
882891d89c chore: update bootnode ENR with correct IPV6 (#8705)
**Motivation**

<!-- Why does this PR exist? What are the goals of the pull request? -->

This PR is to fix https://github.com/eth-clients/mainnet/issues/13

Already created this as well
https://github.com/eth-clients/mainnet/pull/14

<!-- A clear and concise general description of the changes of this pull
request. -->

<!-- If applicable, add screenshots to help explain your solution -->

<!-- Link to issues: Resolves #111, Resolves #222 -->

Closes #issue_number

**AI Assistance Disclosure**

- [ ] External Contributors: I have read the [contributor
guidelines](https://github.com/ChainSafe/lodestar/blob/unstable/CONTRIBUTING.md#ai-assistance-notice)
and disclosed my usage of AI below.

<!-- Insert any AI assistance disclosure here -->
2025-12-18 17:59:39 -05:00
twoeths
c151a164f2 chore: use config from beacon chain (#8703)
**Motivation**

- as a preparation for lodestar-z integration, we should not access
config from any cached BeaconState

**Description**

- use chain.config instead

part of #8652

---------

Co-authored-by: Tuyen Nguyen <twoeths@users.noreply.github.com>
2025-12-18 09:25:53 +07:00
Nico Flaig
f4236afdba chore: delete unused eth1 data from existing databases (#8696)
Suggestion from
https://github.com/ChainSafe/lodestar/pull/8692#pullrequestreview-3580953573
2025-12-17 12:32:41 +01:00
Nico Flaig
2fe8de2346 chore: add lerna exec to fix build watch/ifchanged commands (#8704)
`yarn build:watch` and `yarn build:ifchanged` no longer work since
https://github.com/ChainSafe/lodestar/pull/8675 since `lerna exec`
requires to install a separate package `@lerna-lite/exec` to work
properly
2025-12-17 11:26:44 +00:00
Nico Flaig
aceb5b7416 chore: remove eth1 related code (#8692)
**Motivation**

All networks are post-electra now and transition period is completed,
which means due to [EIP-6110](https://eips.ethereum.org/EIPS/eip-6110)
we no longer need to process deposits via eth1 bridge as those are now
processed by the execution layer.

This code is effectively tech debt, no longer exercised and just gets in
the way when doing refactors.

**Description**

Removes all code related to eth1 bridge mechanism to include new
deposits

- removed all eth1 related code, we can no longer produce blocks with
deposits pre-electra (syncing blocks still works)
- building a genesis state from eth1 is no longer supported (only for
testing)
- removed various db repositories related to deposits/eth1 data
- removed various `lodestar_eth1_*` metrics and dashboard panels
- deprecated all `--eth1.*` flags (but kept for backward compatibility)
- moved shared utility functions from eth1 to execution engine module

Closes https://github.com/ChainSafe/lodestar/issues/7682
Closes https://github.com/ChainSafe/lodestar/issues/8654
2025-12-17 15:45:02 +07:00
dependabot[bot]
b37f2bd1bd chore(deps): bump systeminformation from 5.23.8 to 5.27.14 (#8701) 2025-12-17 00:16:03 +00:00
twoeths
d4a47659a5 feat: transfer pending gossipsub message msg data (#8689)
**Motivation**

- improve memory by transferirng gossipsub message data from network
thread to the main thread
- In snappy decompression in #8647 we had to do `Buffer.alloc()` instead
of `Buffer.allocUnsafe()`. We don't have to feel bad about that because
`Buffer.allocUnsafe()` does not work with this PR, and we don't waste
any memory.

**Description**

- use `transferList` param when posting messages from network thread to
the main thread

part of #8629

**Testing**
I've tested this on `feat2` for 3 days, the previous branch was #8671 so
it's basically the current stable, does not see significant improvement
but some good data for different nodes
- no change on 1k or `novc`
- on hoodi `sas` node we have better memory there on main thread with
same mesh peers, same memory on network thread

<img width="851" height="511" alt="Screenshot 2025-12-12 at 11 05 27"
src="https://github.com/user-attachments/assets/8d7b2c2f-8213-4f89-87e0-437d016bc24a"
/>

- on mainnnet `sas` node, we have better memory on network thread, a
little bit worse on the main thread
<img width="854" height="504" alt="Screenshot 2025-12-12 at 11 08 42"
src="https://github.com/user-attachments/assets/7e638149-2dbe-4c7e-849c-ef78f6ff4d6f"
/>

- but for this mainnet node, the most interesting metric is `forward msg
avg peers`, we're faster than majority of them

<img width="1378" height="379" alt="Screenshot 2025-12-12 at 11 11 00"
src="https://github.com/user-attachments/assets/3ba5eeaa-5a11-4cad-adfa-1e0f68a81f16"
/>

---------

Co-authored-by: Tuyen Nguyen <twoeths@users.noreply.github.com>
2025-12-16 08:47:13 -05:00
Phil Ngo
3bf4734ba9 chore: merge v1.38.0 stable back to unstable (#8694) 2025-12-15 11:08:40 -05:00
Phil Ngo
dbd947813d chore: v1.38.0 release (#8687) v1.38.0 2025-12-15 10:31:50 -05:00
twoeths
ebc352f211 chore: use pubkey2index from BeaconChain (#8691)
**Motivation**

- as a preparation for lodestar-z integration, we should not access
pubkey2index from CachedBeaconState

**Description**

- use that from BeaconChain instead

part of #8652

Co-authored-by: Tuyen Nguyen <twoeths@users.noreply.github.com>
2025-12-12 11:29:41 -05:00
Nico Flaig
889b1c4475 chore: remove merge transition code (#8680)
**Motiviation**

All networks have completed the merge transition and most execution
clients no longer support pre-merge so it's not even possible anymore to
run a network from a genesis before bellatrix, unless you keep it to
phase0/altair only, which still works after this PR is merged.

This code is effectively tech debt, no longer exercised and just gets in
the way when doing refactors.

**Description**

Removes all code related to performing the merge transition. Running the
node pre-merge (CL only mode) is still possible and syncing still works.
Also removed a few CLI flags we added for the merge specifically, those
shouldn't be used anymore. Spec constants like
`TERMINAL_TOTAL_DIFFICULTY` are kept for spec compliance and ssz types
(like `PowBlock`) as well. I had to disable a few spec tests related to
handling the merge block since those code paths are removed.

Closes https://github.com/ChainSafe/lodestar/issues/8661
2025-12-12 10:18:23 +07:00
twoeths
1ddbe5d870 chore: use index2pubkey of BeaconChain (#8674)
**Motivation**

- once we have `state-transition-z`, we're not able to get
`index2pubkey` from a light view of BeaconState in beacon-node

**Description**

- in `beacon-node`, use `index2pubkey` of BeaconChain instead as a
preparation for working with `state-transition-z`
- it's ok to use `state.epochCtx.index2pubkey` in `state-transition`
since it can access the full state there

part of #8652

---------

Co-authored-by: Tuyen Nguyen <twoeths@users.noreply.github.com>
2025-12-11 14:19:08 -05:00
philknows
62d3e49f28 chore: bump package versions to 1.38.0 v1.38.0-rc.0 2025-12-10 11:44:00 -05:00
Nazar Hussain
34d4b7352f chore: update publish workflow for rc an stan;e (#8686)
**Motivation**

Use npm trusted publishing.

**Description**

- Fix the workflows for the `rc` and `stable`.
2025-12-10 11:39:49 -05:00
Nazar Hussain
255e56fb68 chore: pass secrets to nested publish workflows (#8684)
**Motivation**

Pass the workflow secrets in scenario of nested workflows.

**Description**

- Use `secrets: inherit` in case of workflows.
2025-12-10 10:57:09 -05:00
Nazar Hussain
f231d7e8ff chore: use github runners for publish workflow (#8683)
**Motivation**

Provide npm provenance for published packages.

https://docs.npmjs.com/generating-provenance-statements

**Description**

- Use github runners for publish workflows to cover the error. 

```
Error verifying sigstore provenance bundle: Unsupported GitHub Actions runner environment: "self-hosted". Only "github-hosted" runners are supported when publishing with provenance.
```
2025-12-10 10:32:52 -05:00
Nazar Hussain
d5b1e44150 chore: update publish workflow to use job syntax instead of steps (#8682)
**Motivation**

Enable npm trusted publishing

**Description**

- Use job syntax and not the steps.
2025-12-10 16:15:34 +01:00
Nazar Hussain
fe261483ef chore: use npm trusted publishing (#8675)
**Motivation**

Use more secure way publish a release.

**Description**

- Use `npm` [trusted
publishing](https://docs.npmjs.com/trusted-publishers)

---------

Co-authored-by: Matthew Keil <me@matthewkeil.com>
2025-12-10 09:55:26 -04:00
Cayman
688d5584ea feat: use snappy-wasm (#6483) (#8647)
**Motivation**
- #6483 is back 😂 
- Benchmarks show `snappy-wasm` is faster at compressing and
uncompressing than `snappyjs`.

**Description**

- Use `snappy-wasm` for compressing / uncompressing gossip payloads
- Add more `snappy` vs `snappyjs` vs `snappy-wasm` benchmarks

**TODO**
- [x] deploy this branch on our test fleet - deployed on feat3

```
  network / gossip / snappy
    compress
      ✔ 100 bytes - compress - snappyjs                                     335566.9 ops/s    2.980032 us/op        -        685 runs   2.54 s
      ✔ 100 bytes - compress - snappy                                       388610.3 ops/s    2.573272 us/op        -        870 runs   2.74 s
      ✔ 100 bytes - compress - snappy-wasm                                  583254.0 ops/s    1.714519 us/op        -        476 runs   1.32 s
      ✔ 100 bytes - compress - snappy-wasm - prealloc                        1586695 ops/s    630.2410 ns/op        -        481 runs  0.804 s
      ✔ 200 bytes - compress - snappyjs                                     298272.8 ops/s    3.352636 us/op        -        213 runs   1.22 s
      ✔ 200 bytes - compress - snappy                                       419528.0 ops/s    2.383631 us/op        -        926 runs   2.71 s
      ✔ 200 bytes - compress - snappy-wasm                                  472468.5 ops/s    2.116543 us/op        -        577 runs   1.72 s
      ✔ 200 bytes - compress - snappy-wasm - prealloc                        1430445 ops/s    699.0830 ns/op        -        868 runs   1.11 s
      ✔ 300 bytes - compress - snappyjs                                     265124.9 ops/s    3.771807 us/op        -        137 runs   1.02 s
      ✔ 300 bytes - compress - snappy                                       361683.9 ops/s    2.764845 us/op        -       1332 runs   4.18 s
      ✔ 300 bytes - compress - snappy-wasm                                  443688.4 ops/s    2.253834 us/op        -        859 runs   2.44 s
      ✔ 300 bytes - compress - snappy-wasm - prealloc                        1213825 ops/s    823.8420 ns/op        -        370 runs  0.807 s
      ✔ 400 bytes - compress - snappyjs                                     262168.5 ops/s    3.814341 us/op        -        358 runs   1.87 s
      ✔ 400 bytes - compress - snappy                                       382494.9 ops/s    2.614414 us/op        -       1562 runs   4.58 s
      ✔ 400 bytes - compress - snappy-wasm                                  406373.2 ops/s    2.460792 us/op        -        797 runs   2.46 s
      ✔ 400 bytes - compress - snappy-wasm - prealloc                        1111715 ops/s    899.5110 ns/op        -        450 runs  0.906 s
      ✔ 500 bytes - compress - snappyjs                                     229213.1 ops/s    4.362753 us/op        -        359 runs   2.07 s
      ✔ 500 bytes - compress - snappy                                       373695.8 ops/s    2.675973 us/op        -       2050 runs   5.99 s
      ✔ 500 bytes - compress - snappy-wasm                                  714917.4 ops/s    1.398763 us/op        -        960 runs   1.84 s
      ✔ 500 bytes - compress - snappy-wasm - prealloc                        1054619 ops/s    948.2100 ns/op        -        427 runs  0.907 s
      ✔ 1000 bytes - compress - snappyjs                                    148702.3 ops/s    6.724847 us/op        -        171 runs   1.65 s
      ✔ 1000 bytes - compress - snappy                                      423688.1 ops/s    2.360227 us/op        -        525 runs   1.74 s
      ✔ 1000 bytes - compress - snappy-wasm                                 524350.6 ops/s    1.907121 us/op        -        273 runs   1.03 s
      ✔ 1000 bytes - compress - snappy-wasm - prealloc                      685191.5 ops/s    1.459446 us/op        -        349 runs   1.01 s
      ✔ 10000 bytes - compress - snappyjs                                   21716.92 ops/s    46.04704 us/op        -         16 runs   1.24 s
      ✔ 10000 bytes - compress - snappy                                     98051.32 ops/s    10.19874 us/op        -        184 runs   2.39 s
      ✔ 10000 bytes - compress - snappy-wasm                                114681.8 ops/s    8.719783 us/op        -         49 runs  0.937 s
      ✔ 10000 bytes - compress - snappy-wasm - prealloc                     111203.6 ops/s    8.992518 us/op        -         49 runs  0.953 s
      ✔ 100000 bytes - compress - snappyjs                                  2947.313 ops/s    339.2921 us/op        -         12 runs   4.74 s
      ✔ 100000 bytes - compress - snappy                                    14963.78 ops/s    66.82801 us/op        -         70 runs   5.19 s
      ✔ 100000 bytes - compress - snappy-wasm                               19868.33 ops/s    50.33136 us/op        -         14 runs   1.21 s
      ✔ 100000 bytes - compress - snappy-wasm - prealloc                    24579.34 ops/s    40.68457 us/op        -         13 runs   1.06 s
    uncompress
      ✔ 100 bytes - uncompress - snappyjs                                   589201.6 ops/s    1.697212 us/op        -        242 runs  0.911 s
      ✔ 100 bytes - uncompress - snappy                                     537424.1 ops/s    1.860728 us/op        -        220 runs  0.910 s
      ✔ 100 bytes - uncompress - snappy-wasm                                634966.2 ops/s    1.574887 us/op        -        194 runs  0.808 s
      ✔ 100 bytes - uncompress - snappy-wasm - prealloc                      1846964 ops/s    541.4290 ns/op        -        559 runs  0.804 s
      ✔ 200 bytes - uncompress - snappyjs                                   395141.8 ops/s    2.530737 us/op        -        281 runs   1.22 s
      ✔ 200 bytes - uncompress - snappy                                     536862.6 ops/s    1.862674 us/op        -        274 runs   1.01 s
      ✔ 200 bytes - uncompress - snappy-wasm                                420251.6 ops/s    2.379527 us/op        -        129 runs  0.810 s
      ✔ 200 bytes - uncompress - snappy-wasm - prealloc                      1746167 ops/s    572.6830 ns/op        -        529 runs  0.804 s
      ✔ 300 bytes - uncompress - snappyjs                                   441676.2 ops/s    2.264102 us/op        -        898 runs   2.53 s
      ✔ 300 bytes - uncompress - snappy                                     551313.2 ops/s    1.813851 us/op        -        336 runs   1.11 s
      ✔ 300 bytes - uncompress - snappy-wasm                                494773.0 ops/s    2.021129 us/op        -        203 runs  0.912 s
      ✔ 300 bytes - uncompress - snappy-wasm - prealloc                      1528680 ops/s    654.1590 ns/op        -        465 runs  0.805 s
      ✔ 400 bytes - uncompress - snappyjs                                   383746.1 ops/s    2.605890 us/op        -        235 runs   1.11 s
      ✔ 400 bytes - uncompress - snappy                                     515986.6 ops/s    1.938035 us/op        -        158 runs  0.809 s
      ✔ 400 bytes - uncompress - snappy-wasm                                392947.8 ops/s    2.544867 us/op        -        322 runs   1.32 s
      ✔ 400 bytes - uncompress - snappy-wasm - prealloc                      1425978 ops/s    701.2730 ns/op        -        721 runs   1.01 s
      ✔ 500 bytes - uncompress - snappyjs                                   330727.5 ops/s    3.023637 us/op        -        173 runs   1.02 s
      ✔ 500 bytes - uncompress - snappy                                     513874.1 ops/s    1.946002 us/op        -        157 runs  0.806 s
      ✔ 500 bytes - uncompress - snappy-wasm                                389263.0 ops/s    2.568957 us/op        -        161 runs  0.914 s
      ✔ 500 bytes - uncompress - snappy-wasm - prealloc                      1330936 ops/s    751.3510 ns/op        -        672 runs   1.01 s
      ✔ 1000 bytes - uncompress - snappyjs                                  241393.9 ops/s    4.142606 us/op        -        126 runs   1.03 s
      ✔ 1000 bytes - uncompress - snappy                                    491119.6 ops/s    2.036164 us/op        -        201 runs  0.911 s
      ✔ 1000 bytes - uncompress - snappy-wasm                               361794.5 ops/s    2.764000 us/op        -        148 runs  0.910 s
      ✔ 1000 bytes - uncompress - snappy-wasm - prealloc                    959026.5 ops/s    1.042724 us/op        -        390 runs  0.909 s
      ✔ 10000 bytes - uncompress - snappyjs                                 40519.03 ops/s    24.67976 us/op        -         16 runs  0.913 s
      ✔ 10000 bytes - uncompress - snappy                                   202537.6 ops/s    4.937355 us/op        -        796 runs   4.43 s
      ✔ 10000 bytes - uncompress - snappy-wasm                              165017.6 ops/s    6.059960 us/op        -         52 runs  0.822 s
      ✔ 10000 bytes - uncompress - snappy-wasm - prealloc                   175061.5 ops/s    5.712277 us/op        -        130 runs   1.25 s
      ✔ 100000 bytes - uncompress - snappyjs                                4030.391 ops/s    248.1149 us/op        -         12 runs   3.71 s
      ✔ 100000 bytes - uncompress - snappy                                  35459.43 ops/s    28.20124 us/op        -         41 runs   1.67 s
      ✔ 100000 bytes - uncompress - snappy-wasm                             22449.16 ops/s    44.54509 us/op        -         13 runs   1.11 s
      ✔ 100000 bytes - uncompress - snappy-wasm - prealloc                  27169.50 ops/s    36.80598 us/op        -         13 runs  0.997 s
```

Closes #4170

---------

Co-authored-by: Nico Flaig <nflaig@protonmail.com>
Co-authored-by: twoeths <10568965+twoeths@users.noreply.github.com>
Co-authored-by: Tuyen Nguyen <twoeths@users.noreply.github.com>
2025-12-08 23:20:08 -05:00
Progress Ochuko Eyaadah
868300d7ae chore: remove holesky configs and update tests to hoodi (#8622)
**Motivation**

Replace deprecated Holesky network support with Hoodi testnet
configuration. Hoodi is a new Ethereum testnet that will serve as a
replacement testnet, and this change updates Lodestar to support the new
network configuration.

**Description**

This PR removes Holesky network configuration and replaces all
references with Hoodi testnet support. Changes include:

- Removed `packages/cli/src/networks/holesky.ts` network file
- Removed `packages/config/src/chainConfig/networks/holesky.ts` chain
config
- Updated all network references from "holesky" to "hoodi" across CLI,
config, and test files
- Added Hoodi network configuration with proper chain parameters,
genesis data, and bootnodes
- Updated default environment configuration
- Updated unit tests to reflect the network change


<!-- Link to issues: https://github.com/ChainSafe/lodestar/issues/8595
-->

Closes #https://github.com/ChainSafe/lodestar/pull/8615

**AI Assistance Disclosure**

- [ ] External Contributors: I have read the [contributor
guidelines](https://github.com/ChainSafe/lodestar/blob/unstable/CONTRIBUTING.md#ai-assistance-notice)
and disclosed my usage of AI below.

<!-- Insert any AI assistance disclosure here -->
-PR content was developed using Cursor for code updates and
explanations; I reviewed and verified all changes manually.
2025-12-08 15:44:36 +01:00
NC
1f2a3a4524 feat: implement epbs state transition (#8507)
Implement epbs state transition function.

Passes all operations, epoch_transition and rewards spec tests on v1.6.1

Part of #8439

---------

Co-authored-by: Nico Flaig <nflaig@protonmail.com>
2025-12-04 08:35:47 -08:00
Nico Flaig
f61b8d9dad chore: display cgc in lodestar summary dashboard (#8668)
<img width="949" height="213" alt="image"
src="https://github.com/user-attachments/assets/a87dfba8-a8bf-48cf-9738-459e77ba1099"
/>

cc @wemeetagain
2025-12-04 09:41:02 -05:00
Cayman
362bd5ea5d feat: support and test node 24 (#8645)
**Motivation**

- Support the latest LTS

**Description**

- support node 24

---------

Co-authored-by: Nico Flaig <nflaig@protonmail.com>
2025-12-03 13:32:11 -05:00
Nico Flaig
6938ce2049 fix: don't try to serve states for future slots (#8665)
**Motivation**

When requesting a future slot the node tries to dial the state from head
which allows to quite easily DoS the node as it's unbounded amount of
work if the slot is very far away from head.

We should not allow to request states that are in the future (> clock
slot) and return a 404 instead.

**Description**

In case state is request by slot, check if it's a slot from the future
based on clock slot and return 404 state not found error.

I didn't use `forkChoice.getHead().slot` because we should still be able
to serve the state if all slots between the requested slot and the head
slot are skipped.

Related [discord
discussion](https://discord.com/channels/593655374469660673/1387128551962050751/1445514034592878755),
thanks to @guha-rahul for catching and reporting this.
2025-12-03 09:59:02 -05:00
twoeths
1ad9c40143 chore: improve benchmark (#8664)
**Motivation**

- it takes so much time to run benchmark, a lot of them does not make
sense
- seeing OOM with NodeJS 24, see
https://github.com/ChainSafe/lodestar/pull/8645#issuecomment-3601327203

**Description**

- remove benchmarks for flow that's not used in prod
- remove some "minMs" option for some tests that causes a lot of time
- remote test that does not reflect the bottle neck of lodestar's
performance as of Dec 2025
- remote tests that's not part of lodestar code. It's only meaningful in
the scope of that PR only

this is based on the long running test I found in
https://github.com/ChainSafe/lodestar/actions/runs/19874295397/job/56957698411

```
packages/beacon-node/test/perf/chain/validation/attestation.test.ts
  validate gossip attestation
    ✔ batch validate gossip attestation - vc 640000 - chunk 32            8931.657 ops/s    111.9613 us/op   x0.918       7814 runs   30.0 s
    ✔ batch validate gossip attestation - vc 640000 - chunk 64            9972.473 ops/s    100.2760 us/op   x0.926       4321 runs   30.1 s
    ✔ batch validate gossip attestation - vc 640000 - chunk 128           10569.62 ops/s    94.61075 us/op   x0.921       2268 runs   30.0 s
    ✔ batch validate gossip attestation - vc 640000 - chunk 256           10069.74 ops/s    99.30746 us/op   x0.901       1154 runs   30.1 s

packages/fork-choice/test/perf/protoArray/computeDeltas.test.ts
  computeDeltas
    ✔ computeDeltas 1400000 validators 0% inactive                        73.51301 ops/s    13.60303 ms/op   x0.986        539 runs   10.0 s
    ✔ computeDeltas 1400000 validators 10% inactive                       78.91095 ops/s    12.67251 ms/op   x0.989        556 runs   10.0 s
    ✔ computeDeltas 1400000 validators 20% inactive                       86.73608 ops/s    11.52923 ms/op   x1.001        598 runs   10.0 s
    ✔ computeDeltas 1400000 validators 50% inactive                       114.8443 ops/s    8.707439 ms/op   x0.990        799 runs   10.0 s
    ✔ computeDeltas 2100000 validators 0% inactive                        48.69939 ops/s    20.53414 ms/op   x0.996        371 runs   10.0 s
    ✔ computeDeltas 2100000 validators 10% inactive                       53.13929 ops/s    18.81847 ms/op   x1.000        371 runs   10.0 s
    ✔ computeDeltas 2100000 validators 20% inactive                       60.11017 ops/s    16.63612 ms/op   x0.978        418 runs   10.0 s
    ✔ computeDeltas 2100000 validators 50% inactive                       79.46802 ops/s    12.58368 ms/op   x0.967        552 runs   10.0 s

packages/state-transition/test/perf/util/loadState/findModifiedValidators.test.ts
  find modified validators by different ways
    serialize validators then findModifiedValidators
      ✔ findModifiedValidators - 10000 modified validators                  1.382729 ops/s    723.2076 ms/op   x0.993         10 runs   9.21 s
      ✔ findModifiedValidators - 1000 modified validators                   1.298120 ops/s    770.3450 ms/op   x1.152         10 runs   8.68 s
      ✔ findModifiedValidators - 100 modified validators                    3.535168 ops/s    282.8720 ms/op   x1.329         10 runs   3.85 s
      ✔ findModifiedValidators - 10 modified validators                     4.648368 ops/s    215.1293 ms/op   x1.548         10 runs   3.13 s
      ✔ findModifiedValidators - 1 modified validators                      5.296754 ops/s    188.7949 ms/op   x1.187         10 runs   3.10 s
      ✔ findModifiedValidators - no difference                              3.873496 ops/s    258.1647 ms/op   x1.236         12 runs   3.88 s
    deserialize validators then compare validator ViewDUs
      ✔ compare ViewDUs                                                    0.1524038 ops/s    6.561514  s/op   x1.077          9 runs   65.7 s
    serialize each validator then compare Uin8Array
      ✔ compare each validator Uint8Array                                  0.8007866 ops/s    1.248772  s/op   x0.830         10 runs   13.7 s
    compare validator ViewDU to Uint8Array
      ✔ compare ViewDU to Uint8Array                                       0.9549799 ops/s    1.047143  s/op   x0.999         10 runs   11.5 s

packages/state-transition/test/perf/util/loadState/loadState.test.ts
  loadState
    ✔ migrate state 1000000 validators, 24 modified, 0 new               0.9790753 ops/s    1.021372  s/op   x1.147         57 runs   60.1 s
    ✔ migrate state 1000000 validators, 1700 modified, 1000 new          0.7290797 ops/s    1.371592  s/op   x0.942         43 runs   61.1 s
    ✔ migrate state 1000000 validators, 3400 modified, 2000 new          0.6307866 ops/s    1.585322  s/op   x0.883         37 runs   60.9 s
    ✔ migrate state 1500000 validators, 24 modified, 0 new               0.9393088 ops/s    1.064613  s/op   x0.911         55 runs   60.5 s
    ✔ migrate state 1500000 validators, 1700 modified, 1000 new          0.8235204 ops/s    1.214299  s/op   x0.785         48 runs   60.2 s
    ✔ migrate state 1500000 validators, 3400 modified, 2000 new          0.6997867 ops/s    1.429007  s/op   x0.720         41 runs   60.7 s


  ✔ naive computeProposerIndex 100000 validators                        21.29210 ops/s    46.96578 ms/op   x0.591         10 runs   51.8 s

  getNextSyncCommitteeIndices electra
    ✔ naiveGetNextSyncCommitteeIndices 1000 validators                   0.1319639 ops/s    7.577831  s/op   x0.675          8 runs   66.8 s
    ✔ getNextSyncCommitteeIndices 1000 validators                         9.444554 ops/s    105.8811 ms/op   x0.753         10 runs   1.60 s
    ✔ naiveGetNextSyncCommitteeIndices 10000 validators                  0.1280431 ops/s    7.809868  s/op   x0.766          7 runs   61.8 s
    ✔ getNextSyncCommitteeIndices 10000 validators                        9.244910 ops/s    108.1676 ms/op   x0.880         10 runs   1.62 s
    ✔ naiveGetNextSyncCommitteeIndices 100000 validators                 0.1295493 ops/s    7.719071  s/op   x0.814          7 runs   61.9 s
    ✔ getNextSyncCommitteeIndices 100000 validators                       9.279165 ops/s    107.7683 ms/op   x0.751         10 runs   1.62 s

  computeShuffledIndex
    ✔ naive computeShuffledIndex 100000 validators                      0.04376956 ops/s    22.84693  s/op   x0.719          2 runs   67.8 s
    ✔ cached computeShuffledIndex 100000 validators                       1.790556 ops/s    558.4858 ms/op   x0.973         10 runs   6.16 s
    ✔ naive computeShuffledIndex 2000000 validators                    0.002243157 ops/s    445.8003  s/op   x0.922          1 runs    931 s
    ✔ cached computeShuffledIndex 2000000 validators                    0.02947726 ops/s    33.92445  s/op   x0.810          1 runs   71.3 s

packages/state-transition/test/perf/util/signingRoot.test.ts
  computeSigningRoot
    ✔ computeSigningRoot for AttestationData                              51551.61 ops/s    19.39804 us/op   x0.905        491 runs   10.0 s
    ✔ hash AttestationData serialized data then Buffer.toString(base64    639269.7 ops/s    1.564285 us/op   x0.977       5818 runs   10.0 s
    ✔ toHexString serialized data                                         886487.9 ops/s    1.128047 us/op   x0.926       8417 runs   10.0 s
    ✔ Buffer.toString(base64)                                              6071166 ops/s    164.7130 ns/op   x0.974      50685 runs   10.1 s
```

---------

Co-authored-by: Tuyen Nguyen <twoeths@users.noreply.github.com>
2025-12-03 09:57:51 -05:00
Lion - dapplion
8475d71f09 test: remove testcontainers dependency for web3signer test (#4567)
**Motivation**

- PR https://github.com/ChainSafe/lodestar/pull/4502 introduced a dev
testcontainers since @dadepo was having issues with docker

I really want to start decreasing our dependencies exposure, not
increasing it unless required. We have rolled our docker runners in the
past and should continue to do so.

**Description**

- Use adhoc docker

@dadepo I've removed the use of --network=host. If you have to run this
tests locally try to understand the incompatibilities and fix them
together without 3rd party libraries

---------

Co-authored-by: Cayman <caymannava@gmail.com>
Co-authored-by: Nico Flaig <nflaig@protonmail.com>
2025-12-03 09:57:04 -05:00
Nico Flaig
bc1fed4d3d fix: avoid recomputing indexed attestations during block import (#8637)
**Motivation**

- https://github.com/ChainSafe/lodestar/issues/8625

**Description**

Store indexed attestations for each block during block/signature
verification to avoid recomputing them during import
- compute `indexedAttestationsByBlock` once during verification
- enhance `FullyVerifiedBlock` to include indexed attestations for block
import

Closes https://github.com/ChainSafe/lodestar/issues/8625
2025-12-03 14:49:20 +01:00
dependabot[bot]
548d7aa41e chore(deps): bump mdast-util-to-hast from 13.1.0 to 13.2.1 in /docs (#8649)
Bumps
[mdast-util-to-hast](https://github.com/syntax-tree/mdast-util-to-hast)
from 13.1.0 to 13.2.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/syntax-tree/mdast-util-to-hast/releases">mdast-util-to-hast's
releases</a>.</em></p>
<blockquote>
<h2>13.2.1</h2>
<h4>Fix</h4>
<ul>
<li>ab3a795 Fix support for spaces in class names</li>
</ul>
<h4>Types</h4>
<ul>
<li>efb5312 Refactor to use <code>@import</code>s</li>
<li>a5bc210 Add declaration maps</li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/syntax-tree/mdast-util-to-hast/compare/13.2.0...13.2.1">https://github.com/syntax-tree/mdast-util-to-hast/compare/13.2.0...13.2.1</a></p>
<h2>13.2.0</h2>
<h4>Types</h4>
<ul>
<li>24f4576 Add type for <code>data.meta</code> on elements to hast</li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/syntax-tree/mdast-util-to-hast/compare/13.1.0...13.2.0">https://github.com/syntax-tree/mdast-util-to-hast/compare/13.1.0...13.2.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="174795b21f"><code>174795b</code></a>
13.2.1</li>
<li><a
href="3d05b3a715"><code>3d05b3a</code></a>
Update Node in Actions</li>
<li><a
href="ab3a79570a"><code>ab3a795</code></a>
Fix support for spaces in class names</li>
<li><a
href="efb5312310"><code>efb5312</code></a>
Refactor to use <code>@import</code>s</li>
<li><a
href="a5bc210f1a"><code>a5bc210</code></a>
Add declaration maps</li>
<li><a
href="b54955d4e1"><code>b54955d</code></a>
Add <code>.tsbuildinfo</code> to <code>.gitignore</code></li>
<li><a
href="f511a93817"><code>f511a93</code></a>
13.2.0</li>
<li><a
href="24f4576508"><code>24f4576</code></a>
Add type for <code>data.meta</code> on elements to hast</li>
<li><a
href="feeec02562"><code>feeec02</code></a>
Update dev-dependencies</li>
<li>See full diff in <a
href="https://github.com/syntax-tree/mdast-util-to-hast/compare/13.1.0...13.2.1">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=mdast-util-to-hast&package-manager=npm_and_yarn&previous-version=13.1.0&new-version=13.2.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/ChainSafe/lodestar/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-02 10:26:57 +01:00
Nico Flaig
a8c0c7a156 chore: fix test current file launch args (#8632)
Updates `Test Current File` launch config to work with vitest 4 (updated
in https://github.com/ChainSafe/lodestar/pull/8599).
2025-12-01 14:48:21 -05:00
guha-rahul
7dec9cd8fb docs: add ERA package to readme (#8644)
**Motivation**

- The era package was not mentioned in the readme.

**Description**

<!-- A clear and concise general description of the changes of this pull
request. -->

<!-- If applicable, add screenshots to help explain your solution -->

<!-- Link to issues: Resolves #111, Resolves #222 -->


**AI Assistance Disclosure**

- [x] External Contributors: I have read the [contributor
guidelines](https://github.com/ChainSafe/lodestar/blob/unstable/CONTRIBUTING.md#ai-assistance-notice)
and disclosed my usage of AI below.

<!-- Insert any AI assistance disclosure here -->
2025-12-01 10:51:51 -05:00
guha-rahul
8f113529e2 fix: skip genesis slot signature check when validating ERA files (#8642)
**Motivation**

- Era validation lacked genesis slot signature verification skip

**Description**

- Adds a check for genesis slot and skips signature verification for
slot 0 in ERA validation


**AI Assistance Disclosure**

- [x] External Contributors: I have read the [contributor
guidelines](https://github.com/ChainSafe/lodestar/blob/unstable/CONTRIBUTING.md#ai-assistance-notice)
and disclosed my usage of AI below.
No AI is used.
<!-- Insert any AI assistance disclosure here -->
2025-12-01 15:24:41 +00:00
Phil Ngo
68e0c78624 chore: merge v1.37.0 stable back to unstable (#8643) 2025-12-01 10:20:10 -05:00
Phil Ngo
eaf5bc974a chore: v1.37.0 release (#8640) v1.37.0 2025-12-01 09:18:48 -05:00
twoeths
0c3b3f119c feat: track DataTransform metrics (#8639)
**Motivation**

- we usually have to uncompress more messages than needed so it's good
to track it in DataTransform

**Description**

- track `compress` and `uncompress` times by topic type
- in this instance, this node only subscribe to 8 column subnets but we
usually have to uncompress 9 or up to 10/11 DataColumnSidecars per slot,
they will likely be duplicated in the end. See also
https://github.com/ChainSafe/js-libp2p-gossipsub/pull/536

part of #8629
<img width="1046" height="485" alt="Screenshot 2025-11-28 at 17 02 42"
src="https://github.com/user-attachments/assets/df190b29-6681-48de-a04e-cd79ab82858d"
/>

Co-authored-by: Tuyen Nguyen <twoeths@users.noreply.github.com>
2025-12-01 09:14:28 +07:00
philknows
2303b06a91 chore: bump package versions to 1.37.0 v1.37.0-rc.0 2025-11-28 10:17:20 -05:00
Nazar Hussain
c68bfb2ae3 refactor: introduce safe-block to fork-choice (#8618)
**Motivation**

There is a concept documented in the specs called
[safe-block](https://github.com/ethereum/consensus-specs/blob/master/fork_choice/safe-block.md).
Wanted to introduce that concept in our codebase so upcoming feature of
`fcr` have less invasive changes.

**Description**

- Expose functions `getSafeBeaconBlockRoot` and
`getSafeExecutionBlockHash` from `fork-choice` package.
- Update the usage of `safeBlock` to use those functions

---------

Co-authored-by: Nico Flaig <nflaig@protonmail.com>
2025-11-28 15:48:06 +01:00
Nico Flaig
dcab62468a feat: add validator client option to disable skipping slots (#8631)
**Motivation**

We don't wanna skip slots if slot processing takes longer than slot
duration in a distributed setup as delays might get caused by hanging
HTTP requests due to DVT middleware not reaching the signature
threshold.

**Description**

Adds new flag `--clock.skipSlots` (default: `true`) to validator client
to allow disabling skipping slots by setting it to `false`.

**Note:** it will always be set to `false` if `--distributed` flag is
set as the behavior is not desired in a DVT cluster as assumptions about
beacon node change and skipping slots does more harm than good.

Related issue https://github.com/ChainSafe/lodestar/issues/5314
2025-11-28 02:57:47 +01:00
Nico Flaig
ac3059c9b9 test: update web3signer e2e tests to fulu (#8635)
**Motivation**

Closes https://github.com/ChainSafe/lodestar/issues/8316

**Description**

- enable fulu signature tests
- update web3signer to version
[25.11.0](https://github.com/Consensys/web3signer/releases/tag/25.11.0)
2025-11-28 02:57:32 +01:00
Nico Flaig
2724822372 fix: compare signature bytes in proposer signature cache check (#8636)
**Motivation**

https://github.com/ChainSafe/lodestar/pull/8620#discussion_r2567993594

**Description**

Compare signature bytes in proposer signature cache check
2025-11-28 02:57:13 +01:00
dependabot[bot]
2d3601648b chore(deps): bump node-forge from 1.3.1 to 1.3.2 in /docs (#8633) 2025-11-27 11:47:03 +01:00