Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
79d4067
feat(validator-status): persist f_activation_eligibility_epoch
Zyra-V21 Jun 9, 2026
771eb30
docs: clarify deposit-lifecycle vocabulary is proposed, not current B…
Zyra-V21 Jun 9, 2026
ab60df0
docs: rename pending_balance -> pending_minBalance in tables.md
Zyra-V21 Jun 12, 2026
58f0a6d
Merge pull request #274 from migalabs/feat/deposit-lifecycle-statuses
Zyra-V21 Jun 12, 2026
3a2d502
fix(db): remove semicolon inside migration 000037 comment
Zyra-V21 Jun 15, 2026
dadcd7b
feat(relay): add ETHGas relay to mainnet and hoodi relay lists
Zyra-V21 Jul 13, 2026
6f61952
Merge pull request #276 from migalabs/feat/add-ethgas-relay
Zyra-V21 Jul 13, 2026
b064dfd
Update maintainer information in README.md
Zyra-V21 Jul 22, 2026
b96a86b
fix(db): make pool summary aggregation consistent and refreshable
Zyra-V21 Jul 23, 2026
d176ba6
feat(val-window): refresh recent pool summaries when pool tags change
Zyra-V21 Jul 23, 2026
d069048
Merge pull request #278 from migalabs/fix/pool-summary-consistency
Zyra-V21 Jul 24, 2026
a39dba2
fix(val-window): skip pool reroll while the pubkeys table is mid-sync
Zyra-V21 Jul 24, 2026
f3b7487
Merge pull request #279 from migalabs/fix/reroll-truncate-guard
Zyra-V21 Jul 24, 2026
55accce
fix(blobs): record p2p arrival timings again via data_column_sidecar …
Zyra-V21 Jul 24, 2026
2a8aef3
fix(db): make migration 000038 retry-safe with IF NOT EXISTS
Zyra-V21 Aug 11, 2026
9072b7d
fix(events): log and skip instead of crashing on data_column_sidecar …
Zyra-V21 Aug 11, 2026
761372c
perf(analyzer): batch data_column_sidecar persistence off the head loop
Zyra-V21 Aug 11, 2026
e7b924b
fix(analyzer): make the stop flag an atomic.Bool
Zyra-V21 Aug 11, 2026
6d8209a
feat(metrics): expose data_column_sidecar subscription state as a gauge
Zyra-V21 Aug 11, 2026
6078c79
Merge pull request #281 from migalabs/fix/data-column-sidecar-events-280
Zyra-V21 Aug 13, 2026
3f4d042
Merge pull request #283 from migalabs/perf/batch-data-column-events-282
Zyra-V21 Aug 13, 2026
ba375ed
Merge pull request #284 from migalabs/fix/data-column-sidecar-events-280
Zyra-V21 Aug 13, 2026
bfb2cc8
fix(electra): recompute deposit counters when the state object was re…
ander-deran-arteaga Aug 28, 2026
7f17394
Attribute blob sidecars by position instead of by hash
ander-deran-arteaga Aug 28, 2026
b7889c6
fix(reorg): stop AdvanceFinalized orphaning rows it never rewrites
ander-deran-arteaga Aug 28, 2026
8d40fd2
fix(electra): make the deposit recompute idempotent instead of guarded
ander-deran-arteaga Sep 1, 2026
df5bc90
fix(blobs): attribute from the block body instead of the receipt-pars…
ander-deran-arteaga Sep 1, 2026
e36ae45
fix(blobs): name both hashes when a sidecar does not match its position
ander-deran-arteaga Sep 1, 2026
ef0525a
fix(reorg): rewrite reorged epoch metrics after the walk, lowest first
ander-deran-arteaga Sep 1, 2026
4de43bd
fix(reorg): guard the genesis epoch row, and carry an epoch whose own…
ander-deran-arteaga Sep 1, 2026
8bbfc20
revert(reorg): the carry cannot cover an epoch whose own check failed
ander-deran-arteaga Sep 1, 2026
df48665
fix(reorg): make sure the states are still cached before rewriting
ander-deran-arteaga Sep 1, 2026
017b5ab
chore: keep unrelated files out of this branch
ander-deran-arteaga Sep 1, 2026
b22e83b
fix: apply the deposit-counter pattern to consolidation counters
ander-deran-arteaga Sep 3, 2026
d4bf8cd
Merge pull request #290 from migalabs/fix/blob-sidecar-tx-attribution
ander-deran-arteaga Sep 3, 2026
bdb8b61
Merge pull request #288 from migalabs/fix/advance-finalized-orphans-rows
ander-deran-arteaga Sep 3, 2026
48abc88
fix(reorg): AdvanceFinalized can retry an epoch it failed to rewrite
ander-deran-arteaga Sep 7, 2026
04a601a
fix(reorg): drop an unreachable branch and never wait on a lost state
ander-deran-arteaga Sep 7, 2026
0e3293a
fix(analyzer): stop a duplicate epoch leaking a processerBook slot
ander-deran-arteaga Sep 7, 2026
f176583
fix(utils): stop the barrier leaking a timer and waiting for nothing
ander-deran-arteaga Sep 7, 2026
6f29fb1
ci: build, vet and test this repository
ander-deran-arteaga Sep 8, 2026
68a754e
Merge pull request #296 from migalabs/ci/build-and-test
ander-deran-arteaga Sep 8, 2026
191894d
Merge pull request #294 from migalabs/fix/processer-book-slot-leak
ander-deran-arteaga Sep 8, 2026
75485b5
Merge pull request #289 from migalabs/fix/deposit-counters-lost-on-st…
ander-deran-arteaga Sep 8, 2026
c44b48a
Merge pull request #293 from migalabs/fix/advance-finalized-can-retry
ander-deran-arteaga Sep 8, 2026
330b9e5
fix(clientapi,analyzer): stop leaking a timer per retry
ander-deran-arteaga Sep 16, 2026
641091f
fix: stop the long-lived tickers too, so the rule can be checked
ander-deran-arteaga Sep 16, 2026
a504bc8
test(utils): every ticker is stopped, checked across the repository
ander-deran-arteaga Sep 16, 2026
09d608f
fix(clientapi): decide "block not found" from the status code, not th…
ander-deran-arteaga Sep 18, 2026
43b3cd5
Merge pull request #299 from migalabs/fix/typed-not-found-check
ander-deran-arteaga Sep 22, 2026
078de2a
Merge pull request #297 from migalabs/fix/unstopped-tickers
ander-deran-arteaga Sep 22, 2026
c10847e
fix(relay): retry a failed delivered bids request before giving up th…
Zyra-V21 Oct 16, 2026
466e514
fix(relay): remove the bloXroute max-profit mainnet relay
Zyra-V21 Oct 16, 2026
6ee2e50
Merge pull request #301 from migalabs/fix/relay-request-retries
Zyra-V21 Oct 16, 2026
e61829d
fix(relay): retry a failed delivered bids request before giving up th…
Zyra-V21 Oct 16, 2026
04281a2
fix(relay): remove the bloXroute max-profit mainnet relay
Zyra-V21 Oct 16, 2026
3f4b45f
Merge pull request #302 from migalabs/hotfix/relay-retries
Zyra-V21 Oct 16, 2026
0e8bab9
add citation.cff file
cortze Oct 22, 2026
faf00dd
Update authors in CITATION.cff
Zyra-V21 Oct 22, 2026
b23c3ed
Update cff-version to 3.9.0
Zyra-V21 Oct 22, 2026
49b8185
chore: bump version to v3.9.0
Zyra-V21 Oct 22, 2026
f21cf49
Update cff-version from 3.9.0 to 1.2.0
Zyra-V21 Oct 22, 2026
c4fba76
Update version and release date in CITATION.cff
Zyra-V21 Oct 22, 2026
76a9305
Merge pull request #303 from migalabs/dev
Zyra-V21 Oct 22, 2026
6a2816d
Merge pull request #304 from cortze/add-doi-reference
Zyra-V21 Oct 22, 2026
9a31a54
Merge migalabs/goteth 3.9.0 into Obol fork
anadi2311 Nov 11, 2026
e9d99a6
ci: read-only token for the CI workflow (CodeQL)
anadi2311 Nov 12, 2026
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
39 changes: 39 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: CI

