github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/bft/rpc/core/tx.go (about)

     1  package core
     2  
     3  import (
     4  	"fmt"
     5  
     6  	ctypes "github.com/gnolang/gno/tm2/pkg/bft/rpc/core/types"
     7  	rpctypes "github.com/gnolang/gno/tm2/pkg/bft/rpc/lib/types"
     8  	sm "github.com/gnolang/gno/tm2/pkg/bft/state"
     9  )
    10  
    11  // Tx allows you to query the transaction results. `nil` could mean the
    12  // transaction is in the mempool, invalidated, or was not sent in the first
    13  // place
    14  func Tx(_ *rpctypes.Context, hash []byte) (*ctypes.ResultTx, error) {
    15  	// Get the result index from storage, if any
    16  	resultIndex, err := sm.LoadTxResultIndex(stateDB, hash)
    17  	if err != nil {
    18  		return nil, err
    19  	}
    20  
    21  	// Sanity check the block height
    22  	height, err := getHeight(blockStore.Height(), &resultIndex.BlockNum)
    23  	if err != nil {
    24  		return nil, err
    25  	}
    26  
    27  	// Load the block
    28  	block := blockStore.LoadBlock(height)
    29  	numTxs := len(block.Txs)
    30  
    31  	if int(resultIndex.TxIndex) > numTxs || numTxs == 0 {
    32  		return nil, fmt.Errorf(
    33  			"unable to get block transaction for block %d, index %d",
    34  			resultIndex.BlockNum,
    35  			resultIndex.TxIndex,
    36  		)
    37  	}
    38  
    39  	rawTx := block.Txs[resultIndex.TxIndex]
    40  
    41  	// Fetch the block results
    42  	blockResults, err := sm.LoadABCIResponses(stateDB, resultIndex.BlockNum)
    43  	if err != nil {
    44  		return nil, fmt.Errorf("unable to load block results, %w", err)
    45  	}
    46  
    47  	// Grab the block deliver response
    48  	if len(blockResults.DeliverTxs) < int(resultIndex.TxIndex) {
    49  		return nil, fmt.Errorf(
    50  			"unable to get deliver result for block %d, index %d",
    51  			resultIndex.BlockNum,
    52  			resultIndex.TxIndex,
    53  		)
    54  	}
    55  
    56  	deliverResponse := blockResults.DeliverTxs[resultIndex.TxIndex]
    57  
    58  	// Craft the response
    59  	return &ctypes.ResultTx{
    60  		Hash:     hash,
    61  		Height:   resultIndex.BlockNum,
    62  		Index:    resultIndex.TxIndex,
    63  		TxResult: deliverResponse,
    64  		Tx:       rawTx,
    65  	}, nil
    66  }