block.go
Overview
The [block.go](/projects/291/69210) file is part of the Cosmos SDK ecosystem, specifically interacting with the CometBFT (previously Tendermint) blockchain node RPC interface. It provides a service and HTTP client methods to fetch and cache blockchain block data and related information. This file is designed to efficiently retrieve block details, cache them for quick access, and expose additional RPC calls for block search and block results.
Key functionalities include:
Fetching blocks by height (or latest block if height is nil).
Caching fetched blocks locally to reduce repeated RPC calls.
Searching blocks based on query parameters.
Retrieving block results, including transaction and validator results.
Wrapping CometBFT RPC responses and unmarshalling JSON data for internal use.
This file acts as a bridge between the application layer and the CometBFT RPC endpoints related to blockchain blocks.
Types and Structures
BlockFetcher Interface
type BlockFetcher interface {
GetBlock(height *int) (*coretypes.ResultBlock, error)
}
Purpose: Abstracts any type that can fetch block data by height.
Method:
GetBlock(height *int) (*coretypes.ResultBlock, error): Fetches the block at the specified height. Ifheightis nil, fetches the latest block.
Usage: Allows
BlockServiceto use any HTTP client or mock that implements this interface.
BlockService Struct
type BlockService struct {
Latest *BlockResponse
Blocks map[int]*BlockResponse
m sync.RWMutex
httpClient BlockFetcher
}
Purpose: Manages block data caching and retrieval logic.
Fields:
Latest: Pointer to the most recent block cached.Blocks: Map of block height to cachedBlockResponse.m: Read-write mutex to ensure thread-safe access to cache.httpClient: An instance implementingBlockFetcherfor actual RPC calls.
BlockResponse (Referenced but not defined in this file)
Note: This struct is used within this file but its definition is assumed elsewhere in the project. From usage, it contains at least:
Height intHash stringTimestamp int
This struct holds simplified block data used by the service.
Functions and Methods
NewBlockService
func NewBlockService(httpClient BlockFetcher) (*BlockService, error)
Purpose: Constructor for
BlockService.Parameters:
httpClient: An implementation ofBlockFetcherto use for block retrieval.
Returns: A pointer to initialized
BlockService, or an error if the initial fetch fails.Behavior:
Initializes the cache map.
Fetches the latest block using
httpClient.GetBlock(nil).Creates a
BlockResponsefrom the fetched block.Caches the latest block.
Usage example:
client := NewHTTPClient(...) // Assuming constructor exists blockService, err := NewBlockService(client) if err != nil { log.Fatal(err) }
WriteBlock
func (s *BlockService) WriteBlock(block *BlockResponse, latest bool)
Purpose: Stores a block into the cache.
Parameters:
block: TheBlockResponseto cache.latest: Boolean flag indicating whether this block should be marked as the latest.
Behavior:
Locks the cache for writing.
Updates the
Latestpointer iflatestis true.Stores the block in the
Blocksmap keyed by height.Unlocks after update.
Thread-safety: Uses mutex locking for concurrency safety.
GetBlock (on BlockService)
func (s *BlockService) GetBlock(height int) (*BlockResponse, error)
Purpose: Retrieves a cached block by height or fetches it from the RPC client if missing.
Parameters:
height: The height of the block to retrieve.
Returns: Pointer to
BlockResponseor an error.Behavior:
Checks local cache first.
If not cached, calls
httpClient.GetBlock(&height)to fetch.Converts the RPC result to
BlockResponse.Caches the newly fetched block.
Usage example:
block, err := blockService.GetBlock(12345) if err != nil { // Handle error } fmt.Println("Block hash:", block.Hash)
GetBlock (on HTTPClient)
func (c *HTTPClient) GetBlock(height *int) (*coretypes.ResultBlock, error)
Purpose: Makes an HTTP RPC call to fetch a block from CometBFT node.
Parameters:
height: Pointer to int block height, or nil for latest block.
Returns:
ResultBlockwhich contains full block data, or error.Implementation details:
Constructs query parameter
"height"if height is provided.Sends GET request to
/blockRPC endpoint.Handles RPC errors and unmarshals JSON response to
ResultBlock.
Error handling: Wraps errors with context for easier debugging.
BlockSearch (on HTTPClient)
func (c *HTTPClient) BlockSearch(query string, page int, pageSize int) (*coretypes.ResultBlockSearch, error)
Purpose: Searches blocks matching a query string.
Parameters:
query: String query in CometBFT query language.page: Pagination page number.pageSize: Number of results per page.
Returns:
ResultBlockSearchcontaining blocks and total count, or error.Implementation details:
Builds query parameters including ordering by descending height.
Calls
/block_searchendpoint.Handles pagination errors gracefully by returning empty results.
Unmarshals JSON response into
ResultBlockSearch.
Usage example:
results, err := client.BlockSearch("tx.height > 1000", 1, 10) if err != nil { // Handle error } fmt.Printf("Found %d blocks\n", results.TotalCount)
BlockResults (on HTTPClient)
func (c *HTTPClient) BlockResults(height int) (BlockResults, error)
Purpose: Fetches transaction and consensus results for a given block height.
Parameters:
height: The block height for which results are requested.
Returns:
BlockResultsinterface (implemented byResultBlockResults) or error.Implementation details:
Calls
/block_resultsendpoint with height query.Handles RPC errors.
Unmarshals JSON result into
ResultBlockResults.
Note:
BlockResultsandResultBlockResultstypes/interfaces are assumed to be defined elsewhere.Usage example:
results, err := client.BlockResults(12345) if err != nil { // Handle error } // Use results ...
Important Implementation Details and Algorithms
Caching Mechanism:
TheBlockServicecaches block data keyed by height to minimize repeated network calls. It uses a thread-safe map protected by a read-write mutex (sync.RWMutex).Lazy Loading:
Blocks not found in the cache are fetched on-demand from the CometBFT RPC endpoint and then cached.Error Handling:
All RPC calls handle transport, RPC error responses, and JSON unmarshalling errors explicitly, wrapping errors with context for easier debugging.RPC Integration:
The HTTP client methods use a fluent request builder (c.RPC.R()) to set query params and parse responses, integrating tightly with CometBFT's JSON-RPC endpoints.
Interactions with Other System Components
CometBFT Node RPC:
TheHTTPClientmethods interact directly with the CometBFT node's HTTP JSON-RPC endpoints (/block,/block_search,/block_results).Coretypes Package:
The file relies heavily on types from thecoretypespackage, which provides Go representations of CometBFT RPC responses.Higher Level Application Logic:
BlockServiceprovides a cached block data layer that higher-level services or APIs can utilize to quickly retrieve block information without redundant RPC calls.Concurrency:
Designed for concurrent use with mutex locking to ensure thread-safe access to cached data.
Visual Diagram of BlockService Structure
classDiagram
class BlockService {
+Latest: *BlockResponse
+Blocks: map[int]*BlockResponse
-m: sync.RWMutex
-httpClient: BlockFetcher
+WriteBlock(block *BlockResponse, latest bool)
+GetBlock(height int) (*BlockResponse, error)
}
class BlockResponse {
+Height: int
+Hash: string
+Timestamp: int
}
class HTTPClient {
+GetBlock(height *int) (*coretypes.ResultBlock, error)
+BlockSearch(query string, page int, pageSize int) (*coretypes.ResultBlockSearch, error)
+BlockResults(height int) (BlockResults, error)
}
BlockService --> HTTPClient : uses
BlockService --> BlockResponse : caches
Summary
The [block.go](/projects/291/69210) file provides an essential service layer and HTTP client implementation for fetching, caching, and querying blockchain block data from a CometBFT node. It abstracts RPC calls, handles JSON unmarshalling, and caches blocks for efficient repeated access. It is a key component connecting blockchain data with higher-level application modules that require block information and results.