@@ -24,15 +24,15 @@ const (
24
24
25
25
// BlockTracker is an interface to track new blocks on the chain
26
26
type BlockTracker struct {
27
- config * Config
28
- blocks [] * ethgo. Block
29
- blocksLock sync. Mutex
30
- subscriber BlockTrackerInterface
31
- blockChs [] chan * BlockEvent
32
- blockChsLock sync. Mutex
33
- provider BlockProvider
34
- once sync. Once
35
- closeCh chan struct {}
27
+ config * Config
28
+
29
+ blocks [] * ethgo. Block
30
+ lock sync. Mutex
31
+ tracker BlockTrackerInterface
32
+ provider BlockProvider
33
+
34
+ eventBroker * EventBroker
35
+ closeCh chan struct {}
36
36
}
37
37
38
38
type Config struct {
@@ -69,85 +69,43 @@ func NewBlockTracker(provider BlockProvider, opts ...ConfigOption) *BlockTracker
69
69
if tracker == nil {
70
70
tracker = NewJSONBlockTracker (log .New (os .Stderr , "" , log .LstdFlags ), provider )
71
71
}
72
- return & BlockTracker {
73
- blocks : []* ethgo.Block {},
74
- blockChs : []chan * BlockEvent {},
75
- config : config ,
76
- subscriber : tracker ,
77
- provider : provider ,
78
- closeCh : make (chan struct {}),
79
- }
80
- }
81
-
82
- func (b * BlockTracker ) Subscribe () chan * BlockEvent {
83
- b .blockChsLock .Lock ()
84
- defer b .blockChsLock .Unlock ()
85
-
86
- ch := make (chan * BlockEvent , 1 )
87
- b .blockChs = append (b .blockChs , ch )
88
- return ch
89
- }
90
-
91
- func (b * BlockTracker ) AcquireLock () Lock {
92
- return Lock {lock : & b .blocksLock }
93
- }
94
-
95
- func (t * BlockTracker ) Init () (err error ) {
96
- var block * ethgo.Block
97
- t .once .Do (func () {
98
- block , err = t .provider .GetBlockByNumber (ethgo .Latest , false )
99
- if err != nil {
100
- return
101
- }
102
- if block .Number == 0 {
103
- return
104
- }
105
-
106
- blocks := make ([]* ethgo.Block , t .config .MaxBlockBacklog )
107
72
108
- var i uint64
109
- for i = 0 ; i < t .config .MaxBlockBacklog ; i ++ {
110
- blocks [t .config .MaxBlockBacklog - i - 1 ] = block
111
- if block .Number == 0 {
112
- break
113
- }
114
- block , err = t .provider .GetBlockByHash (block .ParentHash , false )
115
- if err != nil {
116
- return
117
- }
118
- }
73
+ broker , err := NewEventBroker (context .Background (), EventBrokerCfg {})
74
+ if err != nil {
75
+ panic (err )
76
+ }
119
77
120
- if i != t .config .MaxBlockBacklog {
121
- // less than maxBacklog elements
122
- blocks = blocks [t .config .MaxBlockBacklog - i - 1 :]
123
- }
124
- t .blocks = blocks
125
- })
126
- return err
127
- }
78
+ initial , err := provider .GetBlockByNumber (ethgo .Latest , false )
79
+ if err != nil {
80
+ panic (err )
81
+ }
128
82
129
- func (b * BlockTracker ) MaxBlockBacklog () uint64 {
130
- return b .config .MaxBlockBacklog
131
- }
83
+ b := & BlockTracker {
84
+ blocks : []* ethgo.Block {},
85
+ config : config ,
86
+ tracker : tracker ,
87
+ provider : provider ,
88
+ eventBroker : broker ,
89
+ closeCh : make (chan struct {}),
90
+ }
132
91
133
- func (b * BlockTracker ) LastBlocked () * ethgo.Block {
134
- target := b .blocks [len (b .blocks )- 1 ]
135
- if target == nil {
136
- return nil
92
+ // add an initial block
93
+ if err := b .HandleReconcile (initial ); err != nil {
94
+ panic (err )
137
95
}
138
- return target . Copy ()
96
+ return b
139
97
}
140
98
141
- func ( b * BlockTracker ) BlocksBlocked () [] * ethgo. Block {
142
- res := [] * ethgo.Block {}
143
- for _ , i := range b . blocks {
144
- res = append ( res , i . Copy () )
145
- }
146
- return res
99
+ // Header returns the last block of the tracked chain
100
+ func ( b * BlockTracker ) Header () * ethgo.Block {
101
+ b . lock . Lock ()
102
+ last := b . blocks [ len ( b . blocks ) - 1 ]. Copy ()
103
+ b . lock . Unlock ()
104
+ return last
147
105
}
148
106
149
- func (b * BlockTracker ) Len () int {
150
- return len ( b . blocks )
107
+ func (b * BlockTracker ) Subscribe () * Subscription {
108
+ return b . eventBroker . Subscribe ( )
151
109
}
152
110
153
111
func (b * BlockTracker ) Close () error {
@@ -162,7 +120,7 @@ func (b *BlockTracker) Start() error {
162
120
cancelFn ()
163
121
}()
164
122
// start the polling
165
- err := b .subscriber .Track (ctx , func (block * ethgo.Block ) error {
123
+ err := b .tracker .Track (ctx , func (block * ethgo.Block ) error {
166
124
return b .HandleReconcile (block )
167
125
})
168
126
if err != nil {
@@ -171,7 +129,7 @@ func (b *BlockTracker) Start() error {
171
129
return err
172
130
}
173
131
174
- func (t * BlockTracker ) AddBlockLocked (block * ethgo.Block ) error {
132
+ func (t * BlockTracker ) addBlocks (block * ethgo.Block ) error {
175
133
if uint64 (len (t .blocks )) == t .config .MaxBlockBacklog {
176
134
// remove past blocks if there are more than maxReconcileBlocks
177
135
t .blocks = t .blocks [1 :]
@@ -225,7 +183,7 @@ func (t *BlockTracker) handleReconcileImpl(block *ethgo.Block) ([]*ethgo.Block,
225
183
count := uint64 (0 )
226
184
for {
227
185
if count > t .config .MaxBlockBacklog {
228
- return nil , - 1 , fmt .Errorf ("cannot reconcile more than max backlog values" )
186
+ return nil , - 1 , fmt .Errorf ("cannot reconcile more than '%d' max backlog values" , t . config . MaxBlockBacklog )
229
187
}
230
188
count ++
231
189
@@ -250,8 +208,8 @@ func (t *BlockTracker) handleReconcileImpl(block *ethgo.Block) ([]*ethgo.Block,
250
208
}
251
209
252
210
func (t * BlockTracker ) HandleBlockEvent (block * ethgo.Block ) (* BlockEvent , error ) {
253
- t .blocksLock .Lock ()
254
- defer t .blocksLock .Unlock ()
211
+ t .lock .Lock ()
212
+ defer t .lock .Unlock ()
255
213
256
214
blocks , indx , err := t .handleReconcileImpl (block )
257
215
if err != nil {
@@ -274,7 +232,7 @@ func (t *BlockTracker) HandleBlockEvent(block *ethgo.Block) (*BlockEvent, error)
274
232
// include the new blocks
275
233
for _ , block := range blocks {
276
234
blockEvnt .Added = append (blockEvnt .Added , block )
277
- if err := t .AddBlockLocked (block ); err != nil {
235
+ if err := t .addBlocks (block ); err != nil {
278
236
return nil , err
279
237
}
280
238
}
@@ -290,15 +248,7 @@ func (t *BlockTracker) HandleReconcile(block *ethgo.Block) error {
290
248
return nil
291
249
}
292
250
293
- t .blockChsLock .Lock ()
294
- for _ , ch := range t .blockChs {
295
- select {
296
- case ch <- blockEvnt :
297
- default :
298
- }
299
- }
300
- t .blockChsLock .Unlock ()
301
-
251
+ t .eventBroker .Publish (blockEvnt )
302
252
return nil
303
253
}
304
254
@@ -409,41 +359,12 @@ func (s *SubscriptionBlockTracker) Track(ctx context.Context, handle func(block
409
359
return nil
410
360
}
411
361
412
- type Lock struct {
413
- Locked bool
414
- lock * sync.Mutex
415
- }
416
-
417
- func (l * Lock ) Lock () {
418
- l .Locked = true
419
- l .lock .Lock ()
420
- }
421
-
422
- func (l * Lock ) Unlock () {
423
- l .Locked = false
424
- l .lock .Unlock ()
425
- }
426
-
427
- // EventType is the type of the event
428
- type EventType int
429
-
430
- const (
431
- // EventAdd happens when a new event is included in the chain
432
- EventAdd EventType = iota
433
- // EventDel may happen when there is a reorg and a past event is deleted
434
- EventDel
435
- )
436
-
437
- // Event is an event emitted when a new log is included
438
- type Event struct {
439
- Type EventType
440
- Added []* ethgo.Log
441
- Removed []* ethgo.Log
442
- }
443
-
444
362
// BlockEvent is an event emitted when a new block is included
445
363
type BlockEvent struct {
446
- Type EventType
447
364
Added []* ethgo.Block
448
365
Removed []* ethgo.Block
449
366
}
367
+
368
+ func (b * BlockEvent ) Header () * ethgo.Block {
369
+ return b .Added [len (b .Added )- 1 ]
370
+ }
0 commit comments