Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
83939d1
release: gloas support
mattevans Mar 23, 2026
5e1c4bf
chore(go.mod): replace dependency on github.com/attestantio/go-eth2-c…
mattevans Mar 23, 2026
7b1d6d7
chore(api.go): remove inline gosec comment for cleaner code readabili…
mattevans Mar 23, 2026
f64d291
chore(go.mod): update dependencies to latest versions for improved st…
mattevans Mar 24, 2026
72e6019
chore(deps): update github.com/ethereum/go-ethereum to v1.17.2-0.2026…
mattevans Mar 25, 2026
4de46d1
chore(deps): migrate go-eth2-client to ethpandaops fork v0.0.1
barnabasbusa Apr 14, 2026
3e4108d
Merge pull request #70 from ethpandaops/chore/use-ethpandaops-go-eth2…
mattevans Apr 16, 2026
bdc1647
fix(go.mod): update go-eth2-client and dynamic-ssz dependencies to la…
mattevans May 7, 2026
3a57d83
feat: ePBS SSE subs
mattevans May 7, 2026
7101e4f
feat(metrics): introduce constants for metrics labels to improve code…
mattevans May 7, 2026
b31a645
Merge pull request #71 from ethpandaops/feat/epbs-sse-events
mattevans May 7, 2026
0260912
Merge branch 'master' into release/gloas
mattevans May 13, 2026
da13b89
chore(api.go): add inline comment to suppress golint warnings for ope…
mattevans May 14, 2026
ddfa770
chore(deps): bump go-ethereum to bal-devnet-6
mattevans May 14, 2026
81b9ef3
Merge branch 'master' into release/gloas
mattevans May 14, 2026
ec67108
Merge branch 'master' into release/gloas
mattevans May 28, 2026
90e7e6a
Merge branch 'master' into release/gloas
mattevans May 28, 2026
e36edcd
feat: deliver flat execution_payload / _gossip events
samcm Jul 8, 2026
77f719e
Merge pull request #78 from ethpandaops/feat/flat-exec-payload
samcm Jul 8, 2026
da5e1aa
feat: subscribe to and deliver head_v2 events
samcm Jul 12, 2026
fcdf565
Merge pull request #79 from ethpandaops/feat/head-v2
samcm Jul 12, 2026
b2498eb
feat: fetch raw signed execution payload envelopes
samcm Jul 16, 2026
1de3961
feat: typed ErrNotFound for 404 responses from raw endpoints
samcm Jul 16, 2026
b274ec0
Merge pull request #80 from ethpandaops/feat/raw-execution-payload-en…
samcm Jul 16, 2026
116daa7
feat(beacon): stream raw API responses
Savid Jul 29, 2026
9f32aa9
Merge pull request #81 from ethpandaops/feat/raw-streaming
Savid Aug 10, 2026
8d66ce6
Revert "Merge pull request #81 from ethpandaops/feat/raw-streaming"
Savid Aug 10, 2026
882506c
feat(beacon): add streaming raw API responses
Savid Aug 10, 2026
77db92c
Merge pull request #82 from ethpandaops/feat/raw-streaming-reland
Savid Aug 17, 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
8 changes: 8 additions & 0 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ jobs:
- name: run tests
run: go test -json ./... > test.json

- name: run bounded-memory acceptance tests
run: |
go test -tags acceptance ./pkg/beacon/api -run Acceptance -count=1 -timeout=20m
go test -tags "acceptance acceptance_http2" ./pkg/beacon/api -run TestAcceptanceConcurrentHTTP2BeaconStateStreams -count=1 -timeout=20m

- name: run race tests
run: go test -race ./...

- name: Annotate tests
if: always()
uses: guyarb/golang-test-annotations@96fc379b171c49932041d6c789e73331a7bdeec1 # v0.9.0
Expand Down
4 changes: 4 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
version: "2"
run:
build-tags:
- acceptance
- acceptance_full_buffered
- acceptance_http2
issues-exit-code: 1
linters:
default: none
Expand Down
41 changes: 40 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ As a general rule, any function that starts with `Fetch` will fetch data from th

## Built with

- [attestantio/go-eth2-client](github.com/attestantio/go-eth2-client)
- [attestantio/go-eth2-client](github.com/ethpandaops/go-eth2-client)
- [ethpandaops/ethwallclock](github.com/ethpandaops/ethwallclock)

## Options
Expand All @@ -27,6 +27,45 @@ go get github.com/ethpandaops/beacon

## Usage

### Streaming raw responses

The `OpenRaw*` methods return after the node accepts the request and sends response headers. The caller must close the response and treat any later read error as a failed transfer.

