Documentation ¶
Overview ¶
Package header contains all services related to generating, requesting, syncing and storing ExtendedHeaders.
An ExtendedHeader is similar to a regular block header from celestia-core, but "extended" by adding the DataAvailabilityHeader (DAH), ValidatorSet and Commit in order to allow for light and full nodes to reconstruct block data by referencing the DAH.
ExtendedHeaders are generated by bridge nodes that listen to the celestia-core network for blocks, validate and extend the block data in order to generate the DAH, and request both the ValidatorSet and Commit for that block height from the celestia-core network. Bridge nodes then package that data up into an ExtendedHeader and broadcast it to the 'header-sub' GossipSub topic (HeaderSub). All nodes subscribed to HeaderSub will receive and validate the ExtendedHeader, and store it, making it available to all other dependent services (such as the DataAvailabilitySampler, or DASer) to access.
There are 5 main components in the header package:
- core.Listener listens for new blocks from the celestia-core network (run by bridge nodes only), extends them, generates a new ExtendedHeader, and publishes it to the HeaderSub.
- p2p.Subscriber listens for new ExtendedHeaders from the Celestia Data Availability (DA) network (via the HeaderSub)
- p2p.Exchange or core.Exchange request ExtendedHeaders from other celestia DA nodes (default for full and light nodes) or from a celestia-core node connection (bridge nodes only)
- Syncer manages syncing of past and recent ExtendedHeaders from either the DA network or a celestia-core connection (bridge nodes only).
- Store manages storing ExtendedHeaders and making them available for access by other dependent services.
For bridge nodes, the general flow of the header Service is as follows:
- core.Listener listens for new blocks from the celestia-core connection
- core.Listener validates the block and generates the ExtendedHeader, simultaneously storing the extended block shares to disk
- core.Listener publishes the new ExtendedHeader to HeaderSub, notifying all subscribed peers of the new ExtendedHeader
- Syncer is already subscribed to the HeaderSub, so it receives new ExtendedHeaders locally from the core.Listener and stores them to disk via Store. - If the celestia-core connection is started simultaneously with the bridge node, then the celestia-core connection will handle the syncing component, piping every synced block to the core.Listener - If the celestia-core connection is already synced to the network, the Syncer handles requesting past headers up to the network head from the celestia-core connection (using core.Exchange rather than p2p.Exchange).
For full and light nodes, the general flow of the header Service is as follows:
- Syncer listens for new ExtendedHeaders from HeaderSub
- If there is a gap between the local head of chain and the new, validated network head, the Syncer kicks off a sync routine to request all ExtendedHeaders between local head and network head.
- While the Syncer requests headers between the local head and network head in batches, it appends them to the subjective chain via Store with the last batched header as the new local head.
Index ¶
- Variables
- func ExtendedHeaderToProto(eh *ExtendedHeader) (*header_pb.ExtendedHeader, error)
- func MarshalExtendedHeader(in *ExtendedHeader) (_ []byte, err error)
- func RandBlockID(t *testing.T) types.BlockID
- func WithMetrics(store Store)
- type Broadcaster
- type ConstructFn
- type DataAvailabilityHeader
- type DummySubscriber
- type ErrNonAdjacent
- type Exchange
- type ExtendedHeader
- func CreateFraudExtHeader(t *testing.T, eh *ExtendedHeader, dag blockservice.BlockService) *ExtendedHeader
- func MakeExtendedHeader(ctx context.Context, b *core.Block, comm *core.Commit, vals *core.ValidatorSet, ...) (*ExtendedHeader, error)
- func ProtoToExtendedHeader(pb *header_pb.ExtendedHeader) (*ExtendedHeader, error)
- func RandExtendedHeader(t *testing.T) *ExtendedHeader
- func UnmarshalExtendedHeader(data []byte) (*ExtendedHeader, error)
- func (eh *ExtendedHeader) Equals(header *ExtendedHeader) bool
- func (eh *ExtendedHeader) Hash() bts.HexBytes
- func (eh *ExtendedHeader) IsBefore(h *ExtendedHeader) bool
- func (eh *ExtendedHeader) IsExpired() bool
- func (eh *ExtendedHeader) IsRecent(blockTime time.Duration) bool
- func (eh *ExtendedHeader) LastHeader() bts.HexBytes
- func (eh *ExtendedHeader) MarshalBinary() ([]byte, error)
- func (eh *ExtendedHeader) MarshalJSON() ([]byte, error)
- func (eh *ExtendedHeader) UnmarshalBinary(data []byte) error
- func (eh *ExtendedHeader) UnmarshalJSON(data []byte) error
- func (eh *ExtendedHeader) ValidateBasic() error
- func (eh *ExtendedHeader) VerifyAdjacent(untrst *ExtendedHeader) error
- func (eh *ExtendedHeader) VerifyNonAdjacent(untrst *ExtendedHeader) error
- type Getter
- type Head
- type RawHeader
- type Store
- type Subscriber
- type Subscription
- type TestSuite
- func (s *TestSuite) Commit(h *RawHeader) *types.Commit
- func (s *TestSuite) GenExtendedHeader() *ExtendedHeader
- func (s *TestSuite) GenExtendedHeaders(num int) []*ExtendedHeader
- func (s *TestSuite) GenRawHeader(height int64, lastHeader, lastCommit, dataHash bytes.HexBytes) *RawHeader
- func (s *TestSuite) Head() *ExtendedHeader
- type Validator
- type VerifyError
Constants ¶
This section is empty.
Variables ¶
var ( // ErrNotFound is returned when there is no requested header. ErrNotFound = errors.New("header: not found") // ErrNoHead is returned when Store is empty (does not contain any known header). ErrNoHead = fmt.Errorf("header/store: no chain head") // ErrHeadersLimitExceeded is returned when ExchangeServer receives header request for more // than maxRequestSize headers. ErrHeadersLimitExceeded = errors.New("header/p2p: header limit per 1 request exceeded") )
var EmptyDAH = da.MinDataAvailabilityHeader
EmptyDAH provides DAH of the empty block.
var TrustingPeriod = 168 * time.Hour
TrustingPeriod is period through which we can trust a header's validators set.
Should be significantly less than the unbonding period (e.g. unbonding period = 3 weeks, trusting period = 2 weeks).
More specifically, trusting period + time needed to check headers + time needed to report and punish misbehavior should be less than the unbonding period.
Functions ¶
func ExtendedHeaderToProto ¶
func ExtendedHeaderToProto(eh *ExtendedHeader) (*header_pb.ExtendedHeader, error)
func MarshalExtendedHeader ¶
func MarshalExtendedHeader(in *ExtendedHeader) (_ []byte, err error)
MarshalExtendedHeader serializes given ExtendedHeader to bytes using protobuf. Paired with UnmarshalExtendedHeader.
func RandBlockID ¶
RandBlockID provides a BlockID fixture.
func WithMetrics ¶ added in v0.4.0
func WithMetrics(store Store)
WithMetrics enables Otel metrics to monitor head.
Types ¶
type Broadcaster ¶
type Broadcaster interface {
Broadcast(ctx context.Context, header *ExtendedHeader, opts ...pubsub.PubOpt) error
}
Broadcaster broadcasts an ExtendedHeader to the network.
type ConstructFn ¶
type ConstructFn = func( context.Context, *core.Block, *core.Commit, *core.ValidatorSet, blockservice.BlockService, ) (*ExtendedHeader, error)
ConstructFn aliases a function that creates an ExtendedHeader.
func FraudMaker ¶
func FraudMaker(t *testing.T, faultHeight int64) ConstructFn
FraudMaker creates a custom ConstructFn that breaks the block at the given height.
type DataAvailabilityHeader ¶
type DataAvailabilityHeader = da.DataAvailabilityHeader
type DummySubscriber ¶
type DummySubscriber struct {
Headers []*ExtendedHeader
}
func (*DummySubscriber) AddValidator ¶
func (mhs *DummySubscriber) AddValidator(Validator) error
func (*DummySubscriber) Cancel ¶
func (mhs *DummySubscriber) Cancel()
func (*DummySubscriber) NextHeader ¶
func (mhs *DummySubscriber) NextHeader(ctx context.Context) (*ExtendedHeader, error)
func (*DummySubscriber) Subscribe ¶
func (mhs *DummySubscriber) Subscribe() (Subscription, error)
type ErrNonAdjacent ¶
ErrNonAdjacent is returned when Store is appended with a header not adjacent to the stored head.
func (*ErrNonAdjacent) Error ¶ added in v0.4.0
func (ena *ErrNonAdjacent) Error() string
type Exchange ¶
type Exchange interface { Getter }
Exchange encompasses the behavior necessary to request ExtendedHeaders from the network.
type ExtendedHeader ¶
type ExtendedHeader struct { RawHeader `json:"header"` Commit *core.Commit `json:"commit"` ValidatorSet *core.ValidatorSet `json:"validator_set"` DAH *DataAvailabilityHeader `json:"dah"` }
ExtendedHeader represents a wrapped "raw" header that includes information necessary for Celestia Nodes to be notified of new block headers and perform Data Availability Sampling.
func CreateFraudExtHeader ¶
func CreateFraudExtHeader(t *testing.T, eh *ExtendedHeader, dag blockservice.BlockService) *ExtendedHeader
func MakeExtendedHeader ¶
func MakeExtendedHeader( ctx context.Context, b *core.Block, comm *core.Commit, vals *core.ValidatorSet, bServ blockservice.BlockService, ) (*ExtendedHeader, error)
MakeExtendedHeader assembles new ExtendedHeader.
func ProtoToExtendedHeader ¶
func ProtoToExtendedHeader(pb *header_pb.ExtendedHeader) (*ExtendedHeader, error)
func RandExtendedHeader ¶
func RandExtendedHeader(t *testing.T) *ExtendedHeader
RandExtendedHeader provides an ExtendedHeader fixture.
func UnmarshalExtendedHeader ¶
func UnmarshalExtendedHeader(data []byte) (*ExtendedHeader, error)
UnmarshalExtendedHeader deserializes given data into a new ExtendedHeader using protobuf. Paired with MarshalExtendedHeader.
func (*ExtendedHeader) Equals ¶
func (eh *ExtendedHeader) Equals(header *ExtendedHeader) bool
Equals returns whether the hash and height of the given header match.
func (*ExtendedHeader) Hash ¶
func (eh *ExtendedHeader) Hash() bts.HexBytes
Hash returns Hash of the wrapped RawHeader. NOTE: It purposely overrides Hash method of RawHeader to get it directly from Commit without recomputing.
func (*ExtendedHeader) IsBefore ¶
func (eh *ExtendedHeader) IsBefore(h *ExtendedHeader) bool
IsBefore returns whether the given header is of a higher height.
func (*ExtendedHeader) IsExpired ¶
func (eh *ExtendedHeader) IsExpired() bool
IsExpired checks if header is expired against trusting period.
func (*ExtendedHeader) IsRecent ¶
func (eh *ExtendedHeader) IsRecent(blockTime time.Duration) bool
IsRecent checks if header is recent against the given blockTime.
func (*ExtendedHeader) LastHeader ¶
func (eh *ExtendedHeader) LastHeader() bts.HexBytes
LastHeader returns the Hash of the last wrapped RawHeader.
func (*ExtendedHeader) MarshalBinary ¶
func (eh *ExtendedHeader) MarshalBinary() ([]byte, error)
MarshalBinary marshals ExtendedHeader to binary.
func (*ExtendedHeader) MarshalJSON ¶ added in v0.5.0
func (eh *ExtendedHeader) MarshalJSON() ([]byte, error)
MarshalJSON marshals an ExtendedHeader to JSON. The ValidatorSet is wrapped with amino encoding, to be able to unmarshal the crypto.PubKey type back from JSON.
func (*ExtendedHeader) UnmarshalBinary ¶
func (eh *ExtendedHeader) UnmarshalBinary(data []byte) error
UnmarshalBinary unmarshals ExtendedHeader from binary.
func (*ExtendedHeader) UnmarshalJSON ¶ added in v0.5.0
func (eh *ExtendedHeader) UnmarshalJSON(data []byte) error
UnmarshalJSON unmarshals an ExtendedHeader from JSON. The ValidatorSet is wrapped with amino encoding, to be able to unmarshal the crypto.PubKey type back from JSON.
func (*ExtendedHeader) ValidateBasic ¶
func (eh *ExtendedHeader) ValidateBasic() error
ValidateBasic performs *basic* validation to check for missed/incorrect fields.
func (*ExtendedHeader) VerifyAdjacent ¶
func (eh *ExtendedHeader) VerifyAdjacent(untrst *ExtendedHeader) error
VerifyAdjacent validates adjacent untrusted header against trusted 'eh'.
func (*ExtendedHeader) VerifyNonAdjacent ¶
func (eh *ExtendedHeader) VerifyNonAdjacent(untrst *ExtendedHeader) error
VerifyNonAdjacent validates non-adjacent untrusted header against trusted 'eh'.
type Getter ¶
type Getter interface { Head // Get returns the ExtendedHeader corresponding to the given hash. Get(context.Context, tmbytes.HexBytes) (*ExtendedHeader, error) // GetByHeight returns the ExtendedHeader corresponding to the given block height. GetByHeight(context.Context, uint64) (*ExtendedHeader, error) // GetRangeByHeight returns the given range of ExtendedHeaders. GetRangeByHeight(ctx context.Context, from, amount uint64) ([]*ExtendedHeader, error) // GetVerifiedRange requests the header range from the provided ExtendedHeader and // verifies that the returned headers are adjacent to each other. GetVerifiedRange(ctx context.Context, from *ExtendedHeader, amount uint64) ([]*ExtendedHeader, error) }
Getter contains the behavior necessary for a component to retrieve headers that have been processed during header sync.
type Head ¶ added in v0.3.1
type Head interface { // Head returns the latest known header. Head(context.Context) (*ExtendedHeader, error) }
Head contains the behavior necessary for a component to retrieve the chain head. Note that "chain head" is subjective to the component reporting it.
type RawHeader ¶
RawHeader is an alias to core.Header. It is "raw" because it is not yet wrapped to include the DataAvailabilityHeader.
func RandRawHeader ¶
RandRawHeader provides a RawHeader fixture.
type Store ¶
type Store interface { // Start starts the store. Start(context.Context) error // Stop stops the store by preventing further writes // and waiting till the ongoing ones are done. Stop(context.Context) error // Getter encompasses all getter methods for headers. Getter // Init initializes Store with the given head, meaning it is initialized with the genesis header. Init(context.Context, *ExtendedHeader) error // Height reports current height of the chain head. Height() uint64 // Has checks whether ExtendedHeader is already stored. Has(context.Context, tmbytes.HexBytes) (bool, error) // Append stores and verifies the given ExtendedHeader(s). // It requires them to be adjacent and in ascending order, // as it applies them contiguously on top of the current head height. // It returns the amount of successfully applied headers, // so caller can understand what given header was invalid, if any. Append(context.Context, ...*ExtendedHeader) (int, error) }
Store encompasses the behavior necessary to store and retrieve ExtendedHeaders from a node's local storage.
type Subscriber ¶
type Subscriber interface { // Subscribe creates long-living Subscription for validated ExtendedHeaders. // Multiple Subscriptions can be created. Subscribe() (Subscription, error) // AddValidator registers a Validator for all Subscriptions. // Registered Validators screen ExtendedHeaders for their validity // before they are sent through Subscriptions. // Multiple validators can be registered. AddValidator(Validator) error // Stop removes header-sub validator and closes the topic. Stop(context.Context) error }
Subscriber encompasses the behavior necessary to subscribe/unsubscribe from new ExtendedHeader events from the network.
type Subscription ¶
type Subscription interface { // NextHeader returns the newest verified and valid ExtendedHeader // in the network. NextHeader(ctx context.Context) (*ExtendedHeader, error) // Cancel cancels the subscription. Cancel() }
Subscription can retrieve the next ExtendedHeader from the network.
type TestSuite ¶
type TestSuite struct {
// contains filtered or unexported fields
}
TestSuite provides everything you need to test chain of Headers. If not, please don't hesitate to extend it for your case.
func NewTestSuite ¶
NewTestSuite setups a new test suite with a given number of validators.
func (*TestSuite) GenExtendedHeader ¶
func (s *TestSuite) GenExtendedHeader() *ExtendedHeader
func (*TestSuite) GenExtendedHeaders ¶
func (s *TestSuite) GenExtendedHeaders(num int) []*ExtendedHeader
func (*TestSuite) GenRawHeader ¶
func (*TestSuite) Head ¶
func (s *TestSuite) Head() *ExtendedHeader
type Validator ¶
type Validator = func(context.Context, *ExtendedHeader) pubsub.ValidationResult
Validator aliases a func that validates ExtendedHeader.
type VerifyError ¶
type VerifyError struct {
Reason error
}
VerifyError is thrown on during VerifyAdjacent and VerifyNonAdjacent if verification fails.
func (*VerifyError) Error ¶
func (vr *VerifyError) Error() string