@@ -4,10 +4,12 @@ package sse
44
55import (
66 "context"
7+ "encoding/hex"
78 "encoding/json"
89 "math"
910 "net/http"
1011 "strconv"
12+ "strings"
1113 "sync"
1214 "time"
1315
@@ -22,19 +24,19 @@ import (
2224
2325type (
2426 ChainReorgEventHandlerFunc func (ctx context.Context , epoch eth2p0.Epoch )
25- BlockEventHandlerFunc func (ctx context.Context , slot eth2p0.Slot , bnAddr string )
27+ HeadEventHandlerFunc func (ctx context.Context , slot eth2p0.Slot , blockRoot eth2p0. Root , bnAddr string )
2628)
2729
2830type Listener interface {
2931 SubscribeChainReorgEvent (ChainReorgEventHandlerFunc )
30- SubscribeBlockEvent ( BlockEventHandlerFunc )
32+ SubscribeHeadEvent ( HeadEventHandlerFunc )
3133}
3234
3335type listener struct {
3436 sync.Mutex
3537
3638 chainReorgSubs []ChainReorgEventHandlerFunc
37- blockSubs [] BlockEventHandlerFunc
39+ headSubs [] HeadEventHandlerFunc
3840 lastReorgEpoch eth2p0.Epoch
3941
4042 // blockGossipTimes stores timestamps of block gossip events per slot and beacon node address
@@ -64,7 +66,7 @@ func StartListener(ctx context.Context, eth2Cl eth2wrap.Client, addresses, heade
6466
6567 l := & listener {
6668 chainReorgSubs : make ([]ChainReorgEventHandlerFunc , 0 ),
67- blockSubs : make ([]BlockEventHandlerFunc , 0 ),
69+ headSubs : make ([]HeadEventHandlerFunc , 0 ),
6870 blockGossipTimes : make (map [uint64 ]map [string ]time.Time ),
6971 genesisTime : genesisTime ,
7072 slotDuration : slotDuration ,
@@ -105,11 +107,11 @@ func (p *listener) SubscribeChainReorgEvent(handler ChainReorgEventHandlerFunc)
105107 p .chainReorgSubs = append (p .chainReorgSubs , handler )
106108}
107109
108- func (p * listener ) SubscribeBlockEvent (handler BlockEventHandlerFunc ) {
110+ func (p * listener ) SubscribeHeadEvent (handler HeadEventHandlerFunc ) {
109111 p .Lock ()
110112 defer p .Unlock ()
111113
112- p .blockSubs = append (p .blockSubs , handler )
114+ p .headSubs = append (p .headSubs , handler )
113115}
114116
115117func (p * listener ) eventHandler (ctx context.Context , event * event , addr string ) error {
@@ -167,6 +169,13 @@ func (p *listener) handleHeadEvent(ctx context.Context, event *event, addr strin
167169 z .Str ("prev_ddr" , head .PreviousDutyDependentRoot ),
168170 z .Str ("curr_ddr" , head .CurrentDutyDependentRoot ))
169171
172+ blockRoot , err := parseRoot (head .Block )
173+ if err != nil {
174+ return errors .Wrap (err , "parse head block root" , z .Str ("addr" , addr ))
175+ }
176+
177+ p .notifyHeadEvent (ctx , eth2p0 .Slot (slot ), blockRoot , addr )
178+
170179 return nil
171180}
172181
@@ -270,8 +279,6 @@ func (p *listener) handleBlockEvent(ctx context.Context, event *event, addr stri
270279
271280 sseBlockHistogram .WithLabelValues (addr ).Observe (delay .Seconds ())
272281
273- p .notifyBlockEvent (ctx , eth2p0 .Slot (slot ), addr )
274-
275282 return nil
276283}
277284
@@ -289,15 +296,32 @@ func (p *listener) notifyChainReorg(ctx context.Context, epoch eth2p0.Epoch) {
289296 }
290297}
291298
292- func (p * listener ) notifyBlockEvent (ctx context.Context , slot eth2p0.Slot , bnAddr string ) {
299+ func (p * listener ) notifyHeadEvent (ctx context.Context , slot eth2p0.Slot , blockRoot eth2p0. Root , bnAddr string ) {
293300 p .Lock ()
294301 defer p .Unlock ()
295302
296- for _ , sub := range p .blockSubs {
297- sub (ctx , slot , bnAddr )
303+ for _ , sub := range p .headSubs {
304+ sub (ctx , slot , blockRoot , bnAddr )
298305 }
299306}
300307
308+ // parseRoot parses a 0x-prefixed hex string into an eth2p0.Root.
309+ func parseRoot (hexRoot string ) (eth2p0.Root , error ) {
310+ b , err := hex .DecodeString (strings .TrimPrefix (hexRoot , "0x" ))
311+ if err != nil {
312+ return eth2p0.Root {}, errors .Wrap (err , "decode hex root" )
313+ }
314+
315+ var root eth2p0.Root
316+ if len (b ) != len (root ) {
317+ return eth2p0.Root {}, errors .New ("invalid root length" , z .Int ("length" , len (b )))
318+ }
319+
320+ copy (root [:], b )
321+
322+ return root , nil
323+ }
324+
301325// computeDelay computes the delay between start of the slot and receiving the event.
302326func (p * listener ) computeDelay (slot uint64 , eventTS time.Time , delayOKFunc func (delay time.Duration ) bool ) (time.Duration , bool ) {
303327 slotStartTime := p .genesisTime .Add (time .Duration (slot ) * p .slotDuration )
0 commit comments