diff --git a/go.mod b/go.mod index 8f89460..3a27d53 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9 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.6-0.20260708061330-ed85bf5c3bab + 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 diff --git a/go.sum b/go.sum index 4fccb5b..f214d7c 100644 --- a/go.sum +++ b/go.sum @@ -24,6 +24,8 @@ github.com/ethpandaops/ethwallclock v0.2.0 h1:EeFKtZ7v6TAdn/oAh0xaPujD7N4amjBxrW github.com/ethpandaops/ethwallclock v0.2.0/go.mod h1:y0Cu+mhGLlem19vnAV2x0hpFS5KZ7oOi2SWYayv9l24= github.com/ethpandaops/go-eth2-client v0.1.6-0.20260708061330-ed85bf5c3bab h1:lOnMzC2Oyzd+hJ0BOH1HXXYou1jMnlX2dVsP8vztX7U= github.com/ethpandaops/go-eth2-client v0.1.6-0.20260708061330-ed85bf5c3bab/go.mod h1:97Oq3omOQSGPPYgrbsOIIw2Pc4T5Ph21f8ZRyHJQBHU= +github.com/ethpandaops/go-eth2-client v0.1.7-0.20260712074542-bca0dce49005 h1:hN4nugJUYn/O1Or4cW8jBYJBgCCrIGeMU2bXbpKWInU= +github.com/ethpandaops/go-eth2-client v0.1.7-0.20260712074542-bca0dce49005/go.mod h1:97Oq3omOQSGPPYgrbsOIIw2Pc4T5Ph21f8ZRyHJQBHU= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= diff --git a/pkg/beacon/beacon.go b/pkg/beacon/beacon.go index 8d98a15..277f6e6 100644 --- a/pkg/beacon/beacon.go +++ b/pkg/beacon/beacon.go @@ -124,6 +124,8 @@ type Node interface { OnFinalizedCheckpoint(ctx context.Context, handler func(ctx context.Context, ev *v1.FinalizedCheckpointEvent) error) // OnHead is called when the head is received. OnHead(ctx context.Context, handler func(ctx context.Context, ev *v1.HeadEvent) error) + // OnHeadV2 is called when a head_v2 event (gloas) is received. + OnHeadV2(ctx context.Context, handler func(ctx context.Context, ev *v1.HeadEventV2) error) // OnChainReOrg is called when a chain reorg is received. OnChainReOrg(ctx context.Context, handler func(ctx context.Context, ev *v1.ChainReorgEvent) error) // OnVoluntaryExit is called when a voluntary exit is received. diff --git a/pkg/beacon/event.go b/pkg/beacon/event.go index 0afe8ce..d1e511a 100644 --- a/pkg/beacon/event.go +++ b/pkg/beacon/event.go @@ -57,6 +57,7 @@ const ( topicExecutionPayloadGossip = "execution_payload_gossip" topicPayloadAttestationMessage = "payload_attestation_message" topicProposerPreferences = "proposer_preferences" + topicHeadV2 = "head_v2" ) type ReadyEvent struct { diff --git a/pkg/beacon/publisher.go b/pkg/beacon/publisher.go index 6b36202..2cf82f1 100644 --- a/pkg/beacon/publisher.go +++ b/pkg/beacon/publisher.go @@ -43,6 +43,10 @@ func (n *node) publishHead(ctx context.Context, event *v1.HeadEvent) { n.broker.Emit(topicHead, event) } +func (n *node) publishHeadV2(ctx context.Context, event *v1.HeadEventV2) { + n.broker.Emit(topicHeadV2, event) +} + func (n *node) publishVoluntaryExit(ctx context.Context, event *phase0.SignedVoluntaryExit) { n.broker.Emit(topicVoluntaryExit, event) } diff --git a/pkg/beacon/subscriber.go b/pkg/beacon/subscriber.go index b991004..6279504 100644 --- a/pkg/beacon/subscriber.go +++ b/pkg/beacon/subscriber.go @@ -60,6 +60,12 @@ func (n *node) OnHead(ctx context.Context, handler func(ctx context.Context, eve }) } +func (n *node) OnHeadV2(ctx context.Context, handler func(ctx context.Context, event *v1.HeadEventV2) error) { + n.broker.On(topicHeadV2, func(event *v1.HeadEventV2) { + n.handleSubscriberError(handler(ctx, event), topicHeadV2) + }) +} + func (n *node) OnVoluntaryExit(ctx context.Context, handler func(ctx context.Context, event *phase0.SignedVoluntaryExit) error) { n.broker.On(topicVoluntaryExit, func(event *phase0.SignedVoluntaryExit) { n.handleSubscriberError(handler(ctx, event), topicVoluntaryExit) diff --git a/pkg/beacon/subscriptions.go b/pkg/beacon/subscriptions.go index af33464..0d460d9 100644 --- a/pkg/beacon/subscriptions.go +++ b/pkg/beacon/subscriptions.go @@ -95,6 +95,8 @@ func (n *node) handleEvent(ctx context.Context, event *v1.Event) error { return n.handleFinalizedCheckpoint(ctx, event) case topicHead: return n.handleHead(ctx, event) + case topicHeadV2: + return n.handleHeadV2(ctx, event) case topicVoluntaryExit: return n.handleVoluntaryExit(ctx, event) case topicContributionAndProof: @@ -200,6 +202,17 @@ func (n *node) handleFinalizedCheckpoint(ctx context.Context, event *v1.Event) e return nil } +func (n *node) handleHeadV2(ctx context.Context, event *v1.Event) error { + head, valid := event.Data.(*v1.HeadEventV2) + if !valid { + return errors.New("invalid head_v2 event") + } + + n.publishHeadV2(ctx, head) + + return nil +} + func (n *node) handleHead(ctx context.Context, event *v1.Event) error { head, valid := event.Data.(*v1.HeadEvent) if !valid {