Skip to content

Commit

Permalink
feat: add TxStatus rpc endpoint (#1178)
Browse files Browse the repository at this point in the history
## Description

Fixes - #1163

we've had some back and forth re this feature, and have decided to
implement this simple rpc endpoint as an interim solution while we
figure out and design an efficient way of querying transaction status
during its life cycle.

---------
  • Loading branch information
ninabarbakadze authored Mar 29, 2024
1 parent 1d70a8e commit e872424
Show file tree
Hide file tree
Showing 19 changed files with 515 additions and 11 deletions.
2 changes: 2 additions & 0 deletions consensus/replay_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
mempl "github.com/cometbft/cometbft/mempool"
"github.com/cometbft/cometbft/privval"
cmtstate "github.com/cometbft/cometbft/proto/tendermint/state"
cmtstore "github.com/cometbft/cometbft/proto/tendermint/store"
cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
"github.com/cometbft/cometbft/proxy"
sm "github.com/cometbft/cometbft/state"
Expand Down Expand Up @@ -1221,6 +1222,7 @@ func (bs *mockBlockStore) LoadBlockMeta(height int64) *types.BlockMeta {
func (bs *mockBlockStore) LoadBlockPart(height int64, index int) *types.Part { return nil }
func (bs *mockBlockStore) SaveBlock(block *types.Block, blockParts *types.PartSet, seenCommit *types.Commit) {
}
func (bs *mockBlockStore) LoadTxInfo(hash []byte) *cmtstore.TxInfo { return &cmtstore.TxInfo{} }

func (bs *mockBlockStore) LoadBlockCommit(height int64) *types.Commit {
return bs.commits[height-1]
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1452,6 +1452,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
9 changes: 9 additions & 0 deletions light/proxy/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ func RPCRoutes(c *lrpc.Client) map[string]*rpcserver.RPCFunc {
"consensus_params": rpcserver.NewRPCFunc(makeConsensusParamsFunc(c), "height", rpcserver.Cacheable("height")),
"unconfirmed_txs": rpcserver.NewRPCFunc(makeUnconfirmedTxsFunc(c), "limit"),
"num_unconfirmed_txs": rpcserver.NewRPCFunc(makeNumUnconfirmedTxsFunc(c), ""),
"tx_status": rpcserver.NewRPCFunc(makeTxStatusFunc(c), "hash"),

// tx broadcast API
"broadcast_tx_commit": rpcserver.NewRPCFunc(makeBroadcastTxCommitFunc(c), "tx"),
Expand Down Expand Up @@ -143,6 +144,14 @@ func makeBlockResultsFunc(c *lrpc.Client) rpcBlockResultsFunc {
}
}

type rpcTxStatusFunc func(ctx *rpctypes.Context, hash []byte) (*ctypes.ResultTxStatus, error)

func makeTxStatusFunc(c *lrpc.Client) rpcTxStatusFunc {
return func(ctx *rpctypes.Context, hash []byte) (*ctypes.ResultTxStatus, error) {
return c.TxStatus(ctx.Context(), hash)
}
}

type rpcCommitFunc func(ctx *rpctypes.Context, height *int64) (*ctypes.ResultCommit, error)

func makeCommitFunc(c *lrpc.Client) rpcCommitFunc {
Expand Down
5 changes: 5 additions & 0 deletions light/rpc/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,11 @@ func (c *Client) BlockResults(ctx context.Context, height *int64) (*ctypes.Resul
return res, nil
}

// TxStatus retrieves the status of the transaction given its hash.
func (c *Client) TxStatus(ctx context.Context, hash []byte) (*ctypes.ResultTxStatus, error) {
return c.next.TxStatus(ctx, hash)
}

// Header fetches and verifies the header directly via the light client
func (c *Client) Header(ctx context.Context, height *int64) (*ctypes.ResultHeader, error) {
lb, err := c.updateLightClientIfNeededTo(ctx, height)
Expand Down
203 changes: 197 additions & 6 deletions proto/tendermint/store/types.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions proto/tendermint/store/types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,9 @@ message BlockStoreState {
int64 base = 1;
int64 height = 2;
}

// TxInfo describes the location of a tx inside a committed block.
message TxInfo {
int64 height = 1;
int64 index = 2;
}
18 changes: 18 additions & 0 deletions rpc/client/http/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,24 @@ func (c *baseRPCClient) DataCommitment(
return result, nil
}

func (c *baseRPCClient) TxStatus(
ctx context.Context,
hash []byte,
) (*ctypes.ResultTxStatus, error) {
result := new(ctypes.ResultTxStatus)
params := map[string]interface{}{
"hash": hash,
}

_, err := c.caller.Call(ctx, "tx_status", params, result)
if err != nil {
return nil, err
}

return result, nil

}

func (c *baseRPCClient) DataRootInclusionProof(
ctx context.Context,
height uint64,
Expand Down
3 changes: 3 additions & 0 deletions rpc/client/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ type SignClient interface {
page, perPage *int,
orderBy string,
) (*ctypes.ResultBlockSearch, error)

// TxStatus returns the transaction status for a given transaction hash.
TxStatus(ctx context.Context, hash []byte) (*ctypes.ResultTxStatus, error)
}

// HistoryClient provides access to data from genesis to now in large chunks.
Expand Down
4 changes: 4 additions & 0 deletions rpc/client/local/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,10 @@ func (c *Local) BlockSearch(
return core.BlockSearch(c.ctx, query, page, perPage, orderBy)
}

func (c *Local) TxStatus(ctx context.Context, hash []byte) (*ctypes.ResultTxStatus, error) {
return core.TxStatus(c.ctx, hash)
}

func (c *Local) BroadcastEvidence(ctx context.Context, ev types.Evidence) (*ctypes.ResultBroadcastEvidence, error) {
return core.BroadcastEvidence(c.ctx, ev)
}
Expand Down
29 changes: 29 additions & 0 deletions rpc/client/rpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,35 @@ func TestBlockSearch(t *testing.T) {
require.Equal(t, blockCount, 0)

}

func TestTxStatus(t *testing.T) {
c := getHTTPClient()

// first we broadcast a few txs
var txHashes [][]byte
var txHeights []int64
for i := 0; i < 10; i++ {
_, _, tx := MakeTxKV()

result, err := c.BroadcastTxCommit(context.Background(), tx)
require.NoError(t, err)
txHashes = append(txHashes, result.Hash)
txHeights = append(txHeights, result.Height)
}

require.NoError(t, client.WaitForHeight(c, 5, nil))

// check the status of each transaction
for i, hash := range txHashes {
result, err := c.TxStatus(context.Background(), hash)
require.NoError(t, err)

expectedIndex := int64(0)
require.Equal(t, txHeights[i], result.Height)
require.Equal(t, expectedIndex, result.Index)
}
}

func TestTxSearch(t *testing.T) {
c := getHTTPClient()

Expand Down
Loading

0 comments on commit e872424

Please sign in to comment.