header

package
v0.2.0-rc1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 22, 2022 License: Apache-2.0 Imports: 38 Imported by: 0

Documentation

Overview

TODO(@Wondertan): Ideally, we should move that into subpackage, so this does not get included into binary of

production code, but that does not matter at the moment.

Index

Constants

View Source
const PubSubTopic = "header-sub"

PubSubTopic hardcodes the name of the ExtendedHeader gossipsub topic.

Variables

View Source
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")

	// ErrNonAdjacent is returned when Store is appended with a header not adjacent to the stored head.
	ErrNonAdjacent = fmt.Errorf("header/store: non-adjacent")
)
View Source
var (
	// DefaultStoreCacheSize defines the amount of max entries allowed in the Header Store cache.
	DefaultStoreCacheSize = 4096
	// DefaultIndexCacheSize defines the amount of max entries allowed in the Height to Hash index cache.
	DefaultIndexCacheSize = 16384
	// DefaultWriteBatchSize defines the size of the batched header write.
	// Headers are written in batches not to thrash the underlying Datastore with writes.
	DefaultWriteBatchSize = 2048
)

TODO(@Wondertan): Those values must be configurable and proper defaults should be set for specific node type.

EmptyDAH provides DAH of the empty block.

View Source
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. TODO(@Wondertan): We should request it from the network's state params

or listen for network params changes to always have a topical value.

Functions

func ExtendedHeaderToProto

func ExtendedHeaderToProto(eh *ExtendedHeader) (*header_pb.ExtendedHeader, error)

func InitStore added in v0.2.0

func InitStore(ctx context.Context, store Store, ex Exchange, hash tmbytes.HexBytes) error

InitStore ensures a Store is initialized. If it is not already initialized, it initializes the Store by requesting the header with the given hash.

func MarshalExtendedHeader

func MarshalExtendedHeader(in *ExtendedHeader) (_ []byte, err error)

MarshalExtendedHeader serializes given ExtendedHeader to bytes using protobuf. Paired with UnmarshalExtendedHeader.

func MarshalExtendedHeaderRequest

func MarshalExtendedHeaderRequest(in *ExtendedHeaderRequest) ([]byte, error)

MarshalExtendedHeaderRequest serializes the given ExtendedHeaderRequest to bytes using protobuf. Paired with UnmarshalExtendedHeaderRequest.

func RandBlockID

func RandBlockID(t *testing.T) types.BlockID

RandBlockID provides a BlockID fixture.

Types

type Broadcaster

type Broadcaster interface {
	Broadcast(ctx context.Context, header *ExtendedHeader) error
}

Broadcaster broadcasts an ExtendedHeader to the network.

type CoreExchange

type CoreExchange struct {
	// contains filtered or unexported fields
}

func NewCoreExchange

func NewCoreExchange(fetcher *core.BlockFetcher, dag format.DAGService) *CoreExchange

func (*CoreExchange) RequestByHash

func (ce *CoreExchange) RequestByHash(ctx context.Context, hash tmbytes.HexBytes) (*ExtendedHeader, error)

func (*CoreExchange) RequestHead

func (ce *CoreExchange) RequestHead(ctx context.Context) (*ExtendedHeader, error)

func (*CoreExchange) RequestHeader

func (ce *CoreExchange) RequestHeader(ctx context.Context, height uint64) (*ExtendedHeader, error)

func (*CoreExchange) RequestHeaders

func (ce *CoreExchange) RequestHeaders(ctx context.Context, from, amount uint64) ([]*ExtendedHeader, error)

type CoreListener added in v0.2.0

type CoreListener struct {
	// contains filtered or unexported fields
}

CoreListener is responsible for listening to Core for new block events and converting new Core blocks into the main data structure used in the Celestia DA network: `ExtendedHeader`. After digesting the Core block, extending it, and generating the `ExtendedHeader`, the CoreListener broadcasts the new `ExtendedHeader` to the header-sub gossipsub network.

func NewCoreListener added in v0.2.0

func NewCoreListener(bcast Broadcaster, fetcher *core.BlockFetcher, dag format.DAGService) *CoreListener

func (*CoreListener) Start added in v0.2.0

func (cl *CoreListener) Start(ctx context.Context) error

Start kicks off the CoreListener listener loop.

func (*CoreListener) Stop added in v0.2.0

func (cl *CoreListener) Stop(ctx context.Context) error

Stop stops the CoreListener listener loop.

type DataAvailabilityHeader

type DataAvailabilityHeader = da.DataAvailabilityHeader

func DataAvailabilityHeaderFromExtendedData