```go
func archiveState(ctx context.Context, node beacon.Node, dst io.Writer) error {
response, err := node.OpenRawBeaconState(ctx, "finalized", "application/octet-stream")
if err != nil {
return err
}
defer response.Close()

mediaType, _, err := mime.ParseMediaType(response.ContentType)
if err != nil || mediaType != "application/octet-stream" {
return fmt.Errorf("unexpected content type %q", response.ContentType)
}

written, err := io.Copy(dst, response)
if err != nil {
return err
}
if response.ContentLength >= 0 && written != response.ContentLength {
return fmt.Errorf("copied %d bytes, expected %d", written, response.ContentLength)
}

return nil
}
```

The request context and configured raw API client timeout both govern body reads. The raw client settings apply to both `FetchRaw*` and `OpenRaw*` calls; set `SetAPIClientTimeout(0)` only when every call has a suitable context deadline. By default the raw client permits 32 active response bodies and 32 connections per host; `MaxConcurrentRequests` also caps multiplexed HTTP/2 streams.

Go may transparently decompress gzip responses, reported by `RawResponse.Uncompressed`. Call `Options.SetAPIClientAcceptEncoding("gzip")` when the caller needs the encoded wire bytes; the returned headers then retain `Content-Encoding`. A `ContentLength` of `-1` means the caller cannot verify an expected byte count from that field. Slow readers keep upstream resources open, so applications should bound concurrency and finish downstream writes before committing their output.

Maintainers can run the streaming memory gates with `go test -tags acceptance ./pkg/beacon/api -run Acceptance -count=1`. The full 50-response buffered comparison requires at least 10 GiB of available memory and is intentionally manual:

```bash
go test -tags "acceptance acceptance_full_buffered" ./pkg/beacon/api -run TestAcceptanceFullBufferedBaseline -count=1 -timeout=20m
```

### Simple example

```go
Expand Down
30 changes: 16 additions & 14 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ go 1.26.1

require (
github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9
github.com/ethereum/go-ethereum v1.16.4
github.com/ethereum/go-ethereum v1.17.3-0.20260507223249-73944e329925
github.com/ethpandaops/ethwallclock v0.2.0
github.com/ethpandaops/go-eth2-client v0.1.3-0.20260513062559-5fb497ba414f
github.com/ethpandaops/go-eth2-client v0.1.7-0.20260712074542-bca0dce49005
github.com/go-co-op/gocron v1.16.2
github.com/prometheus/client_golang v1.23.2
github.com/prometheus/client_model v0.6.2
Expand All @@ -18,40 +18,42 @@ require (

require (
github.com/OffchainLabs/go-bitfield v0.0.0-20251031151322-f427d04d8506 // indirect
github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/casbin/govaluate v1.10.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
github.com/go-logr/logr v1.2.4 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/goccy/go-yaml v1.19.2 // indirect
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
github.com/golang/snappy v1.0.0 // indirect
github.com/holiman/uint256 v1.3.2 // indirect
github.com/huandu/go-clone v1.6.0 // indirect
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pk910/dynamic-ssz v1.3.2-0.20260505131440-111bcb265c8f // indirect
github.com/pk910/hashtree-bindings v0.1.0 // indirect
github.com/pk910/dynamic-ssz v1.3.2 // indirect
github.com/pk910/hashtree-bindings v0.2.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/common v0.66.1 // indirect
github.com/prometheus/procfs v0.16.1 // indirect
github.com/r3labs/sse/v2 v2.10.0 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect
go.opentelemetry.io/otel v1.16.0 // indirect
go.opentelemetry.io/otel/metric v1.16.0 // indirect
go.opentelemetry.io/otel/trace v1.16.0 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.opentelemetry.io/otel v1.40.0 // indirect
go.opentelemetry.io/otel/metric v1.40.0 // indirect
go.opentelemetry.io/otel/trace v1.40.0 // indirect
go.yaml.in/yaml/v2 v2.4.2 // indirect
golang.org/x/crypto v0.42.0 // indirect
golang.org/x/net v0.44.0 // indirect
golang.org/x/sync v0.17.0 // indirect
golang.org/x/sys v0.36.0 // indirect
golang.org/x/crypto v0.47.0 // indirect
golang.org/x/net v0.49.0 // indirect
golang.org/x/sync v0.19.0 // indirect
golang.org/x/sys v0.40.0 // indirect
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
google.golang.org/protobuf v1.36.8 // indirect
google.golang.org/protobuf v1.36.11 // indirect
gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading