Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: improve documentation and error handling in core/fetcher.go #4034

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 26 additions & 17 deletions core/fetcher.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Package core provides fundamental blockchain interaction functionality,
// including block fetching, subscription handling, and validator set management.
package core

import (
Expand All @@ -12,13 +14,18 @@ import (
libhead "github.com/celestiaorg/go-header"
)

// Constants for event subscription
const newBlockSubscriber = "NewBlock/Events"

var (
// log is the package-level logger
log = logging.Logger("core")
// newDataSignedBlockQuery defines the query string for subscribing to signed block events
newDataSignedBlockQuery = types.QueryForEvent(types.EventSignedBlock).String()
)

// BlockFetcher provides functionality to fetch blocks, commits, and validator sets
// from a Tendermint Core node. It also supports subscribing to new block events.
type BlockFetcher struct {
client Client

Expand All @@ -33,11 +40,13 @@ func NewBlockFetcher(client Client) *BlockFetcher {
}
}

// GetBlockInfo queries Core for additional block information, like Commit and ValidatorSet.
// GetBlockInfo queries Core for additional block information, including Commit and ValidatorSet.
// If height is nil, it fetches information for the latest block.
// Returns an error if either the commit or validator set cannot be retrieved.
func (f *BlockFetcher) GetBlockInfo(ctx context.Context, height *int64) (*types.Commit, *types.ValidatorSet, error) {
commit, err := f.Commit(ctx, height)
if err != nil {
return nil, nil, fmt.Errorf("core/fetcher: getting commit at height %d: %w", height, err)
return nil, nil, fmt.Errorf("failed to get commit at height %v: %w", height, err)
}

// If a nil `height` is given as a parameter, there is a chance
Expand All @@ -47,34 +56,33 @@ func (f *BlockFetcher) GetBlockInfo(ctx context.Context, height *int64) (*types.
// prevent this potential inconsistency.
valSet, err := f.ValidatorSet(ctx, &commit.Height)
if err != nil {
return nil, nil, fmt.Errorf("core/fetcher: getting validator set at height %d: %w", height, err)
return nil, nil, fmt.Errorf("failed to get validator set at height %v: %w", height, err)
}

return commit, valSet, nil
}

// GetBlock queries Core for a `Block` at the given height.
// GetBlock retrieves a block at the specified height from Core.
// If height is nil, it fetches the latest block.
func (f *BlockFetcher) GetBlock(ctx context.Context, height *int64) (*types.Block, error) {
res, err := f.client.Block(ctx, height)
if err != nil {
return nil, err
return nil, fmt.Errorf("failed to get block: %w", err)
}

if res != nil && res.Block == nil {
return nil, fmt.Errorf("core/fetcher: block not found, height: %d", height)
return nil, fmt.Errorf("block not found at height %v", height)
}

return res.Block, nil
}

// GetBlockByHash retrieves a block with the specified hash from Core.
func (f *BlockFetcher) GetBlockByHash(ctx context.Context, hash libhead.Hash) (*types.Block, error) {
res, err := f.client.BlockByHash(ctx, hash)
if err != nil {
return nil, err
return nil, fmt.Errorf("failed to get block by hash: %w", err)
}

if res != nil && res.Block == nil {
return nil, fmt.Errorf("core/fetcher: block not found, hash: %s", hash.String())
return nil, fmt.Errorf("block not found with hash %s", hash.String())
}

return res.Block, nil
Expand Down Expand Up @@ -123,12 +131,12 @@ func (f *BlockFetcher) ValidatorSet(ctx context.Context, height *int64) (*types.
return types.NewValidatorSet(vals), nil
}

// SubscribeNewBlockEvent subscribes to new block events from Core, returning
// a new block event channel on success.
// SubscribeNewBlockEvent subscribes to new block events from Core.
// Returns a channel that receives new block events and an error if the subscription fails.
// The subscription can be cancelled using UnsubscribeNewBlockEvent or when the context is cancelled.
func (f *BlockFetcher) SubscribeNewBlockEvent(ctx context.Context) (<-chan types.EventDataSignedBlock, error) {
// start the client if not started yet
if !f.client.IsRunning() {
return nil, errors.New("client not running")
return nil, errors.New("client is not running")
}

ctx, cancel := context.WithCancel(ctx)
Expand All @@ -137,7 +145,7 @@ func (f *BlockFetcher) SubscribeNewBlockEvent(ctx context.Context) (<-chan types

eventChan, err := f.client.Subscribe(ctx, newBlockSubscriber, newDataSignedBlockQuery)
if err != nil {
return nil, err
return nil, fmt.Errorf("failed to subscribe to new blocks: %w", err)
}

signedBlockCh := make(chan types.EventDataSignedBlock)
Expand All @@ -150,7 +158,7 @@ func (f *BlockFetcher) SubscribeNewBlockEvent(ctx context.Context) (<-chan types
return
case newEvent, ok := <-eventChan:
if !ok {
log.Errorw("fetcher: new blocks subscription channel closed unexpectedly")
log.Errorw("new blocks subscription channel closed unexpectedly")
return
}
signedBlock := newEvent.Data.(types.EventDataSignedBlock)
Expand Down Expand Up @@ -187,3 +195,4 @@ func (f *BlockFetcher) IsSyncing(ctx context.Context) (bool, error) {
}
return resp.SyncInfo.CatchingUp, nil
}

Loading