func DataAvailabilityHeaderFromExtendedData(data *rsmt2d.ExtendedDataSquare) (DataAvailabilityHeader, error)

DataAvailabilityHeaderFromExtendedData generates a DataAvailabilityHeader from the given data square. TODO @renaynay: use da.NewDataAvailabilityHeader

type DummySubscriber added in v0.2.0

type DummySubscriber struct {
	Headers []*ExtendedHeader
}

func (*DummySubscriber) AddValidator added in v0.2.0

func (mhs *DummySubscriber) AddValidator(Validator) error

func (*DummySubscriber) Cancel added in v0.2.0

func (mhs *DummySubscriber) Cancel()

func (*DummySubscriber) NextHeader added in v0.2.0

func (mhs *DummySubscriber) NextHeader(ctx context.Context) (*ExtendedHeader, error)

func (*DummySubscriber) Subscribe added in v0.2.0

func (mhs *DummySubscriber) Subscribe() (Subscription, error)

type Exchange

type Exchange interface {
	// RequestHead requests the latest ExtendedHeader. Note that the ExtendedHeader
	// must be verified thereafter.
	RequestHead(ctx context.Context) (*ExtendedHeader, error)
	// RequestHeader performs a request for the ExtendedHeader at the given
	// height to the network. Note that the ExtendedHeader must be verified
	// thereafter.
	RequestHeader(ctx context.Context, height uint64) (*ExtendedHeader, error)
	// RequestHeaders performs a request for the given range of ExtendedHeaders
	// to the network. Note that the ExtendedHeaders must be verified thereafter.
	RequestHeaders(ctx context.Context, origin, amount uint64) ([]*ExtendedHeader, error)
	// RequestByHash performs a request for the ExtendedHeader by the given hash corresponding
	// to the RawHeader. Note that the ExtendedHeader must be verified thereafter.
	RequestByHash(ctx context.Context, hash tmbytes.HexBytes) (*ExtendedHeader, error)
}

Exchange encompasses the behavior necessary to request ExtendedHeaders from the network.

func NewLocalExchange

func NewLocalExchange(store Store) Exchange

NewLocalExchange creates new Exchange.

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 MakeExtendedHeader added in v0.2.0

func MakeExtendedHeader(
	ctx context.Context,
	b *core.Block,
	comm *core.Commit,
	vals *core.ValidatorSet,
	dag format.NodeAdder,
) (*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) 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) IsExpired added in v0.2.0

func (eh *ExtendedHeader) IsExpired() bool

IsExpired checks if header is expired against trusting period.

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) UnmarshalBinary

func (eh *ExtendedHeader) UnmarshalBinary(data []byte) error

UnmarshalBinary unmarshals ExtendedHeader from binary.

func (*ExtendedHeader) ValidateBasic

func (eh *ExtendedHeader) ValidateBasic() error

ValidateBasic performs *basic* validation to check for missed/incorrect fields.

func (*ExtendedHeader) VerifyAdjacent added in v0.2.0

func (eh *ExtendedHeader) VerifyAdjacent(untrst *ExtendedHeader) error

VerifyAdjacent validates adjacent untrusted header against trusted 'eh'.

func (*ExtendedHeader) VerifyNonAdjacent added in v0.2.0

func (eh *ExtendedHeader) VerifyNonAdjacent(untrst *ExtendedHeader) error

VerifyNonAdjacent validates non-adjacent untrusted header against trusted 'eh'.

type ExtendedHeaderRequest

type ExtendedHeaderRequest struct {
	Origin uint64 // block height from which to request ExtendedHeaders
	Amount uint64 // amount of desired ExtendedHeaders starting from Origin, syncing in ascending order
}

ExtendedHeaderRequest is the packet format for nodes to request ExtendedHeaders from the network.

func UnmarshalExtendedHeaderRequest

func UnmarshalExtendedHeaderRequest(data []byte) (*ExtendedHeaderRequest, error)

UnmarshalExtendedHeaderRequest deserializes given data into a new ExtendedHeader using protobuf. Paired with MarshalExtendedHeaderRequest.

func (*ExtendedHeaderRequest) MarshalBinary

func (ehr *ExtendedHeaderRequest) MarshalBinary() ([]byte, error)

MarshalBinary marshals ExtendedHeaderRequest to binary.

func (*ExtendedHeaderRequest) ToProto

func (*ExtendedHeaderRequest) UnmarshalBinary

func (ehr *ExtendedHeaderRequest) UnmarshalBinary(data []byte) error

type LocalExchange

type LocalExchange struct {
	// contains filtered or unexported fields
}

LocalExchange is a simple Exchange that reads Headers from Store without any networking.

