-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathblock.go
67 lines (57 loc) · 2.82 KB
/
block.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// Package sdk implements utility functions for interacting with POKT full nodes.
package sdk
import (
"context"
"errors"
"fmt"
ctypes "github.com/cometbft/cometbft/rpc/core/types"
cosmos "github.com/cosmos/cosmos-sdk/client"
)
// TODO_IDEA: The BlockClient could leverage websockets to get notified about new blocks
// and cache the latest block height to avoid querying the blockchain for it every time.
// BlockClient is a concrete type used to interact with the on-chain block module.
// For example, it can be used to get the latest block height.
//
// For obtaining the latest height, BlockClient uses a POKT full node's status
// which contains the latest block height. This is done to avoid fetching the
// entire latest block just to extract the block height.
type BlockClient struct {
// PoktNodeStatusFetcher specifies the functionality required by the
// BlockClient to interact with a POKT full node.
PoktNodeStatusFetcher
}
// LatestBlockHeight returns the height of the latest committed block in the blockchain.
func (bc *BlockClient) LatestBlockHeight(ctx context.Context) (height int64, err error) {
if bc.PoktNodeStatusFetcher == nil {
return 0, errors.New("LatestBlockHeight: nil PoktNodeStatusFetcher")
}
nodeStatus, err := bc.PoktNodeStatusFetcher.Status(ctx)
if err != nil {
return 0, err
}
return nodeStatus.SyncInfo.LatestBlockHeight, nil
}
// NewPoktNodeStatusFetcher returns the default implementation of the PoktNodeStatusFetcher interface.
// It connects, through a cometbft RPC HTTP client, to a POKT full node to get its status.
func NewPoktNodeStatusFetcher(queryNodeRpcUrl string) (PoktNodeStatusFetcher, error) {
// TODO_IMPROVE: drop the cosmos dependency and directly use cometbft rpchttp.New,
// once the latter publishes a release that includes this functionality.
// Directly using the cometbft will simplify the code by both reducing imported
// repos and removing the cosmos wrapper which we don't use.
// This can be done once there is a cometbft release that includes the following
// version: github.com/cometbft/cometbft v1.0.0-alpha.2.0.20240530055211-ae27f7eb3c08
statusFetcher, err := cosmos.NewClientFromNode(queryNodeRpcUrl)
if err != nil {
return nil, fmt.Errorf("error constructing a default POKT full node status fetcher: %w", err)
}
return statusFetcher, nil
}
// PoktNodeStatusFetcher interface is used by the BlockClient to get the status of a POKT full node.
// The BlokClient extracts the latest height from this status struct.
//
// Most users can rely on the default implementation provided by NewPoktNodeStatusFetcher function.
// A custom implementation of this interface can be used to gain more granular control
// over the interactions of the BlockClient with the POKT full node.
type PoktNodeStatusFetcher interface {
Status(ctx context.Context) (*ctypes.ResultStatus, error)
}