Skip to content
This repository has been archived by the owner on Dec 4, 2024. It is now read-only.

Commit

Permalink
one more change
Browse files Browse the repository at this point in the history
  • Loading branch information
igorcrevar committed Sep 19, 2023
1 parent 093e701 commit 6c0bc6e
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 108 deletions.
95 changes: 19 additions & 76 deletions tracker/blocktracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ type BlockTracker struct {
blockChsLock sync.Mutex
provider bt.BlockProvider
closeCh chan struct{}
once sync.Once
logger hclog.Logger
}

Expand Down Expand Up @@ -65,16 +64,15 @@ func NewBlockTracker(provider bt.BlockProvider, logger hclog.Logger, opts ...Con
}

return &BlockTracker{
blocks: []*ethgo.Block{},
blockChs: []chan *bt.BlockEvent{},
blocks: nil,
blockChs: nil,
config: config,
subscriber: tracker,
provider: provider,
closeCh: make(chan struct{}),
logger: logger,
blocksLock: sync.Mutex{},
blockChsLock: sync.Mutex{},
once: sync.Once{},
}
}

Expand All @@ -93,63 +91,19 @@ func (t *BlockTracker) AcquireLock() bt.Lock {
}

func (t *BlockTracker) Init() error {
var (
block *ethgo.Block
err error
i uint64
)

t.once.Do(func() {
block, err = t.provider.GetBlockByNumber(ethgo.Latest, false)
if err != nil {
return
}

if block.Number == 0 {
return
}

blocks := make([]*ethgo.Block, t.config.MaxBlockBacklog)

for i = 0; i < t.config.MaxBlockBacklog; i++ {
blocks[t.config.MaxBlockBacklog-i-1] = block
if block.Number == 0 {
break
}

block, err = t.provider.GetBlockByHash(block.ParentHash, false)
if err != nil {
return
} else if block == nil {
// if block does not exist (for example reorg happened) GetBlockByHash will return nil, nil
err = fmt.Errorf("block with hash %s not found", block.ParentHash)

return
}
}

if i != t.config.MaxBlockBacklog {
// less than maxBacklog elements
blocks = blocks[t.config.MaxBlockBacklog-i-1:]
}

t.blocks = blocks
})

return err
return nil
}

func (t *BlockTracker) MaxBlockBacklog() uint64 {
return t.config.MaxBlockBacklog
}

func (t *BlockTracker) LastBlocked() *ethgo.Block {
target := t.blocks[len(t.blocks)-1]
if target == nil {
if len(t.blocks) == 0 {
return nil
}

return target.Copy()
return t.blocks[len(t.blocks)-1].Copy()
}

func (t *BlockTracker) BlocksBlocked() []*ethgo.Block {
Expand Down Expand Up @@ -212,13 +166,8 @@ func (t *BlockTracker) blockAtIndex(hash ethgo.Hash) int {
}

func (t *BlockTracker) handleReconcileImpl(block *ethgo.Block) ([]*ethgo.Block, int, error) {
// The state is empty
if len(t.blocks) == 0 {
return []*ethgo.Block{block}, -1, nil
}

// Append to the head of the chain
if t.blocks[len(t.blocks)-1].Hash == block.ParentHash {
if len(t.blocks) > 0 && t.blocks[len(t.blocks)-1].Hash == block.ParentHash {
return []*ethgo.Block{block}, -1, nil
}

Expand All @@ -227,38 +176,34 @@ func (t *BlockTracker) handleReconcileImpl(block *ethgo.Block) ([]*ethgo.Block,
return nil, indx + 1, nil
}

// Fork in the middle of the chain
if indx := t.blockAtIndex(block.ParentHash); indx != -1 {
return []*ethgo.Block{block}, indx + 1, nil
}

// Backfill. We dont know the parent of the block.
// Need to query the chain until we find a known block
var (
added = []*ethgo.Block{block}
count uint64 = 0
indx int
indx = 0 // if indx stays 0 - it means remove all from the current state
err error
)

for ; count < t.config.MaxBlockBacklog; count++ {
hash := block.ParentHash
for ; count < t.config.MaxBlockBacklog && block.Number > 1; count++ {
parentHash := block.ParentHash

// if there is a parent at some index, break loop and update from where should we delete
if indx = t.blockAtIndex(parentHash); indx != -1 {
indx++

break
}

block, err = t.provider.GetBlockByHash(hash, false)
block, err = t.provider.GetBlockByHash(parentHash, false)
if err != nil {
return nil, -1, fmt.Errorf("parent with hash retrieving error: %w", err)
} else if block == nil {
// if block does not exist (for example reorg happened) GetBlockByHash will return nil, nil
return nil, -1, fmt.Errorf("parent with hash %s not found", hash)
return nil, -1, fmt.Errorf("parent with hash %s not found", parentHash)
}

added = append(added, block)

if indx = t.blockAtIndex(block.ParentHash); indx != -1 {
indx++

break
}
}

// need the blocks in reverse order
Expand All @@ -268,8 +213,6 @@ func (t *BlockTracker) handleReconcileImpl(block *ethgo.Block) ([]*ethgo.Block,
}

if count == t.config.MaxBlockBacklog {
indx = 0 // remove all from the current state

t.logger.Info("reconcile did not found parent for new blocks", "hash", added[0].Hash)
}

Expand All @@ -292,7 +235,7 @@ func (t *BlockTracker) HandleBlockEvent(block *ethgo.Block) (*bt.BlockEvent, err
blockEvnt := &bt.BlockEvent{}

// there are some blocks to remove
if indx >= 0 {
if indx >= 0 && indx < len(t.blocks) {
for i := indx; i < len(t.blocks); i++ {
blockEvnt.Removed = append(blockEvnt.Removed, t.blocks[i])
}
Expand Down
32 changes: 0 additions & 32 deletions tracker/blocktracker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,38 +10,6 @@ import (
"github.com/umbracle/ethgo/testutil"
)

func TestBlockTracker_PopulateBlocks(t *testing.T) {
t.Parallel()

// more than maxBackLog blocks
{
l := testutil.MockList{}
l.Create(0, 15, func(b *testutil.MockBlock) {})

m := &testutil.MockClient{}
m.AddScenario(l)

tt0 := NewBlockTracker(m, hclog.NewNullLogger())

require.NoError(t, tt0.Init())
require.True(t, testutil.CompareBlocks(l.ToBlocks()[5:], tt0.blocks))
}
// less than maxBackLog
{
l0 := testutil.MockList{}
l0.Create(0, 5, func(b *testutil.MockBlock) {})

m1 := &testutil.MockClient{}
m1.AddScenario(l0)

tt1 := NewBlockTracker(m1, hclog.NewNullLogger())
tt1.provider = m1

require.NoError(t, tt1.Init())
require.True(t, testutil.CompareBlocks(l0.ToBlocks(), tt1.blocks))
}
}

func TestBlockTracker_Events(t *testing.T) {
t.Parallel()

Expand Down

0 comments on commit 6c0bc6e

Please sign in to comment.