github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/ibc-go/modules/core/client/query.go (about)

     1  package client
     2  
     3  import (
     4  	"fmt"
     5  
     6  	clictx "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/context"
     7  	clienttypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/02-client/types"
     8  	commitmenttypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/23-commitment/types"
     9  	host "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/24-host"
    10  	abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types"
    11  )
    12  
    13  // QueryTendermintProof performs an ABCI query with the given key and returns
    14  // the value of the query, the proto encoded merkle proof, and the height of
    15  // the Tendermint block containing the state root. The desired tendermint height
    16  // to perform the query should be set in the client context. The query will be
    17  // performed at one below this height (at the IAVL version) in order to obtain
    18  // the correct merkle proof. Proof queries at height less than or equal to 2 are
    19  // not supported. Queries with a client context height of 0 will perform a query
    20  // at the lastest state available.
    21  // Issue: https://github.com/cosmos/cosmos-sdk/issues/6567
    22  func QueryTendermintProof(clientCtx clictx.CLIContext, key []byte) ([]byte, []byte, clienttypes.Height, error) {
    23  	height := clientCtx.Height
    24  
    25  	// ABCI queries at heights 1, 2 or less than or equal to 0 are not supported.
    26  	// Base app does not support queries for height less than or equal to 1.
    27  	// Therefore, a query at height 2 would be equivalent to a query at height 3.
    28  	// A height of 0 will query with the lastest state.
    29  	if height != 0 && height <= 2 {
    30  		return nil, nil, clienttypes.Height{}, fmt.Errorf("proof queries at height <= 2 are not supported")
    31  	}
    32  
    33  	// Use the IAVL height if a valid tendermint height is passed in.
    34  	// A height of 0 will query with the latest state.
    35  	if height != 0 {
    36  		height--
    37  	}
    38  
    39  	req := abci.RequestQuery{
    40  		Path:   fmt.Sprintf("store/%s/key", host.StoreKey),
    41  		Height: height,
    42  		Data:   key,
    43  		Prove:  true,
    44  	}
    45  
    46  	res, err := clientCtx.QueryABCI(req)
    47  	if err != nil {
    48  		return nil, nil, clienttypes.Height{}, err
    49  	}
    50  
    51  	merkleProof, err := commitmenttypes.ConvertProofs(res.Proof)
    52  	if err != nil {
    53  		return nil, nil, clienttypes.Height{}, err
    54  	}
    55  
    56  	proofBz, err := clientCtx.CodecProy.GetProtocMarshal().MarshalBinaryBare(&merkleProof)
    57  	if err != nil {
    58  		return nil, nil, clienttypes.Height{}, err
    59  	}
    60  
    61  	revision := clienttypes.ParseChainID(clientCtx.ChainID)
    62  	return res.Value, proofBz, clienttypes.NewHeight(revision, uint64(res.Height)+1), nil
    63  }