Skip to content

Commit e851d7f

Browse files
committed
Major scaffolding
1 parent d753735 commit e851d7f

26 files changed

+2005
-2244
lines changed

blocktracker/blocktracker.go renamed to block-tracker/blocktracker.go

Lines changed: 48 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@ const (
2424

2525
// BlockTracker is an interface to track new blocks on the chain
2626
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{}
3636
}
3737

3838
type Config struct {
@@ -69,85 +69,43 @@ func NewBlockTracker(provider BlockProvider, opts ...ConfigOption) *BlockTracker
6969
if tracker == nil {
7070
tracker = NewJSONBlockTracker(log.New(os.Stderr, "", log.LstdFlags), provider)
7171
}
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)
10772

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+
}
11977

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+
}
12882

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+
}
13291

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)
13795
}
138-
return target.Copy()
96+
return b
13997
}
14098

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
147105
}
148106

149-
func (b *BlockTracker) Len() int {
150-
return len(b.blocks)
107+
func (b *BlockTracker) Subscribe() *Subscription {
108+
return b.eventBroker.Subscribe()
151109
}
152110

153111
func (b *BlockTracker) Close() error {
@@ -162,7 +120,7 @@ func (b *BlockTracker) Start() error {
162120
cancelFn()
163121
}()
164122
// 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 {
166124
return b.HandleReconcile(block)
167125
})
168126
if err != nil {
@@ -171,7 +129,7 @@ func (b *BlockTracker) Start() error {
171129
return err
172130
}
173131

174-
func (t *BlockTracker) AddBlockLocked(block *ethgo.Block) error {
132+
func (t *BlockTracker) addBlocks(block *ethgo.Block) error {
175133
if uint64(len(t.blocks)) == t.config.MaxBlockBacklog {
176134
// remove past blocks if there are more than maxReconcileBlocks
177135
t.blocks = t.blocks[1:]
@@ -225,7 +183,7 @@ func (t *BlockTracker) handleReconcileImpl(block *ethgo.Block) ([]*ethgo.Block,
225183
count := uint64(0)
226184
for {
227185
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)
229187
}
230188
count++
231189

@@ -250,8 +208,8 @@ func (t *BlockTracker) handleReconcileImpl(block *ethgo.Block) ([]*ethgo.Block,
250208
}
251209

252210
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()
255213

256214
blocks, indx, err := t.handleReconcileImpl(block)
257215
if err != nil {
@@ -274,7 +232,7 @@ func (t *BlockTracker) HandleBlockEvent(block *ethgo.Block) (*BlockEvent, error)
274232
// include the new blocks
275233
for _, block := range blocks {
276234
blockEvnt.Added = append(blockEvnt.Added, block)
277-
if err := t.AddBlockLocked(block); err != nil {
235+
if err := t.addBlocks(block); err != nil {
278236
return nil, err
279237
}
280238
}
@@ -290,15 +248,7 @@ func (t *BlockTracker) HandleReconcile(block *ethgo.Block) error {
290248
return nil
291249
}
292250

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)
302252
return nil
303253
}
304254

@@ -409,41 +359,12 @@ func (s *SubscriptionBlockTracker) Track(ctx context.Context, handle func(block
409359
return nil
410360
}
411361

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-
444362
// BlockEvent is an event emitted when a new block is included
445363
type BlockEvent struct {
446-
Type EventType
447364
Added []*ethgo.Block
448365
Removed []*ethgo.Block
449366
}
367+
368+
func (b *BlockEvent) Header() *ethgo.Block {
369+
return b.Added[len(b.Added)-1]
370+
}

blocktracker/blocktracker_test.go renamed to block-tracker/blocktracker_test.go

Lines changed: 10 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
package blocktracker
22

3+
/*
34
import (
45
"context"
56
"log"
67
"os"
78
"testing"
89
"time"
910
10-
"github.com/stretchr/testify/assert"
11-
"github.com/umbracle/ethgo"
12-
"github.com/umbracle/ethgo/jsonrpc"
13-
"github.com/umbracle/ethgo/testutil"
11+
web3 "github.com/umbracle/go-web3"
12+
"github.com/umbracle/go-web3/jsonrpc"
13+
"github.com/umbracle/go-web3/testutil"
1414
)
1515
1616
func testListener(t *testing.T, server *testutil.TestServer, tracker BlockTrackerInterface) {
1717
ctx, cancelFn := context.WithCancel(context.Background())
1818
defer cancelFn()
1919
20-
blocks := make(chan *ethgo.Block)
21-
err := tracker.Track(ctx, func(block *ethgo.Block) error {
20+
blocks := make(chan *web3.Block)
21+
err := tracker.Track(ctx, func(block *web3.Block) error {
2222
blocks <- block
2323
return nil
2424
})
@@ -83,11 +83,10 @@ func TestBlockTracker_Lifecycle(t *testing.T) {
8383
8484
c, _ := jsonrpc.NewClient(s.HTTPAddr())
8585
tr := NewBlockTracker(c.Eth())
86-
assert.NoError(t, tr.Init())
8786
8887
go tr.Start()
8988
90-
sub := tr.Subscribe()
89+
sub := tr.Subscribe().GetEventCh()
9190
for i := 0; i < 10; i++ {
9291
select {
9392
case <-sub:
@@ -97,46 +96,6 @@ func TestBlockTracker_Lifecycle(t *testing.T) {
9796
}
9897
}
9998
100-
func TestBlockTracker_PopulateBlocks(t *testing.T) {
101-
// more than maxBackLog blocks
102-
{
103-
l := testutil.MockList{}
104-
l.Create(0, 15, func(b *testutil.MockBlock) {})
105-
106-
m := &testutil.MockClient{}
107-
m.AddScenario(l)
108-
109-
tt0 := NewBlockTracker(m)
110-
111-
err := tt0.Init()
112-
if err != nil {
113-
t.Fatal(err)
114-
}
115-
if !testutil.CompareBlocks(l.ToBlocks()[5:], tt0.blocks) {
116-
t.Fatal("bad")
117-
}
118-
}
119-
// less than maxBackLog
120-
{
121-
l0 := testutil.MockList{}
122-
l0.Create(0, 5, func(b *testutil.MockBlock) {})
123-
124-
m1 := &testutil.MockClient{}
125-
m1.AddScenario(l0)
126-
127-
tt1 := NewBlockTracker(m1)
128-
tt1.provider = m1
129-
130-
err := tt1.Init()
131-
if err != nil {
132-
panic(err)
133-
}
134-
if !testutil.CompareBlocks(l0.ToBlocks(), tt1.blocks) {
135-
t.Fatal("bad")
136-
}
137-
}
138-
}
139-
14099
func TestBlockTracker_Events(t *testing.T) {
141100
142101
type TestEvent struct {
@@ -336,10 +295,10 @@ func TestBlockTracker_Events(t *testing.T) {
336295
337296
// build past block history
338297
for _, b := range c.History.ToBlocks() {
339-
tt.AddBlockLocked(b)
298+
tt.addBlocks(b)
340299
}
341300
342-
sub := tt.Subscribe()
301+
sub := tt.Subscribe().GetEventCh()
343302
for _, b := range c.Reconcile {
344303
if err := tt.HandleReconcile(b.block.Block()); err != nil {
345304
t.Fatal(err)
@@ -370,3 +329,4 @@ func TestBlockTracker_Events(t *testing.T) {
370329
})
371330
}
372331
}
332+
*/

0 commit comments

Comments
 (0)