func (*LocalExchange) RequestByHash

func (l *LocalExchange) RequestByHash(ctx context.Context, hash bytes.HexBytes) (*ExtendedHeader, error)

func (*LocalExchange) RequestHead

func (l *LocalExchange) RequestHead(ctx context.Context) (*ExtendedHeader, error)

func (*LocalExchange) RequestHeader

func (l *LocalExchange) RequestHeader(ctx context.Context, height uint64) (*ExtendedHeader, error)

func (*LocalExchange) RequestHeaders

func (l *LocalExchange) RequestHeaders(ctx context.Context, origin, amount uint64) ([]*ExtendedHeader, error)

func (*LocalExchange) Start

func (l *LocalExchange) Start(context.Context) error

func (*LocalExchange) Stop

type P2PExchange

type P2PExchange struct {
	// contains filtered or unexported fields
}

P2PExchange enables sending outbound ExtendedHeaderRequests to the network as well as handling inbound ExtendedHeaderRequests from the network.

func NewP2PExchange

func NewP2PExchange(host host.Host, peers peer.IDSlice) *P2PExchange

func (*P2PExchange) RequestByHash

func (ex *P2PExchange) RequestByHash(ctx context.Context, hash tmbytes.HexBytes) (*ExtendedHeader, error)

func (*P2PExchange) RequestHead

func (ex *P2PExchange) RequestHead(ctx context.Context) (*ExtendedHeader, error)

func (*P2PExchange) RequestHeader

func (ex *P2PExchange) RequestHeader(ctx context.Context, height uint64) (*ExtendedHeader, error)

func (*P2PExchange) RequestHeaders

func (ex *P2PExchange) RequestHeaders(ctx context.Context, from, amount uint64) ([]*ExtendedHeader, error)

type P2PExchangeServer added in v0.2.0

type P2PExchangeServer struct {
	// contains filtered or unexported fields
}

P2PExchangeServer represents the server-side component for responding to inbound header-related requests.

func NewP2PExchangeServer added in v0.2.0

func NewP2PExchangeServer(host host.Host, store Store) *P2PExchangeServer

NewP2PExchangeServer returns a new P2P server that handles inbound header-related requests.

func (*P2PExchangeServer) Start added in v0.2.0

func (serv *P2PExchangeServer) Start(context.Context) error

Start sets the stream handler for inbound header-related requests.

func (*P2PExchangeServer) Stop added in v0.2.0

func (serv *P2PExchangeServer) Stop(context.Context) error

Stop removes the stream handler for serving header-related requests.

type P2PSubscriber added in v0.2.0

type P2PSubscriber struct {
	// contains filtered or unexported fields
}

P2PSubscriber manages the lifecycle and relationship of header Service with the "header-sub" gossipsub topic.

func NewP2PSubscriber added in v0.2.0

func NewP2PSubscriber(ps *pubsub.PubSub) *P2PSubscriber

NewP2PSubscriber returns a P2PSubscriber that manages the header Service's relationship with the "header-sub" gossipsub topic.

func (*P2PSubscriber) AddValidator added in v0.2.0

func (p *P2PSubscriber) AddValidator(val Validator) error

AddValidator applies basic pubsub validator for the topic.

func (*P2PSubscriber) Broadcast added in v0.2.0

func (p *P2PSubscriber) Broadcast(ctx context.Context, header *ExtendedHeader) error

Broadcast broadcasts the given ExtendedHeader to the topic.

func (*P2PSubscriber) Start added in v0.2.0

func (p *P2PSubscriber) Start(context.Context) (err error)

Start starts the P2PSubscriber, registering a topic validator for the "header-sub" topic and joining it.

func (*P2PSubscriber) Stop added in v0.2.0

Stop closes the topic and unregisters its validator.

func (*P2PSubscriber) Subscribe added in v0.2.0

func (p *P2PSubscriber) Subscribe() (Subscription, error)

Subscribe returns a new subscription to the P2PSubscriber's topic.

type RawHeader

type RawHeader = core.Header

RawHeader is an alias to core.Header. It is "raw" because it is not yet wrapped to include the DataAvailabilityHeader.

func RandRawHeader

func RandRawHeader(t *testing.T) *RawHeader

RandRawHeader provides a RawHeader fixture.

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service represents the header service that can be started / stopped on a node. Service's main function is to manage its sub-services. Service can contain several sub-services, such as Exchange, P2PExchangeServer, Syncer, and so forth.

func NewHeaderService

func NewHeaderService(
	syncer *Syncer,
	sub Subscriber,
	p2pServer *P2PExchangeServer,
	ex Exchange) *Service

NewHeaderService creates a new instance of header Service.

