Skip to content

Commit

Permalink
implement block time calculator
Browse files Browse the repository at this point in the history
  • Loading branch information
envestcc committed Oct 27, 2023
1 parent 65833f7 commit 524c6ef
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 0 deletions.
43 changes: 43 additions & 0 deletions pkg/util/blockutil/block_time_calculator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package blockutil

import "time"

type (
// BlockTimeCalculator calculates block time of a given height.
BlockTimeCalculator struct {
getBlockInterval getBlockIntervalFn
getTipHeight getTipHeightFn
getHistoryBlockTime getHistoryblockTimeFn
}

getBlockIntervalFn func(uint64) time.Duration
getTipHeightFn func() uint64
getHistoryblockTimeFn func(uint64) (time.Time, error)
)

// NewBlockTimeCalculator creates a new BlockTimeCalculator.
func NewBlockTimeCalculator(getBlockInterval getBlockIntervalFn, getTipHeight getTipHeightFn, getHistoryBlockTime getHistoryblockTimeFn) *BlockTimeCalculator {
return &BlockTimeCalculator{
getBlockInterval: getBlockInterval,
getTipHeight: getTipHeight,
getHistoryBlockTime: getHistoryBlockTime,
}
}

// CalculateBlockTime returns the block time of the given height.
// If the height is in the future, it will predict the block time according to the tip block time and interval.
// If the height is in the past, it will get the block time from indexer.
func (btc *BlockTimeCalculator) CalculateBlockTime(height uint64) (time.Time, error) {
// get block time from indexer if height is in the past
tipHeight := btc.getTipHeight()
if height <= tipHeight {
return btc.getHistoryBlockTime(height)
}

// predict block time according to tip block time and interval
tipBlockTime, err := btc.getHistoryBlockTime(tipHeight)
if err != nil {
return time.Time{}, err
}
return tipBlockTime.Add(time.Duration(height-tipHeight) * btc.getBlockInterval(height)), nil
}
46 changes: 46 additions & 0 deletions pkg/util/blockutil/block_time_calculator_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package blockutil

import (
"testing"
"time"

"github.com/stretchr/testify/require"
)

func TestBlockTimeCalculator_CalculateBlockTime(t *testing.T) {
r := require.New(t)
interval := 5 * time.Second
intervalFn := func(h uint64) time.Duration {
return 5 * time.Second
}
tipHeight := uint64(100)
tipHeightF := func() uint64 { return tipHeight }
baseTime, err := time.Parse("2006-01-02T15:04:05.000Z", "2022-01-01T00:00:00.000Z")
r.NoError(err)
historyBlockTimeF := func(height uint64) (time.Time, error) { return baseTime.Add(time.Hour * time.Duration(height)), nil }
btc := NewBlockTimeCalculator(intervalFn, tipHeightF, historyBlockTimeF)

historyWrapper := func(height uint64) time.Time {
t, err := historyBlockTimeF(height)
r.NoError(err)
return t
}
cases := []struct {
name string
height uint64
want time.Time
}{
{"height is in the past", tipHeight - 1, historyWrapper(tipHeight - 1)},
{"height is in the past I", tipHeight, historyWrapper(tipHeight)},
{"height is in the future", tipHeight + 1, historyWrapper(tipHeight).Add(interval)},
{"height is in the future I", tipHeight + 2, historyWrapper(tipHeight).Add(2 * interval)},
}

for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
got, err := btc.CalculateBlockTime(c.height)
r.NoError(err)
r.Equal(c.want, got)
})
}
}

0 comments on commit 524c6ef

Please sign in to comment.