/
cm40_query.go
133 lines (107 loc) · 3.09 KB
/
cm40_query.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package utils
import (
"encoding/hex"
"errors"
"fmt"
"strings"
"time"
codectypes "github.com/FiboChain/fbc/libs/cosmos-sdk/codec/types"
"github.com/FiboChain/fbc/libs/cosmos-sdk/client/context"
types "github.com/FiboChain/fbc/libs/cosmos-sdk/types/ibc-adapter"
ibc_tx "github.com/FiboChain/fbc/libs/cosmos-sdk/x/auth/ibc-tx"
ctypes "github.com/FiboChain/fbc/libs/tendermint/rpc/core/types"
)
func Query40Tx(cliCtx context.CLIContext, hashHexStr string) (*types.TxResponse, error) {
// strip 0x prefix
if strings.HasPrefix(hashHexStr, "0x") {
hashHexStr = hashHexStr[2:]
}
hash, err := hex.DecodeString(hashHexStr)
if err != nil {
return nil, err
}
node, err := cliCtx.GetNode()
if err != nil {
return nil, err
}
resTx, err := node.Tx(hash, !cliCtx.TrustNode)
if err != nil {
return nil, err
}
resBlocks, err := getBlocksForTxResults(cliCtx, []*ctypes.ResultTx{resTx})
if err != nil {
return nil, err
}
out, err := mk40TxResult(cliCtx, resTx, resBlocks[resTx.Height])
if err != nil {
return out, err
}
return out, nil
}
func Query40TxsByEvents(cliCtx context.CLIContext, events []string, page, limit int) (*types.SearchTxsResult, error) {
if len(events) == 0 {
return nil, errors.New("must declare at least one event to search")
}
if page <= 0 {
return nil, errors.New("page must greater than 0")
}
if limit <= 0 {
return nil, errors.New("limit must greater than 0")
}
// XXX: implement ANY
query := strings.Join(events, " AND ")
node, err := cliCtx.GetNode()
if err != nil {
return nil, err
}
prove := !cliCtx.TrustNode
resTxs, err := node.TxSearch(query, prove, page, limit, "")
if err != nil {
return nil, err
}
if prove {
for _, tx := range resTxs.Txs {
err := ValidateTxResult(cliCtx, tx)
if err != nil {
return nil, err
}
}
}
resBlocks, err := getBlocksForTxResults(cliCtx, resTxs.Txs)
if err != nil {
return nil, err
}
txs, err := format40TxResults(cliCtx, resTxs.Txs, resBlocks)
if err != nil {
return nil, err
}
result := types.NewSearchTxsResult(uint64(resTxs.TotalCount), uint64(len(txs)), uint64(page), uint64(limit), txs)
return result, nil
}
// formatTxResults parses the indexed txs into a slice of TxResponse objects.
func format40TxResults(cliCtx context.CLIContext, resTxs []*ctypes.ResultTx, resBlocks map[int64]*ctypes.ResultBlock) ([]*types.TxResponse, error) {
var err error
out := make([]*types.TxResponse, len(resTxs))
for i := range resTxs {
out[i], err = mk40TxResult(cliCtx, resTxs[i], resBlocks[resTxs[i].Height])
if err != nil {
return nil, err
}
}
return out, nil
}
func mk40TxResult(cliCtx context.CLIContext, resTx *ctypes.ResultTx, resBlock *ctypes.ResultBlock) (*types.TxResponse, error) {
txb, err := ibc_tx.CM40TxDecoder(cliCtx.CodecProy.GetProtocMarshal())(resTx.Tx)
if nil != err {
return nil, err
}
p, ok := txb.(intoAny)
if !ok {
return nil, fmt.Errorf("expecting a type implementing intoAny, got: %T", txb)
}
any := p.AsAny()
return types.NewResponseResultTx(resTx, any, resBlock.Block.Time.Format(time.RFC3339)), nil
}
type intoAny interface {
AsAny() *codectypes.Any
}