func (*Service) IsSyncing added in v0.2.0

func (s *Service) IsSyncing() bool

IsSyncing returns the status of sync

func (*Service) Start

func (s *Service) Start(context.Context) error

Start starts the header Service.

func (*Service) Stop

func (s *Service) Stop(context.Context) error

Stop stops the header Service.

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

	// 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

	// Head returns the ExtendedHeader of the chain head.
	Head(context.Context) (*ExtendedHeader, error)

	// 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 [from:to) of ExtendedHeaders.
	GetRangeByHeight(ctx context.Context, from, to uint64) ([]*ExtendedHeader, error)

	// 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.

func NewStore

func NewStore(ds datastore.Batching) (Store, error)

NewStore constructs a Store over datastore. The datastore must have a head there otherwise Start will error. For first initialization of Store use NewStoreWithHead.

func NewStoreWithHead

func NewStoreWithHead(ctx context.Context, ds datastore.Batching, head *ExtendedHeader) (Store, error)

NewStoreWithHead initiates a new Store and forcefully sets a given trusted header as head.

func NewTestStore added in v0.2.0

func NewTestStore(ctx context.Context, t *testing.T, head *ExtendedHeader) Store

NewTestStore creates initialized and started in memory header Store which is useful for testing.

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
}

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 SyncState added in v0.2.0

type SyncState struct {
	ID                   uint64 // incrementing ID of a sync
	Height               uint64 // height at the moment when State is requested for a sync
	FromHeight, ToHeight uint64 // the starting and the ending point of a sync
	FromHash, ToHash     tmbytes.HexBytes
	Start, End           time.Time
	Error                error // the error that might happen within a sync
}

SyncState collects all the information about a sync.

func (SyncState) Finished added in v0.2.0

func (s SyncState) Finished() bool

Finished returns true if sync is done, false otherwise.

type Syncer

type Syncer struct {
	// contains filtered or unexported fields
}

Syncer implements efficient synchronization for headers.

There are two main processes running in Syncer: 1. Main syncing loop(s.syncLoop)

  • Performs syncing from the subjective(local chain view) header up to the latest known trusted header
  • Syncs by requesting missing headers from Exchange or
  • By accessing cache of pending and verified headers

2. Receives new headers from PubSub subnetwork (s.processIncoming)

  • Usually, a new header is adjacent to the trusted head and if so, it is simply appended to the local store, incrementing the subjective height and making it the new latest known trusted header.
  • Or, if it receives a header further in the future,
  • verifies against the latest known trusted header
  • adds the header to pending cache(making it the latest known trusted header)
  • and triggers syncing loop to catch up to that point.

func NewSyncer

func NewSyncer(exchange Exchange, store Store, sub Subscriber) *Syncer

NewSyncer creates a new instance of Syncer.

func (*Syncer) Start added in v0.2.0

func (s *Syncer) Start(context.Context) error

Start starts the syncing routine.

func (*Syncer) State added in v0.2.0

func (s *Syncer) State() SyncState

State reports state of the current (if in progress), or last sync (if finished). Note that throughout the whole Syncer lifetime there might an initial sync and multiple catch-ups. All of them are treated as different syncs with different state IDs and other information.

func (*Syncer) Stop added in v0.2.0

func (s *Syncer) Stop(context.Context) error

Stop stops Syncer.

func (*Syncer) WaitSync added in v0.2.0

func (s *Syncer) WaitSync(ctx context.Context) error

WaitSync blocks until ongoing sync is done.

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

func NewTestSuite(t *testing.T, num int) *TestSuite

NewTestSuite setups a new test suite with a given number of validators.

func (*TestSuite) Commit

func (s *TestSuite) Commit(h *RawHeader) *types.Commit

func (*TestSuite) GenExtendedHeader

func (s *TestSuite) GenExtendedHeader() *ExtendedHeader

func (*TestSuite) GenExtendedHeaders

func (s *TestSuite) GenExtendedHeaders(num int) []*ExtendedHeader

func (*TestSuite) GenRawHeader

func (s *TestSuite) GenRawHeader(
	height int64, lastHeader, lastCommit, dataHash bytes.HexBytes) *RawHeader

func (*TestSuite) Head

func (s *TestSuite) Head() *ExtendedHeader

type Validator added in v0.2.0

Validator aliases a func that validates ExtendedHeader.

type VerifyError added in v0.2.0

type VerifyError struct {
	Reason error
}

VerifyError is thrown on during VerifyAdjacent and VerifyNonAdjacent if verification fails.

func (*VerifyError) Error added in v0.2.0

func (vr *VerifyError) Error() string

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL