github.com/ari-anchor/sei-tendermint@v0.0.0-20230519144642-dc826b7b56bb/internal/rpc/core/tx.go (about) 1 package core 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "sort" 8 9 tmquery "github.com/ari-anchor/sei-tendermint/internal/pubsub/query" 10 "github.com/ari-anchor/sei-tendermint/internal/state/indexer" 11 tmmath "github.com/ari-anchor/sei-tendermint/libs/math" 12 "github.com/ari-anchor/sei-tendermint/rpc/coretypes" 13 "github.com/ari-anchor/sei-tendermint/types" 14 ) 15 16 // Tx allows you to query the transaction results. `nil` could mean the 17 // transaction is in the mempool, invalidated, or was not sent in the first 18 // place. 19 // More: https://docs.tendermint.com/master/rpc/#/Info/tx 20 func (env *Environment) Tx(ctx context.Context, req *coretypes.RequestTx) (*coretypes.ResultTx, error) { 21 // if index is disabled, return error 22 if !indexer.KVSinkEnabled(env.EventSinks) { 23 return nil, errors.New("transaction querying is disabled due to no kvEventSink") 24 } 25 26 for _, sink := range env.EventSinks { 27 if sink.Type() == indexer.KV { 28 r, err := sink.GetTxByHash(req.Hash) 29 if r == nil { 30 return nil, fmt.Errorf("tx (%X) not found, err: %w", req.Hash, err) 31 } 32 33 var proof types.TxProof 34 if req.Prove { 35 block := env.BlockStore.LoadBlock(r.Height) 36 proof = block.Data.Txs.Proof(int(r.Index)) 37 } 38 39 return &coretypes.ResultTx{ 40 Hash: req.Hash, 41 Height: r.Height, 42 Index: r.Index, 43 TxResult: r.Result, 44 Tx: r.Tx, 45 Proof: proof, 46 }, nil 47 } 48 } 49 50 return nil, fmt.Errorf("transaction querying is disabled on this node due to the KV event sink being disabled") 51 } 52 53 // TxSearch allows you to query for multiple transactions results. It returns a 54 // list of transactions (maximum ?per_page entries) and the total count. 55 // More: https://docs.tendermint.com/master/rpc/#/Info/tx_search 56 func (env *Environment) TxSearch(ctx context.Context, req *coretypes.RequestTxSearch) (*coretypes.ResultTxSearch, error) { 57 if !indexer.KVSinkEnabled(env.EventSinks) { 58 return nil, fmt.Errorf("transaction searching is disabled due to no kvEventSink") 59 } else if len(req.Query) > maxQueryLength { 60 return nil, errors.New("maximum query length exceeded") 61 } 62 63 q, err := tmquery.New(req.Query) 64 if err != nil { 65 return nil, err 66 } 67 68 for _, sink := range env.EventSinks { 69 if sink.Type() == indexer.KV { 70 results, err := sink.SearchTxEvents(ctx, q) 71 if err != nil { 72 return nil, err 73 } 74 75 // sort results (must be done before pagination) 76 switch req.OrderBy { 77 case "desc", "": 78 sort.Slice(results, func(i, j int) bool { 79 if results[i].Height == results[j].Height { 80 return results[i].Index > results[j].Index 81 } 82 return results[i].Height > results[j].Height 83 }) 84 case "asc": 85 sort.Slice(results, func(i, j int) bool { 86 if results[i].Height == results[j].Height { 87 return results[i].Index < results[j].Index 88 } 89 return results[i].Height < results[j].Height 90 }) 91 default: 92 return nil, fmt.Errorf("expected order_by to be either `asc` or `desc` or empty: %w", coretypes.ErrInvalidRequest) 93 } 94 95 // paginate results 96 totalCount := len(results) 97 perPage := env.validatePerPage(req.PerPage.IntPtr()) 98 99 page, err := validatePage(req.Page.IntPtr(), perPage, totalCount) 100 if err != nil { 101 return nil, err 102 } 103 104 skipCount := validateSkipCount(page, perPage) 105 pageSize := tmmath.MinInt(perPage, totalCount-skipCount) 106 107 apiResults := make([]*coretypes.ResultTx, 0, pageSize) 108 for i := skipCount; i < skipCount+pageSize; i++ { 109 r := results[i] 110 111 var proof types.TxProof 112 if req.Prove { 113 block := env.BlockStore.LoadBlock(r.Height) 114 proof = block.Data.Txs.Proof(int(r.Index)) 115 } 116 117 apiResults = append(apiResults, &coretypes.ResultTx{ 118 Hash: types.Tx(r.Tx).Hash(), 119 Height: r.Height, 120 Index: r.Index, 121 TxResult: r.Result, 122 Tx: r.Tx, 123 Proof: proof, 124 }) 125 } 126 127 return &coretypes.ResultTxSearch{Txs: apiResults, TotalCount: totalCount}, nil 128 } 129 } 130 131 return nil, fmt.Errorf("transaction searching is disabled on this node due to the KV event sink being disabled") 132 }