Skip to content

Commit fb62d4e

Browse files
authored
feat(header)!: introduce header.Header interface (#1304)
Most important changes in this PR: * `tmbytes.HexBytes` replaced by `header.Hash` * `header.Header` used in interfaces in `header` package * `IsBefore` inlined, so we don't need to include this method in interface (it's a oneliner used once) * `VerifyNonAdjacent` added to `Header` interface (at least for now) * Generics introduced to avoid casting Resolves evstack/ev-node#575.
1 parent c559ab7 commit fb62d4e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1527
-1083
lines changed

header/core/exchange.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@ import (
88
"github.com/ipfs/go-blockservice"
99
logging "github.com/ipfs/go-log/v2"
1010

11-
tmbytes "github.com/tendermint/tendermint/libs/bytes"
12-
1311
"github.com/celestiaorg/celestia-node/core"
1412
"github.com/celestiaorg/celestia-node/header"
13+
libhead "github.com/celestiaorg/celestia-node/libs/header"
1514
)
1615

1716
var log = logging.Logger("header/core")
@@ -57,7 +56,7 @@ func (ce *Exchange) GetRangeByHeight(ctx context.Context, from, amount uint64) (
5756

5857
func (ce *Exchange) GetVerifiedRange(ctx context.Context, from *header.ExtendedHeader, amount uint64,
5958
) ([]*header.ExtendedHeader, error) {
60-
headers, err := ce.GetRangeByHeight(ctx, uint64(from.Height)+1, amount)
59+
headers, err := ce.GetRangeByHeight(ctx, uint64(from.Height())+1, amount)
6160
if err != nil {
6261
return nil, err
6362
}
@@ -72,7 +71,7 @@ func (ce *Exchange) GetVerifiedRange(ctx context.Context, from *header.ExtendedH
7271
return headers, nil
7372
}
7473

75-
func (ce *Exchange) Get(ctx context.Context, hash tmbytes.HexBytes) (*header.ExtendedHeader, error) {
74+
func (ce *Exchange) Get(ctx context.Context, hash libhead.Hash) (*header.ExtendedHeader, error) {
7675
log.Debugw("requesting header", "hash", hash.String())
7776
block, err := ce.fetcher.GetBlockByHash(ctx, hash)
7877
if err != nil {

header/core/listener.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010

1111
"github.com/celestiaorg/celestia-node/core"
1212
"github.com/celestiaorg/celestia-node/header"
13+
libhead "github.com/celestiaorg/celestia-node/libs/header"
1314
)
1415

1516
// Listener is responsible for listening to Core for
@@ -20,15 +21,15 @@ import (
2021
// broadcasts the new `ExtendedHeader` to the header-sub gossipsub
2122
// network.
2223
type Listener struct {
23-
bcast header.Broadcaster
24+
bcast libhead.Broadcaster[*header.ExtendedHeader]
2425
fetcher *core.BlockFetcher
2526
bServ blockservice.BlockService
2627
construct header.ConstructFn
2728
cancel context.CancelFunc
2829
}
2930

3031
func NewListener(
31-
bcast header.Broadcaster,
32+
bcast libhead.Broadcaster[*header.ExtendedHeader],
3233
fetcher *core.BlockFetcher,
3334
bServ blockservice.BlockService,
3435
construct header.ConstructFn,
@@ -98,7 +99,7 @@ func (cl *Listener) listen(ctx context.Context, sub <-chan *types.Block) {
9899
// broadcast new ExtendedHeader, but if core is still syncing, notify only local subscribers
99100
err = cl.bcast.Broadcast(ctx, eh, pubsub.WithLocalPublication(syncing))
100101
if err != nil {
101-
log.Errorw("listener: broadcasting next header", "height", eh.Height,
102+
log.Errorw("listener: broadcasting next header", "height", eh.Height(),
102103
"err", err)
103104
}
104105
case <-ctx.Done():

header/core/listener_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414

1515
"github.com/celestiaorg/celestia-node/core"
1616
"github.com/celestiaorg/celestia-node/header"
17-
"github.com/celestiaorg/celestia-node/header/p2p"
17+
"github.com/celestiaorg/celestia-node/libs/header/p2p"
1818
)
1919

2020
// TestListener tests the lifecycle of the core listener.
@@ -94,7 +94,7 @@ func createListener(
9494
fetcher *core.BlockFetcher,
9595
ps *pubsub.PubSub,
9696
) *Listener {
97-
p2pSub := p2p.NewSubscriber(ps)
97+
p2pSub := p2p.NewSubscriber[*header.ExtendedHeader](ps, header.MsgID)
9898
err := p2pSub.Start(ctx)
9999
require.NoError(t, err)
100100
t.Cleanup(func() {

header/header.go

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,33 @@ import (
55
"context"
66
"encoding/json"
77
"fmt"
8+
"time"
89

910
"github.com/ipfs/go-blockservice"
1011
logging "github.com/ipfs/go-log/v2"
1112

12-
bts "github.com/tendermint/tendermint/libs/bytes"
1313
amino "github.com/tendermint/tendermint/libs/json"
1414
core "github.com/tendermint/tendermint/types"
1515

1616
appshares "github.com/celestiaorg/celestia-app/pkg/shares"
1717

1818
"github.com/celestiaorg/celestia-app/pkg/da"
1919

20+
libhead "github.com/celestiaorg/celestia-node/libs/header"
2021
"github.com/celestiaorg/celestia-node/share"
2122
)
2223

2324
var log = logging.Logger("header")
2425

26+
// ConstructFn aliases a function that creates an ExtendedHeader.
27+
type ConstructFn = func(
28+
context.Context,
29+
*core.Block,
30+
*core.Commit,
31+
*core.ValidatorSet,
32+
blockservice.BlockService,
33+
) (*ExtendedHeader, error)
34+
2535
type DataAvailabilityHeader = da.DataAvailabilityHeader
2636

2737
// EmptyDAH provides DAH of the empty block.
@@ -42,6 +52,28 @@ type ExtendedHeader struct {
4252
DAH *DataAvailabilityHeader `json:"dah"`
4353
}
4454

55+
func (eh *ExtendedHeader) New() libhead.Header {
56+
return new(ExtendedHeader)
57+
}
58+
59+
func (eh *ExtendedHeader) IsZero() bool {
60+
return eh == nil
61+
}
62+
63+
func (eh *ExtendedHeader) ChainID() string {
64+
return eh.RawHeader.ChainID
65+
}
66+
67+
func (eh *ExtendedHeader) Height() int64 {
68+
return eh.RawHeader.Height
69+
}
70+
71+
func (eh *ExtendedHeader) Time() time.Time {
72+
return eh.RawHeader.Time
73+
}
74+
75+
var _ libhead.Header = &ExtendedHeader{}
76+
4577
// MakeExtendedHeader assembles new ExtendedHeader.
4678
func MakeExtendedHeader(
4779
ctx context.Context,
@@ -73,33 +105,30 @@ func MakeExtendedHeader(
73105
Commit: comm,
74106
ValidatorSet: vals,
75107
}
76-
return eh, eh.ValidateBasic()
108+
return eh, eh.Validate()
77109
}
78110

79111
// Hash returns Hash of the wrapped RawHeader.
80112
// NOTE: It purposely overrides Hash method of RawHeader to get it directly from Commit without
81113
// recomputing.
82-
func (eh *ExtendedHeader) Hash() bts.HexBytes {
83-
return eh.Commit.BlockID.Hash
114+
func (eh *ExtendedHeader) Hash() libhead.Hash {
115+
return libhead.Hash(eh.Commit.BlockID.Hash)
84116
}
85117

86118
// LastHeader returns the Hash of the last wrapped RawHeader.
87-
func (eh *ExtendedHeader) LastHeader() bts.HexBytes {
88-
return eh.RawHeader.LastBlockID.Hash
119+
func (eh *ExtendedHeader) LastHeader() libhead.Hash {
120+
return libhead.Hash(eh.RawHeader.LastBlockID.Hash)
89121
}
90122

91123
// IsBefore returns whether the given header is of a higher height.
92-
func (eh *ExtendedHeader) IsBefore(h *ExtendedHeader) bool {
93-
return eh.Height < h.Height
94-
}
95124

96125
// Equals returns whether the hash and height of the given header match.
97126
func (eh *ExtendedHeader) Equals(header *ExtendedHeader) bool {
98-
return eh.Height == header.Height && bytes.Equal(eh.Hash(), header.Hash())
127+
return eh.Height() == header.Height() && bytes.Equal(eh.Hash(), header.Hash())
99128
}
100129

101-
// ValidateBasic performs *basic* validation to check for missed/incorrect fields.
102-
func (eh *ExtendedHeader) ValidateBasic() error {
130+
// Validate performs *basic* validation to check for missed/incorrect fields.
131+
func (eh *ExtendedHeader) Validate() error {
103132
err := eh.RawHeader.ValidateBasic()
104133
if err != nil {
105134
return err
@@ -122,7 +151,7 @@ func (eh *ExtendedHeader) ValidateBasic() error {
122151
)
123152
}
124153

125-
if err := eh.ValidatorSet.VerifyCommitLight(eh.ChainID, eh.Commit.BlockID, eh.Height, eh.Commit); err != nil {
154+
if err := eh.ValidatorSet.VerifyCommitLight(eh.ChainID(), eh.Commit.BlockID, eh.Height(), eh.Commit); err != nil {
126155
return err
127156
}
128157

header/header_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,6 @@ func TestMismatchedDataHash_ComputedRoot(t *testing.T) {
4343

4444
header.DataHash = rand.Bytes(32)
4545

46-
err := header.ValidateBasic()
46+
err := header.Validate()
4747
assert.ErrorContains(t, err, "mismatch between data hash")
4848
}

header/local/exchange.go

Lines changed: 0 additions & 53 deletions
This file was deleted.

header/metrics.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ import (
77
"go.opentelemetry.io/otel/metric/global"
88
"go.opentelemetry.io/otel/metric/instrument"
99
"go.opentelemetry.io/otel/metric/unit"
10+
11+
libhead "github.com/celestiaorg/celestia-node/libs/header"
1012
)
1113

1214
var meter = global.MeterProvider().Meter("header")
1315

1416
// WithMetrics enables Otel metrics to monitor head.
15-
func WithMetrics(store Store) {
17+
func WithMetrics(store libhead.Store[*ExtendedHeader]) {
1618
headC, _ := meter.AsyncInt64().Counter(
1719
"head",
1820
instrument.WithUnit(unit.Dimensionless),
@@ -32,7 +34,7 @@ func WithMetrics(store Store) {
3234

3335
headC.Observe(
3436
ctx,
35-
head.Height,
37+
head.Height(),
3638
attribute.Int("square_size", len(head.DAH.RowsRoots)),
3739
)
3840
},

header/mocks/store.go

Lines changed: 0 additions & 100 deletions
This file was deleted.

0 commit comments

Comments
 (0)