From eea05fbf82c3a4da08c155b6af4012d69607b3f8 Mon Sep 17 00:00:00 2001 From: Wondertan Date: Thu, 24 Aug 2023 18:44:22 +0200 Subject: [PATCH] refactor!: make Header.Height uint64 --- header.go | 2 +- headertest/dummy_header.go | 10 +++++----- headertest/store.go | 12 ++++++------ interface.go | 4 ++-- metrics.go | 2 +- p2p/exchange_test.go | 4 ++-- p2p/server.go | 4 ++-- store/batch.go | 4 ++-- store/height_indexer.go | 2 +- store/heightsub.go | 2 +- sync/sync_head.go | 4 ++-- sync/sync_test.go | 4 ++-- verify.go | 6 +++--- 13 files changed, 30 insertions(+), 30 deletions(-) diff --git a/header.go b/header.go index 134d7a11..4f3eb53a 100644 --- a/header.go +++ b/header.go @@ -21,7 +21,7 @@ type Header[H any] interface { // Hash returns hash of a header. Hash() Hash // Height returns the height of a header. - Height() int64 + Height() uint64 // LastHeader returns the hash of last header before this header (aka. previous header hash). LastHeader() Hash // Time returns time when header was created. diff --git a/headertest/dummy_header.go b/headertest/dummy_header.go index a654d142..64d21f22 100644 --- a/headertest/dummy_header.go +++ b/headertest/dummy_header.go @@ -19,7 +19,7 @@ var ErrDummyVerify = errors.New("dummy verify error") type DummyHeader struct { Chainid string PreviousHash header.Hash - HeightI int64 + HeightI uint64 Timestamp time.Time hash header.Hash @@ -34,7 +34,7 @@ func RandDummyHeader(t *testing.T) *DummyHeader { dh := &DummyHeader{ PreviousHash: RandBytes(32), - HeightI: randInt63(), + HeightI: randUint63(), Timestamp: time.Now().UTC(), } err := dh.rehash() @@ -75,7 +75,7 @@ func (d *DummyHeader) rehash() error { return nil } -func (d *DummyHeader) Height() int64 { +func (d *DummyHeader) Height() uint64 { return d.HeightI } @@ -128,7 +128,7 @@ func RandBytes(n int) []byte { return buf } -func randInt63() int64 { +func randUint63() uint64 { var buf [8]byte _, err := rand.Read(buf[:]) @@ -136,5 +136,5 @@ func randInt63() int64 { return math.MaxInt64 } - return int64(binary.BigEndian.Uint64(buf[:]) & math.MaxInt64) + return binary.BigEndian.Uint64(buf[:]) & math.MaxInt64 } diff --git a/headertest/store.go b/headertest/store.go index 690cfc55..d3530804 100644 --- a/headertest/store.go +++ b/headertest/store.go @@ -13,8 +13,8 @@ type Generator[H header.Header[H]] interface { } type Store[H header.Header[H]] struct { - Headers map[int64]H - HeadHeight int64 + Headers map[uint64]H + HeadHeight uint64 } // NewDummyStore creates a store for DummyHeader. @@ -25,7 +25,7 @@ func NewDummyStore(t *testing.T) *Store[*DummyHeader] { // NewStore creates a generic mock store supporting different type of Headers based on Generator. func NewStore[H header.Header[H]](t *testing.T, gen Generator[H], numHeaders int) *Store[H] { store := &Store[H]{ - Headers: make(map[int64]H), + Headers: make(map[uint64]H), HeadHeight: 0, } @@ -63,7 +63,7 @@ func (m *Store[H]) Get(ctx context.Context, hash header.Hash) (H, error) { } func (m *Store[H]) GetByHeight(ctx context.Context, height uint64) (H, error) { - return m.Headers[int64(height)], nil + return m.Headers[height], nil } func (m *Store[H]) GetRangeByHeight(ctx context.Context, from, to uint64) ([]H, error) { @@ -75,7 +75,7 @@ func (m *Store[H]) GetRangeByHeight(ctx context.Context, from, to uint64) ([]H, return nil, header.ErrNotFound } for i := range headers { - headers[i] = m.Headers[int64(from)] + headers[i] = m.Headers[from] from++ } return headers, nil @@ -94,7 +94,7 @@ func (m *Store[H]) Has(context.Context, header.Hash) (bool, error) { } func (m *Store[H]) HasAt(_ context.Context, height uint64) bool { - return height != 0 && m.HeadHeight >= int64(height) + return height != 0 && m.HeadHeight >= height } func (m *Store[H]) Append(ctx context.Context, headers ...H) error { diff --git a/interface.go b/interface.go index 1d2d66fb..b7d554ed 100644 --- a/interface.go +++ b/interface.go @@ -61,8 +61,8 @@ var ( // ErrNonAdjacent is returned when Store is appended with a header not adjacent to the stored head. type ErrNonAdjacent struct { - Head int64 - Attempted int64 + Head uint64 + Attempted uint64 } func (ena *ErrNonAdjacent) Error() string { diff --git a/metrics.go b/metrics.go index 51290b6d..81f59f56 100644 --- a/metrics.go +++ b/metrics.go @@ -30,7 +30,7 @@ func WithMetrics[H Header[H]](store Store[H]) error { metric.WithAttributes( attribute.String("err", err.Error()))) } else { - observer.ObserveInt64(headC, head.Height()) + observer.ObserveInt64(headC, int64(head.Height())) } return nil } diff --git a/p2p/exchange_test.go b/p2p/exchange_test.go index ca772d8d..6b81f529 100644 --- a/p2p/exchange_test.go +++ b/p2p/exchange_test.go @@ -53,7 +53,7 @@ func TestExchange_RequestHead(t *testing.T) { tests := []struct { requestFromTrusted bool lastHeader header.Header[*headertest.DummyHeader] - expectedHeight int64 + expectedHeight uint64 expectedHash header.Hash }{ // routes to trusted peer only @@ -297,7 +297,7 @@ func Test_bestHead(t *testing.T) { } testCases := []struct { precondition func() []*headertest.DummyHeader - expectedHeight int64 + expectedHeight uint64 }{ /* Height -> Amount diff --git a/p2p/server.go b/p2p/server.go index 3c3f9f82..b304d2ce 100644 --- a/p2p/server.go +++ b/p2p/server.go @@ -175,7 +175,7 @@ func (serv *ExchangeServer[H]) handleRequestByHash(hash []byte) ([]H, error) { span.AddEvent("fetched-header-from-store", trace.WithAttributes( attribute.String("hash", header.Hash(hash).String()), - attribute.Int64("height", h.Height())), + attribute.Int64("height", int64(h.Height()))), ) span.SetStatus(codes.Ok, "") return []H{h}, nil @@ -263,7 +263,7 @@ func (serv *ExchangeServer[H]) handleHeadRequest() ([]H, error) { span.AddEvent("fetched-head", trace.WithAttributes( attribute.String("hash", head.Hash().String()), - attribute.Int64("height", head.Height())), + attribute.Int64("height", int64(head.Height()))), ) span.SetStatus(codes.Ok, "") return []H{head}, nil diff --git a/store/batch.go b/store/batch.go index 3d41f5fa..7785953f 100644 --- a/store/batch.go +++ b/store/batch.go @@ -70,7 +70,7 @@ func (b *batch[H]) getByHeight(height uint64) H { return zero } - head := uint64(b.headers[ln-1].Height()) + head := b.headers[ln-1].Height() base := head - ln if height > head || height <= base { return zero @@ -85,7 +85,7 @@ func (b *batch[H]) Append(headers ...H) { defer b.lk.Unlock() for _, h := range headers { b.headers = append(b.headers, h) - b.heights[h.Hash().String()] = uint64(h.Height()) + b.heights[h.Hash().String()] = h.Height() } } diff --git a/store/height_indexer.go b/store/height_indexer.go index e8f25fe5..7ff8306e 100644 --- a/store/height_indexer.go +++ b/store/height_indexer.go @@ -48,7 +48,7 @@ func (hi *heightIndexer[H]) HashByHeight(ctx context.Context, h uint64) (header. // IndexTo saves mapping between header Height and Hash to the given batch. func (hi *heightIndexer[H]) IndexTo(ctx context.Context, batch datastore.Batch, headers ...H) error { for _, h := range headers { - err := batch.Put(ctx, heightKey(uint64(h.Height())), h.Hash()) + err := batch.Put(ctx, heightKey(h.Height()), h.Hash()) if err != nil { return err } diff --git a/store/heightsub.go b/store/heightsub.go index b75ef83c..a69f28f6 100644 --- a/store/heightsub.go +++ b/store/heightsub.go @@ -82,7 +82,7 @@ func (hs *heightSub[H]) Pub(headers ...H) { } height := hs.Height() - from, to := uint64(headers[0].Height()), uint64(headers[ln-1].Height()) + from, to := headers[0].Height(), headers[ln-1].Height() if height+1 != from && height != 0 { // height != 0 is needed to enable init from any height and not only 1 log.Fatalf("PLEASE FILE A BUG REPORT: headers given to the heightSub are in the wrong order: expected %d, got %d", height+1, from) return diff --git a/sync/sync_head.go b/sync/sync_head.go index 7fa78d0d..8459af27 100644 --- a/sync/sync_head.go +++ b/sync/sync_head.go @@ -159,10 +159,10 @@ func (s *Syncer[H]) verify(ctx context.Context, newHead H) (bool, error) { return true, &header.VerifyError{Reason: err, SoftFailure: true} } - var heightThreshold int64 + var heightThreshold uint64 if s.Params.TrustingPeriod != 0 && s.Params.blockTime != 0 { buffer := time.Hour * 6 / s.Params.blockTime // small buffer to account for network delays - heightThreshold = int64(s.Params.TrustingPeriod/s.Params.blockTime + buffer) + heightThreshold = uint64(s.Params.TrustingPeriod/s.Params.blockTime + buffer) } err = header.Verify(sbjHead, newHead, heightThreshold) diff --git a/sync/sync_test.go b/sync/sync_test.go index 02936462..1411c0d0 100644 --- a/sync/sync_test.go +++ b/sync/sync_test.go @@ -197,7 +197,7 @@ func TestSyncPendingRangesWithMisses(t *testing.T) { lastHead, err := syncer.store.Head(ctx) require.NoError(t, err) - require.Equal(t, lastHead.Height(), int64(43)) + require.Equal(t, lastHead.Height(), uint64(43)) exp, err := remoteStore.Head(ctx) require.NoError(t, err) @@ -247,7 +247,7 @@ func TestSyncer_FindHeadersReturnsCorrectRange(t *testing.T) { head, err = syncer.store.Head(ctx) require.NoError(t, err) - assert.Equal(t, head.Height(), int64(21)) + assert.Equal(t, head.Height(), uint64(21)) } func TestSyncerIncomingDuplicate(t *testing.T) { diff --git a/verify.go b/verify.go index 13205858..0c1f3e9e 100644 --- a/verify.go +++ b/verify.go @@ -8,14 +8,14 @@ import ( // DefaultHeightThreshold defines default height threshold beyond which headers are rejected // NOTE: Compared against subjective head which is guaranteed to be non-expired -const DefaultHeightThreshold int64 = 80000 // ~ 14 days of 15 second headers +const DefaultHeightThreshold uint64 = 80000 // ~ 14 days of 15 second headers // Verify verifies untrusted Header against trusted following general Header checks and // custom user-specific checks defined in Header.Verify // // If heightThreshold is zero, uses DefaultHeightThreshold. // Always returns VerifyError. -func Verify[H Header[H]](trstd, untrstd H, heightThreshold int64) error { +func Verify[H Header[H]](trstd, untrstd H, heightThreshold uint64) error { // general mandatory verification err := verify[H](trstd, untrstd, heightThreshold) if err != nil { @@ -45,7 +45,7 @@ func Verify[H Header[H]](trstd, untrstd H, heightThreshold int64) error { // verify is a little bro of Verify yet performs mandatory Header checks // for any Header implementation. -func verify[H Header[H]](trstd, untrstd H, heightThreshold int64) error { +func verify[H Header[H]](trstd, untrstd H, heightThreshold uint64) error { if heightThreshold == 0 { heightThreshold = DefaultHeightThreshold }