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