github.com/cosmos/cosmos-sdk@v0.50.10/client/rpc/block.go (about) 1 package rpc 2 3 import ( 4 "context" 5 "encoding/hex" 6 "fmt" 7 "time" 8 9 cmt "github.com/cometbft/cometbft/proto/tendermint/types" 10 coretypes "github.com/cometbft/cometbft/rpc/core/types" 11 12 "github.com/cosmos/cosmos-sdk/client" 13 sdk "github.com/cosmos/cosmos-sdk/types" 14 ) 15 16 // GetChainHeight returns the current blockchain height. 17 func GetChainHeight(clientCtx client.Context) (int64, error) { 18 node, err := clientCtx.GetNode() 19 if err != nil { 20 return -1, err 21 } 22 23 status, err := node.Status(context.Background()) 24 if err != nil { 25 return -1, err 26 } 27 28 height := status.SyncInfo.LatestBlockHeight 29 return height, nil 30 } 31 32 // QueryBlocks performs a search for blocks based on BeginBlock and EndBlock 33 // events via the CometBFT RPC. A custom query may be passed as described below: 34 // 35 // To tell which events you want, you need to provide a query. query is a 36 // string, which has a form: "condition AND condition ..." (no OR at the 37 // moment). condition has a form: "key operation operand". key is a string with 38 // a restricted set of possible symbols ( \t\n\r\\()"'=>< are not allowed). 39 // operation can be "=", "<", "<=", ">", ">=", "CONTAINS" AND "EXISTS". operand 40 // can be a string (escaped with single quotes), number, date or time. 41 42 // Examples: 43 // tm.event = 'NewBlock' # new blocks 44 // tm.event = 'CompleteProposal' # node got a complete proposal 45 // tm.event = 'Tx' AND tx.hash = 'XYZ' # single transaction 46 // tm.event = 'Tx' AND tx.height = 5 # all txs of the fifth block 47 // tx.height = 5 # all txs of the fifth block 48 // 49 // For more information, see the /subscribe CometBFT RPC endpoint documentation 50 func QueryBlocks(clientCtx client.Context, page, limit int, query, orderBy string) (*sdk.SearchBlocksResult, error) { 51 node, err := clientCtx.GetNode() 52 if err != nil { 53 return nil, err 54 } 55 56 resBlocks, err := node.BlockSearch(context.Background(), query, &page, &limit, orderBy) 57 if err != nil { 58 return nil, err 59 } 60 61 blocks, err := formatBlockResults(resBlocks.Blocks) 62 if err != nil { 63 return nil, err 64 } 65 66 result := sdk.NewSearchBlocksResult(int64(resBlocks.TotalCount), int64(len(blocks)), int64(page), int64(limit), blocks) 67 68 return result, nil 69 } 70 71 // get block by height 72 func GetBlockByHeight(clientCtx client.Context, height *int64) (*cmt.Block, error) { 73 // get the node 74 node, err := clientCtx.GetNode() 75 if err != nil { 76 return nil, err 77 } 78 79 // header -> BlockchainInfo 80 // header, tx -> Block 81 // results -> BlockResults 82 resBlock, err := node.Block(context.Background(), height) 83 if err != nil { 84 return nil, err 85 } 86 87 out := sdk.NewResponseResultBlock(resBlock, resBlock.Block.Time.Format(time.RFC3339)) 88 if out == nil { 89 return nil, fmt.Errorf("unable to create response block from comet result block: %v", resBlock) 90 } 91 92 return out, nil 93 } 94 95 func GetBlockByHash(clientCtx client.Context, hashHexString string) (*cmt.Block, error) { 96 hash, err := hex.DecodeString(hashHexString) 97 if err != nil { 98 return nil, err 99 } 100 101 // get the node 102 node, err := clientCtx.GetNode() 103 if err != nil { 104 return nil, err 105 } 106 107 resBlock, err := node.BlockByHash(context.Background(), hash) 108 109 if err != nil { 110 return nil, err 111 } else if resBlock.Block == nil { 112 return nil, fmt.Errorf("block not found with hash: %s", hashHexString) 113 } 114 115 out := sdk.NewResponseResultBlock(resBlock, resBlock.Block.Time.Format(time.RFC3339)) 116 if out == nil { 117 return nil, fmt.Errorf("unable to create response block from comet result block: %v", resBlock) 118 } 119 120 return out, nil 121 } 122 123 // formatBlockResults parses the indexed blocks into a slice of BlockResponse objects. 124 func formatBlockResults(resBlocks []*coretypes.ResultBlock) ([]*cmt.Block, error) { 125 out := make([]*cmt.Block, len(resBlocks)) 126 for i := range resBlocks { 127 out[i] = sdk.NewResponseResultBlock(resBlocks[i], resBlocks[i].Block.Time.Format(time.RFC3339)) 128 if out[i] == nil { 129 return nil, fmt.Errorf("unable to create response block from comet result block: %v", resBlocks[i]) 130 } 131 } 132 133 return out, nil 134 }