Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
e4a8e2a
feat: gloas support
mattevans Mar 22, 2026
33b3fc7
feat(go.mod): update go-eth2-client dependency to include Gloas/EIP-7…
mattevans Mar 22, 2026
e7896ae
feat(beacon): add ExecutionPayloadSlotNumber to beacon block batch
mattevans Mar 22, 2026
d894cd5
feat(event): add BeaconBlockAccessList for ETH V2 event handling
mattevans Mar 23, 2026
8d92c07
chore(ci): update buf setup action to use a more recent commit SHA fo…
mattevans Mar 23, 2026
e5f523d
chore(go.mod): update ethpandaops/beacon dependency to latest version…
mattevans Mar 23, 2026
f5f8ce2
fix(go.mod): update go-ethereum to v1.17.1 and c-kzg-4844 to v2.1.6 f…
mattevans Mar 23, 2026
3c146fb
feat(docker-compose): add support for beacon block access list events…
mattevans Mar 23, 2026
fb5e988
refactor: bals structure rlp decoded
mattevans Mar 24, 2026
315f9b6
Merge pull request #796 from ethpandaops/refactor/bals-tweaks
mattevans Mar 24, 2026
f63087f
fix(vector-kafka-clickhouse.yaml): update block_number and block_hash…
mattevans Mar 24, 2026
fdd348a
chore(buf.yaml): update linting rules to exclude specific checks for …
mattevans Mar 24, 2026
0fc80fc
Merge branch 'master' into release/gloas
mattevans Mar 24, 2026
4ff67bf
feat(gloas): add BAL storage reads and bump deps to bal-devnet-3
mattevans Mar 25, 2026
689b4d3
feat(proto): introduce BlockAccessListStorageRead message for enhance…
mattevans Mar 25, 2026
eb01162
Merge pull request #797 from ethpandaops/feat/gloas-storage-read
mattevans Mar 25, 2026
3347d95
feat(block_access_list): add support for "touched" event for accounts…
mattevans Mar 25, 2026
c32a21a
Merge pull request #798 from ethpandaops/feat/gloas-acc-touched
mattevans Mar 25, 2026
eb1bd33
feat: prepare epbs types
mattevans Mar 26, 2026
de05331
Merge pull request #799 from ethpandaops/feat/epbs-types
mattevans Mar 26, 2026
44caab8
feat(migrations): add support for EIP-7732 ePBS and Gloas columns in …
mattevans Mar 26, 2026
4029caa
Merge pull request #800 from ethpandaops/feat/epbs-ch-schema
mattevans Mar 26, 2026
6a98536
feat(epbs): add server event handlers, libp2p gossipsub types, and eP…
mattevans Mar 26, 2026
f537b30
refactor(beacon_api_eth_v2_beacon_block.go, canonical_beacon_block.go…
mattevans Mar 26, 2026
181885b
feat: ebps wiring wip
mattevans Mar 26, 2026
fb2b3b3
feat(beacon): add event names for various beacon API events to handle…
mattevans Mar 26, 2026
f0c3f84
feat: ebps wiring wip
mattevans Mar 26, 2026
12d9c0d
feat: ebps wiring wip
mattevans Mar 26, 2026
360c568
feat: ebps wiring wip
mattevans Mar 26, 2026
98b171c
Merge pull request #801 from ethpandaops/feat/epbs-wiring-pt1
mattevans Mar 29, 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
2 changes: 1 addition & 1 deletion .github/workflows/buf.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0

- name: Set up buf
uses: bufbuild/buf-setup-action@a47c93e0b1648769eb9a2e1f98e7b4e3e13089f0 # v1.50.0
uses: bufbuild/buf-setup-action@a47c93e0b1648d5651a065437926377d060baa99 # v1.50.0

- name: Lint protos
run: buf lint
Expand Down
17 changes: 17 additions & 0 deletions deploy/local/docker-compose/vector-http-kafka.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ transforms:
eth_v2_beacon_block_v2: .event.name == "BEACON_API_ETH_V2_BEACON_BLOCK_V2"
eth_v2_beacon_block_voluntary_exit: .event.name == "BEACON_API_ETH_V2_BEACON_BLOCK_VOLUNTARY_EXIT"
eth_v2_beacon_block_withdrawal: .event.name == "BEACON_API_ETH_V2_BEACON_BLOCK_WITHDRAWAL"
eth_v2_beacon_block_access_list: .event.name == "BEACON_API_ETH_V2_BEACON_BLOCK_ACCESS_LIST"
eth_v2_beacon_block: .event.name == "BEACON_API_ETH_V2_BEACON_BLOCK"
mempool_transaction_v2: .event.name == "MEMPOOL_TRANSACTION_V2"
mempool_transaction: .event.name == "MEMPOOL_TRANSACTION"
Expand Down Expand Up @@ -763,6 +764,22 @@ sinks:
enabled: true
encoding:
codec: json
beacon_api_eth_v2_beacon_block_access_list_kafka:
type: kafka
buffer:
max_events: 500000
batch:
timeout_secs: 0.5
inputs:
- xatu_server_events_router.eth_v2_beacon_block_access_list
bootstrap_servers: "${KAFKA_BROKERS}"
key_field: "event.id"
topic: beacon-api-eth-v2-beacon-block-access-list
compression: snappy
healthcheck:
enabled: true
encoding:
codec: json
beacon_api_eth_v1_beacon_blob_sidecar_kafka:
type: kafka
buffer:
Expand Down
60 changes: 60 additions & 0 deletions deploy/local/docker-compose/vector-kafka-clickhouse.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,7 @@ transforms:
canonical_beacon_block_voluntary_exit: .event.name == "BEACON_API_ETH_V2_BEACON_BLOCK_VOLUNTARY_EXIT"
canonical_beacon_validators: .event.name == "BEACON_API_ETH_V1_BEACON_VALIDATORS"
canonical_beacon_block_withdrawal: .event.name == "BEACON_API_ETH_V2_BEACON_BLOCK_WITHDRAWAL"
canonical_beacon_block_access_list: .event.name == "BEACON_API_ETH_V2_BEACON_BLOCK_ACCESS_LIST"
canonical_beacon_block: .event.name == "BEACON_API_ETH_V2_BEACON_BLOCK_V2" && .meta.client.additional_data.finalized_when_requested == true
canonical_beacon_proposer_duty: .event.name == "BEACON_API_ETH_V1_PROPOSER_DUTY" && .meta.client.additional_data.state_id == "finalized"
canonical_beacon_committee: .event.name == "BEACON_API_ETH_V1_BEACON_COMMITTEE" && .meta.client.additional_data.state_id == "finalized"
Expand Down Expand Up @@ -480,6 +481,7 @@ transforms:
- xatu_server_events_router.canonical_beacon_block_proposer_slashing
- xatu_server_events_router.canonical_beacon_block_voluntary_exit
- xatu_server_events_router.canonical_beacon_block_withdrawal
- xatu_server_events_router.canonical_beacon_block_access_list
- xatu_server_events_router.canonical_beacon_proposer_duty
- xatu_server_events_router.canonical_beacon_committee
- xatu_server_events_router.eth_v1_beacon_committee
Expand Down Expand Up @@ -1207,6 +1209,7 @@ transforms:
.execution_payload_base_fee_per_gas = .data.message.body.execution_payload.base_fee_per_gas
.execution_payload_blob_gas_used = .data.message.body.execution_payload.blob_gas_used
.execution_payload_excess_blob_gas = .data.message.body.execution_payload.excess_blob_gas
.execution_payload_slot_number = .data.message.body.execution_payload.slot_number
.execution_payload_gas_limit = .data.message.body.execution_payload.gas_limit
.execution_payload_gas_used = .data.message.body.execution_payload.gas_used
.execution_payload_state_root = .data.message.body.execution_payload.state_root
Expand Down Expand Up @@ -1278,6 +1281,7 @@ transforms:
.execution_payload_base_fee_per_gas = .data.message.body.execution_payload.base_fee_per_gas
.execution_payload_blob_gas_used = .data.message.body.execution_payload.blob_gas_used
.execution_payload_excess_blob_gas = .data.message.body.execution_payload.excess_blob_gas
.execution_payload_slot_number = .data.message.body.execution_payload.slot_number
.execution_payload_gas_limit = .data.message.body.execution_payload.gas_limit
.execution_payload_gas_used = .data.message.body.execution_payload.gas_used
.execution_payload_state_root = .data.message.body.execution_payload.state_root
Expand Down Expand Up @@ -1557,6 +1561,41 @@ transforms:
del(.event)
del(.meta)
del(.data)
canonical_beacon_block_access_list_formatted:
type: remap
inputs:
- xatu_server_events_router.canonical_beacon_block_access_list
source: |-
.slot = .meta.client.additional_data.block.slot.number
slot_start_date_time, err = parse_timestamp(.meta.client.additional_data.block.slot.start_date_time, format: "%+");
if err == null {
.slot_start_date_time = to_unix_timestamp(slot_start_date_time)
} else {
.error = err
.error_description = "failed to parse slot start date time"
log(., level: "error", rate_limit_secs: 60)
}
.epoch = .meta.client.additional_data.block.epoch.number
epoch_start_date_time, err = parse_timestamp(.meta.client.additional_data.block.epoch.start_date_time, format: "%+");
if err == null {
.epoch_start_date_time = to_unix_timestamp(epoch_start_date_time)
} else {
.error = err
.error_description = "failed to parse epoch start date time"
log(., level: "error", rate_limit_secs: 60)
}
.block_root = .meta.client.additional_data.block.root
.block_number = .meta.client.additional_data.blockNumber
.block_hash = .meta.client.additional_data.blockHash
.address = .data.address
.change_type = .data.change_type
.block_access_index = .data.block_access_index
.storage_key = .data.storage_key
.new_value = .data.new_value
.updated_date_time = to_unix_timestamp(now())
del(.event)
del(.meta)
del(.data)
canonical_beacon_blob_sidecar_formatted:
type: remap
inputs:
Expand Down Expand Up @@ -2313,6 +2352,7 @@ transforms:
.execution_payload_base_fee_per_gas = .data.message.body.execution_payload.base_fee_per_gas
.execution_payload_blob_gas_used = .data.message.body.execution_payload.blob_gas_used
.execution_payload_excess_blob_gas = .data.message.body.execution_payload.excess_blob_gas
.execution_payload_slot_number = .data.message.body.execution_payload.slot_number
.execution_payload_gas_limit = .data.message.body.execution_payload.gas_limit
.execution_payload_gas_used = .data.message.body.execution_payload.gas_used
.execution_payload_transactions_count = .meta.client.additional_data.transactions_count
Expand Down Expand Up @@ -3508,6 +3548,26 @@ sinks:
healthcheck:
enabled: true
skip_unknown_fields: false
canonical_beacon_block_access_list_clickhouse:
type: clickhouse
inputs:
- canonical_beacon_block_access_list_formatted
database: default
endpoint: "${CLICKHOUSE_ENDPOINT}"
table: canonical_beacon_block_access_list
auth:
strategy: basic
user: "${CLICKHOUSE_USER}"
password: "${CLICKHOUSE_PASSWORD}"
batch:
max_bytes: 52428800
max_events: 200000
timeout_secs: 1
buffer:
max_events: 200000
healthcheck:
enabled: true
skip_unknown_fields: false
canonical_beacon_blob_sidecar_clickhouse:
type: clickhouse
inputs:
Expand Down
1 change: 1 addition & 0 deletions deploy/local/docker-compose/xatu-server.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ services:
- BEACON_API_ETH_V2_BEACON_BLOCK_VOLUNTARY_EXIT
- BEACON_API_ETH_V2_BEACON_BLOCK_DEPOSIT
- BEACON_API_ETH_V2_BEACON_BLOCK_WITHDRAWAL
- BEACON_API_ETH_V2_BEACON_BLOCK_ACCESS_LIST
- BEACON_API_ETH_V2_BEACON_BLOCK_ELABORATED_ATTESTATION
- BEACON_API_ETH_V2_BEACON_BLOCK
- BEACON_API_ETH_V2_BEACON_BLOCK_V2
Expand Down
19 changes: 19 additions & 0 deletions deploy/migrations/clickhouse/106_gloas_bals_support.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
-- Drop canonical_beacon_block_access_list tables
DROP TABLE IF EXISTS default.canonical_beacon_block_access_list ON CLUSTER '{cluster}';
DROP TABLE IF EXISTS default.canonical_beacon_block_access_list_local ON CLUSTER '{cluster}';

-- Remove columns from canonical_beacon_block
ALTER TABLE default.canonical_beacon_block ON CLUSTER '{cluster}'
DROP COLUMN IF EXISTS execution_payload_block_access_list_root,
DROP COLUMN IF EXISTS execution_payload_slot_number;

ALTER TABLE default.canonical_beacon_block_local ON CLUSTER '{cluster}'
DROP COLUMN IF EXISTS execution_payload_block_access_list_root,
DROP COLUMN IF EXISTS execution_payload_slot_number;

-- Remove columns from beacon_api_eth_v2_beacon_block
ALTER TABLE default.beacon_api_eth_v2_beacon_block ON CLUSTER '{cluster}'
DROP COLUMN IF EXISTS execution_payload_slot_number;

ALTER TABLE default.beacon_api_eth_v2_beacon_block_local ON CLUSTER '{cluster}'
DROP COLUMN IF EXISTS execution_payload_slot_number;
63 changes: 63 additions & 0 deletions deploy/migrations/clickhouse/106_gloas_bals_support.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
-- Add execution_payload_slot_number to beacon_api_eth_v2_beacon_block
ALTER TABLE default.beacon_api_eth_v2_beacon_block_local ON CLUSTER '{cluster}'
ADD COLUMN IF NOT EXISTS execution_payload_slot_number Nullable(UInt64)
CODEC(DoubleDelta, ZSTD(1)) AFTER execution_payload_excess_blob_gas;

ALTER TABLE default.beacon_api_eth_v2_beacon_block ON CLUSTER '{cluster}'
ADD COLUMN IF NOT EXISTS execution_payload_slot_number Nullable(UInt64)
CODEC(DoubleDelta, ZSTD(1)) AFTER execution_payload_excess_blob_gas;

-- Add execution_payload_slot_number and execution_payload_block_access_list_root to canonical_beacon_block
ALTER TABLE default.canonical_beacon_block_local ON CLUSTER '{cluster}'
ADD COLUMN IF NOT EXISTS execution_payload_slot_number Nullable(UInt64)
CODEC(DoubleDelta, ZSTD(1)) AFTER execution_payload_excess_blob_gas,
ADD COLUMN IF NOT EXISTS execution_payload_block_access_list_root Nullable(FixedString(66))
CODEC(ZSTD(1)) AFTER execution_payload_slot_number;

ALTER TABLE default.canonical_beacon_block ON CLUSTER '{cluster}'
ADD COLUMN IF NOT EXISTS execution_payload_slot_number Nullable(UInt64)
CODEC(DoubleDelta, ZSTD(1)) AFTER execution_payload_excess_blob_gas,
ADD COLUMN IF NOT EXISTS execution_payload_block_access_list_root Nullable(FixedString(66))
CODEC(ZSTD(1)) AFTER execution_payload_slot_number;

-- Create canonical_beacon_block_access_list table
CREATE TABLE IF NOT EXISTS default.canonical_beacon_block_access_list_local ON CLUSTER '{cluster}' (
updated_date_time DateTime CODEC(DoubleDelta, ZSTD(1)),
slot UInt32 CODEC(DoubleDelta, ZSTD(1)),
slot_start_date_time DateTime CODEC(DoubleDelta, ZSTD(1)),
epoch UInt32 CODEC(DoubleDelta, ZSTD(1)),
epoch_start_date_time DateTime CODEC(DoubleDelta, ZSTD(1)),
block_root FixedString(66) CODEC(ZSTD(1)),
block_number UInt64 CODEC(DoubleDelta, ZSTD(1)),
block_hash FixedString(66) CODEC(ZSTD(1)),
address FixedString(42) CODEC(ZSTD(1)),
change_type LowCardinality(String) CODEC(ZSTD(1)),
block_access_index UInt16 CODEC(DoubleDelta, ZSTD(1)),
storage_key FixedString(66) CODEC(ZSTD(1)),
new_value Nullable(String) CODEC(ZSTD(1)),
meta_client_name LowCardinality(String) CODEC(ZSTD(1)),
meta_client_id String CODEC(ZSTD(1)),
meta_client_version LowCardinality(String) CODEC(ZSTD(1)),
meta_client_implementation LowCardinality(String) CODEC(ZSTD(1)),
meta_client_os LowCardinality(String) CODEC(ZSTD(1)),
meta_client_ip Nullable(IPv6) CODEC(ZSTD(1)),
meta_client_geo_city LowCardinality(String) CODEC(ZSTD(1)),
meta_client_geo_country LowCardinality(String) CODEC(ZSTD(1)),
meta_client_geo_country_code LowCardinality(String) CODEC(ZSTD(1)),
meta_client_geo_continent_code LowCardinality(String) CODEC(ZSTD(1)),
meta_client_geo_longitude Nullable(Float64) CODEC(ZSTD(1)),
meta_client_geo_latitude Nullable(Float64) CODEC(ZSTD(1)),
meta_client_geo_autonomous_system_number Nullable(UInt32) CODEC(ZSTD(1)),
meta_client_geo_autonomous_system_organization Nullable(String) CODEC(ZSTD(1)),
meta_network_id Int32 CODEC(DoubleDelta, ZSTD(1)),
meta_network_name LowCardinality(String) CODEC(ZSTD(1)),
meta_consensus_version LowCardinality(String) CODEC(ZSTD(1)),
meta_consensus_implementation LowCardinality(String) CODEC(ZSTD(1)),
meta_labels Map(String, String) CODEC(ZSTD(1))
) ENGINE = ReplicatedReplacingMergeTree(updated_date_time)
PARTITION BY toStartOfMonth(slot_start_date_time)
ORDER BY (slot_start_date_time, meta_network_name, block_hash, address, change_type, storage_key, block_access_index);

CREATE TABLE IF NOT EXISTS default.canonical_beacon_block_access_list ON CLUSTER '{cluster}'
AS default.canonical_beacon_block_access_list_local
ENGINE = Distributed('{cluster}', default, canonical_beacon_block_access_list_local, rand());
74 changes: 74 additions & 0 deletions deploy/migrations/clickhouse/107_gloas_epbs_support.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
-- Reverse EIP-7732 ePBS support

-- Drop new tables
DROP TABLE IF EXISTS default.canonical_beacon_block_payload_attestation ON CLUSTER '{cluster}';
DROP TABLE IF EXISTS default.canonical_beacon_block_payload_attestation_local ON CLUSTER '{cluster}';

DROP TABLE IF EXISTS default.canonical_beacon_block_execution_payload_bid ON CLUSTER '{cluster}';
DROP TABLE IF EXISTS default.canonical_beacon_block_execution_payload_bid_local ON CLUSTER '{cluster}';

DROP TABLE IF EXISTS default.beacon_api_eth_v1_events_execution_payload ON CLUSTER '{cluster}';
DROP TABLE IF EXISTS default.beacon_api_eth_v1_events_execution_payload_local ON CLUSTER '{cluster}';

DROP TABLE IF EXISTS default.beacon_api_eth_v1_events_payload_attestation ON CLUSTER '{cluster}';
DROP TABLE IF EXISTS default.beacon_api_eth_v1_events_payload_attestation_local ON CLUSTER '{cluster}';

DROP TABLE IF EXISTS default.beacon_api_eth_v1_events_execution_payload_bid ON CLUSTER '{cluster}';
DROP TABLE IF EXISTS default.beacon_api_eth_v1_events_execution_payload_bid_local ON CLUSTER '{cluster}';

DROP TABLE IF EXISTS default.beacon_api_eth_v1_events_proposer_preferences ON CLUSTER '{cluster}';
DROP TABLE IF EXISTS default.beacon_api_eth_v1_events_proposer_preferences_local ON CLUSTER '{cluster}';

DROP TABLE IF EXISTS default.libp2p_gossipsub_execution_payload_envelope ON CLUSTER '{cluster}';
DROP TABLE IF EXISTS default.libp2p_gossipsub_execution_payload_envelope_local ON CLUSTER '{cluster}';

DROP TABLE IF EXISTS default.libp2p_gossipsub_execution_payload_bid ON CLUSTER '{cluster}';
DROP TABLE IF EXISTS default.libp2p_gossipsub_execution_payload_bid_local ON CLUSTER '{cluster}';

DROP TABLE IF EXISTS default.libp2p_gossipsub_payload_attestation_message ON CLUSTER '{cluster}';
DROP TABLE IF EXISTS default.libp2p_gossipsub_payload_attestation_message_local ON CLUSTER '{cluster}';

DROP TABLE IF EXISTS default.libp2p_gossipsub_proposer_preferences ON CLUSTER '{cluster}';
DROP TABLE IF EXISTS default.libp2p_gossipsub_proposer_preferences_local ON CLUSTER '{cluster}';

-- Remove ePBS columns from beacon block tables
ALTER TABLE default.canonical_beacon_block ON CLUSTER '{cluster}'
DROP COLUMN IF EXISTS payload_present,
DROP COLUMN IF EXISTS execution_payment,
DROP COLUMN IF EXISTS bid_value,
DROP COLUMN IF EXISTS builder_index;

ALTER TABLE default.canonical_beacon_block_local ON CLUSTER '{cluster}'
DROP COLUMN IF EXISTS payload_present,
DROP COLUMN IF EXISTS execution_payment,
DROP COLUMN IF EXISTS bid_value,
DROP COLUMN IF EXISTS builder_index;

ALTER TABLE default.beacon_api_eth_v2_beacon_block ON CLUSTER '{cluster}'
DROP COLUMN IF EXISTS payload_present,
DROP COLUMN IF EXISTS execution_payment,
DROP COLUMN IF EXISTS bid_value,
DROP COLUMN IF EXISTS builder_index;

ALTER TABLE default.beacon_api_eth_v2_beacon_block_local ON CLUSTER '{cluster}'
DROP COLUMN IF EXISTS payload_present,
DROP COLUMN IF EXISTS execution_payment,
DROP COLUMN IF EXISTS bid_value,
DROP COLUMN IF EXISTS builder_index;

-- Remove Gloas columns from DataColumnSidecar tables
ALTER TABLE default.beacon_api_eth_v1_events_data_column_sidecar ON CLUSTER '{cluster}'
DROP COLUMN IF EXISTS sidecar_beacon_block_root,
DROP COLUMN IF EXISTS sidecar_slot;

ALTER TABLE default.beacon_api_eth_v1_events_data_column_sidecar_local ON CLUSTER '{cluster}'
DROP COLUMN IF EXISTS sidecar_beacon_block_root,
DROP COLUMN IF EXISTS sidecar_slot;

ALTER TABLE default.libp2p_gossipsub_data_column_sidecar ON CLUSTER '{cluster}'
DROP COLUMN IF EXISTS sidecar_beacon_block_root,
DROP COLUMN IF EXISTS sidecar_slot;

ALTER TABLE default.libp2p_gossipsub_data_column_sidecar_local ON CLUSTER '{cluster}'
DROP COLUMN IF EXISTS sidecar_beacon_block_root,
DROP COLUMN IF EXISTS sidecar_slot;
Loading
Loading