on:
push:
branches: [main, master, dev]
pull_request:

# The job only reads the code: give its token read access, like build_push.yml.
permissions:
contents: read

# This repository had no CI at all. Every change to the indexer serving
# mainnet merged without being compiled, vetted or tested by anything but
# whoever wrote it.
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
# go.mod replaces go-relay-client with a local path.
submodules: recursive

- uses: actions/setup-go@v5
with:
go-version-file: go.mod
cache: true

- name: Build
run: go build ./...

- name: Vet
run: go vet ./...

- name: Test
# The metrics tests need a live beacon node and skip themselves when
# none answers; set GOTETH_TEST_BN_ENDPOINT (and GOTETH_TEST_EL_ENDPOINT)
# to run them against one.
run: go test -race ./...
Comment thread
github-advanced-security[bot] marked this conversation as resolved.
Fixed
31 changes: 31 additions & 0 deletions CITATION.cff
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
cff-version: 1.2.0
message: "If you use this software, please cite it using the metadata from this file."
type: software
title: GotEth
abstract: >-
GotEth is a go-written client that indexes all validator-related duties,
parameters and transactions from Ethereum's consensus and execution layers.
authors:
- given-names: Tarun
family-names: Mohandas
affiliation: MigaLabs
- alias: Zyra-V21
given-names: Ruben
family-names: Planes Llinares
affiliation: MigaLabs
- given-names: Leo
family-names: Bautista-Gomez
affiliation: MigaLabs
- given-names: Mikel
family-names: Cortes
affiliation: MigaLabs
repository-code: "https://github.com/migalabs/goteth"
license: MIT
keywords:
- ethereum
- consensus layer
- beacon chain
- validators
- clickhouse
version: v3.9.0
date-released: "2026-10-22"
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,15 @@ If specific upgrades or downgrades need to be done manually, one could do this w
During `v3.0.0` we migrated our database system from PostgreSQL to Clickhouse.
If you wish to migrate your existing database, please follow [this](https://migalabs.notion.site/PostgreSQL-to-Clickhouse-migration-611a52a457824cd494d701773365f62f) guide.

# Citation

[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.XXXXXXX.svg)](https://doi.org/10.5281/zenodo.XXXXXXX)

If you use GotEth in your work, please cite it using the metadata in [CITATION.cff](CITATION.cff), or the "Cite this repository" button on GitHub.

# Maintainers

@santi1234567
@Zyra-V21

# Contributing

Expand Down
2 changes: 1 addition & 1 deletion cmd/blocks_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ var BlocksCommand = &cli.Command{
},
&cli.StringFlag{
Name: "metrics",
Usage: "Metrics to be persisted to the database: epoch,block,rewards,transactions,api_rewards,blob_sidecars",
Usage: "Metrics to be persisted to the database: epoch,block,rewards,transactions,api_rewards,blob_sidecars. blob_sidecars covers blob metadata (t_blob_sidecars); blob p2p arrival timings are always recorded in head mode via the data_column_sidecar event into t_data_column_sidecars_events (the post-Fulu replacement of the dead blob_sidecar event)",
EnvVars: []string{"ANALYZER_METRICS"},
DefaultText: "epoch,block",
},
Expand Down
71 changes: 71 additions & 0 deletions cmd/pool_summary_refill_cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package cmd

import (
"fmt"

"github.com/attestantio/go-eth2-client/spec/phase0"
"github.com/migalabs/goteth/pkg/db"
"github.com/migalabs/goteth/pkg/utils"
"github.com/sirupsen/logrus"
cli "github.com/urfave/cli/v2"
)

var PoolSummaryRefillCommand = &cli.Command{
Name: "pool-summary-refill",
Usage: "Recomputes t_pool_summary for an epoch range from the current rewards and pool tags. Deletes the range first so pool renames do not leave ghost rows. Use after pool re-tagging or rewards backfills.",
Action: LaunchPoolSummaryRefill,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "log-level",
Usage: "Log level: debug, warn, info, error",
EnvVars: []string{"ANALYZER_LOG_LEVEL"},
DefaultText: "info",
},
&cli.StringFlag{
Name: "db-url",
Usage: "Database where the pool summaries are persisted",
EnvVars: []string{"ANALYZER_DB_URL"},
DefaultText: "clickhouse://username:password@localhost:9000/goteth?x-multi-statement=true&max_memory_usage=10000000000",
},
&cli.Uint64Flag{
Name: "from-epoch",
Usage: "First epoch of the range to recompute (inclusive)",
Required: true,
},
&cli.Uint64Flag{
Name: "to-epoch",
Usage: "Last epoch of the range to recompute (inclusive)",
Required: true,
},
},
}

func LaunchPoolSummaryRefill(c *cli.Context) error {

if c.IsSet("log-level") {
logrus.SetLevel(utils.ParseLogLevel(c.String("log-level")))
}

dbUrl := c.String("db-url")
if dbUrl == "" {
return fmt.Errorf("db-url is required")
}

fromEpoch := phase0.Epoch(c.Uint64("from-epoch"))
toEpoch := phase0.Epoch(c.Uint64("to-epoch"))
if toEpoch < fromEpoch {
return fmt.Errorf("to-epoch (%d) must be greater or equal than from-epoch (%d)", toEpoch, fromEpoch)
}

dbClient, err := db.New(c.Context, dbUrl)
if err != nil {
return err
}
err = dbClient.Connect()
if err != nil {
return err
}
defer dbClient.Finish()

return dbClient.RefreshPoolSummaryRange(fromEpoch, toEpoch)
}
6 changes: 6 additions & 0 deletions cmd/validator_window_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ var ValidatorWindowCommand = &cli.Command{
EnvVars: []string{"DELETE_CADENCE_EPOCHS"},
DefaultText: "32",
},
&cli.IntFlag{
Name: "pool-reroll-epochs",
Usage: "Refresh t_pool_summary for the last N epochs whenever the validator->pool mapping in t_eth2_pubkeys changes, so late-tagged validators and pool renames propagate to recent history. Set to 0 to disable.",
EnvVars: []string{"POOL_REROLL_EPOCHS"},
DefaultText: "0",
},
&cli.StringFlag{
Name: "bn-endpoint",
Usage: "Beacon node endpoint (to request the Beacon States and Blocks)",
Expand Down
46 changes: 36 additions & 10 deletions docs/tables.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,12 +156,32 @@ Config: `engine = MergeTree ORDER BY f_val_idx`
| f_status | uint8 | status (see status table) |
| f_slashed | bool | whether the validator has ever been slashed or not |
| f_activation_epoch | uint64 | epoch at which the validator was activated |
| f_activation_eligibility_epoch | uint64 | epoch at which the validator became eligible for activation; `FAR_FUTURE_EPOCH` (`18446744073709551615`) means not yet eligible. Combined with `f_activation_epoch`, this splits the pre-activation queue (`f_status = 0`) into the two deposit-lifecycle states described below. |
| f_withdrawal_epoch | uint64 | epoch at which the validator can withdraw funds |
| f_exit_epoch | uint64 | epoch at which the validator exited the network |
| f_public_key | string | public key of the validator |
| f_withdrawal_prefix | uint8 | withdrawal prefix of the validator's credentials |
| f_withdrawal_credentials | text | withdrawal credentials of the validator (see below) |

## Appendix: deposit-lifecycle status vocabulary

`f_status` keeps its coarse, stable encoding (`0 in_activation_queue · 1 active · 2 exited · 3 slashed`).
Consumers that want the finer deposit-lifecycle vocabulary derive it from
`f_status` + `f_activation_eligibility_epoch` (and, for pre-registration deposits, from
`t_deposit_requests`). This is a proposed vocabulary the current Beacon API `ValidatorStatus`
enum does not provide — its `pending_initialized` / `pending_queued` predate the post-Electra
deposit pipeline (EIP-6110/EIP-7251) and there is no deposit-queue state:

| Derived status | Condition | Meaning |
| -------------- | --------- | ------- |
| `deposit_inqueue` | pubkey present in `t_deposit_requests`, absent from `t_validator_last_status` (not yet a registered validator) | Deposit waiting in `state.pending_deposits`; the real churn-limited queue |
| `pending_minBalance` | `f_status = 0` and `f_activation_eligibility_epoch = FAR_FUTURE_EPOCH` | Validator created, effective balance < 32 ETH (not yet eligible) |
| `pending_lookahead` | `f_status = 0` and `f_activation_eligibility_epoch != FAR_FUTURE_EPOCH` | Eligible; fixed `1 + MAX_SEED_LOOKAHEAD` delay (not a queue) |
| `active` / `exited` / `slashed` | `f_status` 1 / 2 / 3 | unchanged |

`deposit_inqueue` is not a `t_validator_last_status` row because the deposit has no validator index
yet; it is materialised by downstream consumers (e.g. bindeth) joining `t_deposit_requests`.

## Appendix: Reference for `f_withdrawal_prefix`

The `f_withdrawal_prefix` column indicates the type of withdrawal credentials associated with the validator. The possible values are:
Expand Down Expand Up @@ -307,18 +327,24 @@ Config: `engine = ReplacingMergeTree ORDER BY f_slot, f_index`
| f_kzg_proof | string | kzg proof of the blob |
| f_ending_0s | uint64 | amount of consecutive 0s at the end of the blob bytes |

# Blob Sidecars Events (`t_blob_sidecars_events`)
# Data Column Sidecars Events (`t_data_column_sidecars_events`)

Config: `engine = ReplacingMergeTree PARTITION BY intDiv(f_slot, 100000) ORDER BY (f_slot, f_column_index, f_block_root)`

P2P arrival timings for blob data. Since the Fulu fork (PeerDAS) blobs are no longer gossiped whole: they are erasure-coded into columns and each node custodies a subset, so beacon nodes emit `data_column_sidecar` instead of the now-dead `blob_sidecar` event. One row per **column** arrival (up to 128 per slot), which also exposes the reconstruction curve of each blob rather than a single arrival timestamp.

Blob *metadata* is unaffected and still comes from the block itself (`t_blob_sidecars`).

Config: `engine = ReplacingMergeTree ORDER BY f_arrival_timestamp_ms, f_blob_hash, f_slot`
| Column Name | Type of Data | Description | | |
| ---------------------- | ------------- | -------------------------------------------------------------- | --- | --- |
| f_arrival_timestamp_ms | uint64 | timestamp at which goteth received the data column event |
| f_slot | uint64 | slot the data column belongs to |
| f_block_root | string | block root hash |
| f_column_index | uint16 | index of the data column (0..127) |
| f_kzg_commitments | array(string) | kzg commitments of the blobs this column carries a piece of |
| f_num_commitments | uint16 | number of commitments (denormalised from the array for queries)|

| Column Name | Type of Data | Description | | |
| ---------------------- | ------------ | ------------------------------------------------- | --- | --- |
| f_arrival_timestamp_ms | uint64 | timestamp at which goteth received the blob event |
| f_blob_hash | string | hash of the blob |
| f_slot | uint64 | slot at which the blob was sent |
| f_block_root | string | block root hash |
| f_index | uint8 | index of the blob |
| f_kzg_commitment | string | kzg commitment of the blob |
> `t_blob_sidecars_events` is the pre-Fulu predecessor of this table (one row per whole blob). It can no longer receive rows because the `blob_sidecar` event is never emitted post-Fulu; migration `000038` renames it to `t_blob_sidecars_events_pre_fulu` to preserve its history.

# Block Rewards (`t_block_rewards`)

Expand Down
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func main() {
Commands: []*cli.Command{
cmd.BlocksCommand,
cmd.ValidatorWindowCommand,
cmd.PoolSummaryRefillCommand,
},
}

Expand Down
21 changes: 15 additions & 6 deletions pkg/analyzer/chain_analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package analyzer
import (
"context"
"sync"
"sync/atomic"
"time"

"github.com/attestantio/go-eth2-client/spec/phase0"
Expand Down Expand Up @@ -42,7 +43,7 @@ type ChainAnalyzer struct {
// Control Variables
wgMainRoutine *sync.WaitGroup // wait group for main routine (either historical or head)
wgDownload *sync.WaitGroup // wait group for download routine
stop bool // flag to notify all routine to finish
stop atomic.Bool // flag to notify all routine to finish (read and written from several goroutines)
routineClosed chan struct{} // signal that everything was closed succesfully
downloadMode string // whether to download historical blocks (defined by user) or follow chain head
rewardsAggregationEpochs int // number of epochs to aggregate rewards
Expand All @@ -51,12 +52,15 @@ type ChainAnalyzer struct {
metrics db.DBMetrics // what metrics to be downloaded / processed
processerBook *utils.RoutineBook // defines slot to process new metrics into the database, good for monitoring

downloadCache ChainCache // store the blocks and states downloaded
downloadCache ChainCache // store the blocks and states downloaded
validatorsRewardsAggregations map[phase0.ValidatorIndex]*spec.ValidatorRewardsAggregation
validatorsRewardsAggregationsMu sync.Mutex
advanceFinalizedMu sync.Mutex // serializes AdvanceFinalized so concurrent invocations cannot race CleanUpTo against in-flight Wait()s
advanceFinalizedMu sync.Mutex // serializes AdvanceFinalized so concurrent invocations cannot race CleanUpTo against in-flight Wait()s
handleReorgMu sync.Mutex // serializes HandleReorg so two walks cannot process the same epoch at once and leak processerBook slots (#292)
pendingReprocess map[uint64]bool // epochs whose derived rows went stale when an earlier epoch was rewritten, and that AdvanceFinalized could not reach in that invocation (#285). Guarded by advanceFinalizedMu.
reprocessAttempts map[uint64]int // how many times each pending epoch has been attempted, so a debt that cannot be paid is abandoned loudly rather than retried forever (#291). Guarded by advanceFinalizedMu.
aggregatedEpochsInWindow map[phase0.Epoch]bool // set of unique epochs aggregated in current window; prevents double-counting on reprocessing (#255)
epochBoundaryStateRoots sync.Map // slot -> phase0.Root, caches state roots from Head SSE events at epoch boundaries
epochBoundaryStateRoots sync.Map // slot -> phase0.Root, caches state roots from Head SSE events at epoch boundaries

initTime time.Time
PromMetrics *prom_metrics.PrometheusMetrics // metrics to be stored to prometheus
Expand Down Expand Up @@ -182,6 +186,7 @@ func NewChainAnalyzer(
downloadCache: NewQueue(),
validatorsRewardsAggregations: make(map[phase0.ValidatorIndex]*spec.ValidatorRewardsAggregation),
aggregatedEpochsInWindow: make(map[phase0.Epoch]bool),
pendingReprocess: make(map[uint64]bool),
processerBook: utils.NewRoutineBook(32, "processer"), // one whole epoch
wgMainRoutine: &sync.WaitGroup{},
wgDownload: &sync.WaitGroup{},
Expand Down Expand Up @@ -218,12 +223,16 @@ func (s *ChainAnalyzer) Run() {
// Block requester in finalized slots, not used for now
s.wgMainRoutine.Add(1)
go s.runHead()

// Persists data_column_sidecar arrivals in batches, off the head loop (#282).
s.wgMainRoutine.Add(1)
go s.runDataColumnSidecarsPersister()
}

s.PromMetrics.Start()

s.wgMainRoutine.Wait()
s.stop = true
s.stop.Store(true)
log.Infof("main routine finished, waiting for downloader...")

s.wgDownload.Wait()
Expand All @@ -241,7 +250,7 @@ func (s *ChainAnalyzer) Run() {

func (s *ChainAnalyzer) Close() {
log.Info("Sudden closed detected, closing StateAnalyzer")
s.stop = true
s.stop.Store(true)
s.cancel()
<-s.routineClosed // Wait for services to stop before returning
}
4 changes: 2 additions & 2 deletions pkg/analyzer/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func (s *ChainAnalyzer) DownloadBlock(slot phase0.Slot) {
newBlock, err := s.cli.RequestBeaconBlock(slot)
if err != nil {
log.Errorf("block error at slot %d: %s", slot, err)
s.stop = true
s.stop.Store(true)
s.cancel()
return
}
Expand Down Expand Up @@ -63,7 +63,7 @@ func (s *ChainAnalyzer) DownloadState(slot phase0.Slot) {

if err != nil {
log.Errorf("unable to retrieve beacon state from the beacon node, closing requester routine. %s", err.Error())
s.stop = true
s.stop.Store(true)
s.cancel()
return
}
Expand Down
Loading
Loading