-
Notifications
You must be signed in to change notification settings - Fork 3.5k
/
data.go
159 lines (138 loc) · 5.03 KB
/
data.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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
package service
import (
"context"
"github.com/coinbase/rosetta-sdk-go/types"
"github.com/cosmos/cosmos-sdk/server/rosetta/lib/errors"
crgtypes "github.com/cosmos/cosmos-sdk/server/rosetta/lib/types"
)
// AccountBalance retrieves the account balance of an address
// rosetta requires us to fetch the block information too
func (on OnlineNetwork) AccountBalance(ctx context.Context, request *types.AccountBalanceRequest) (*types.AccountBalanceResponse, *types.Error) {
var (
height int64
block crgtypes.BlockResponse
err error
)
switch {
case request.BlockIdentifier == nil:
block, err = on.client.BlockByHeight(ctx, nil)
if err != nil {
return nil, errors.ToRosetta(err)
}
case request.BlockIdentifier.Hash != nil:
block, err = on.client.BlockByHash(ctx, *request.BlockIdentifier.Hash)
if err != nil {
return nil, errors.ToRosetta(err)
}
height = block.Block.Index
case request.BlockIdentifier.Index != nil:
height = *request.BlockIdentifier.Index
block, err = on.client.BlockByHeight(ctx, &height)
if err != nil {
return nil, errors.ToRosetta(err)
}
}
accountCoins, err := on.client.Balances(ctx, request.AccountIdentifier.Address, &height)
if err != nil {
return nil, errors.ToRosetta(err)
}
return &types.AccountBalanceResponse{
BlockIdentifier: block.Block,
Balances: accountCoins,
Metadata: nil,
}, nil
}
// Block gets the transactions in the given block
func (on OnlineNetwork) Block(ctx context.Context, request *types.BlockRequest) (*types.BlockResponse, *types.Error) {
var (
blockResponse crgtypes.BlockTransactionsResponse
err error
)
// block identifier is assumed not to be nil as rosetta will do this check for us
// check if we have to query via hash or block number
switch {
case request.BlockIdentifier.Hash != nil:
blockResponse, err = on.client.BlockTransactionsByHash(ctx, *request.BlockIdentifier.Hash)
if err != nil {
return nil, errors.ToRosetta(err)
}
case request.BlockIdentifier.Index != nil:
blockResponse, err = on.client.BlockTransactionsByHeight(ctx, request.BlockIdentifier.Index)
if err != nil {
return nil, errors.ToRosetta(err)
}
default:
err := errors.WrapError(errors.ErrBadArgument, "at least one of hash or index needs to be specified")
return nil, errors.ToRosetta(err)
}
return &types.BlockResponse{
Block: &types.Block{
BlockIdentifier: blockResponse.Block,
ParentBlockIdentifier: blockResponse.ParentBlock,
Timestamp: blockResponse.MillisecondTimestamp,
Transactions: blockResponse.Transactions,
Metadata: nil,
},
OtherTransactions: nil,
}, nil
}
// BlockTransaction gets the given transaction in the specified block, we do not need to check the block itself too
// due to the fact that tendermint achieves instant finality
func (on OnlineNetwork) BlockTransaction(ctx context.Context, request *types.BlockTransactionRequest) (*types.BlockTransactionResponse, *types.Error) {
tx, err := on.client.GetTx(ctx, request.TransactionIdentifier.Hash)
if err != nil {
return nil, errors.ToRosetta(err)
}
return &types.BlockTransactionResponse{
Transaction: tx,
}, nil
}
// Mempool fetches the transactions contained in the mempool
func (on OnlineNetwork) Mempool(ctx context.Context, _ *types.NetworkRequest) (*types.MempoolResponse, *types.Error) {
txs, err := on.client.Mempool(ctx)
if err != nil {
return nil, errors.ToRosetta(err)
}
return &types.MempoolResponse{
TransactionIdentifiers: txs,
}, nil
}
// MempoolTransaction fetches a single transaction in the mempool
// NOTE: it is not implemented yet
func (on OnlineNetwork) MempoolTransaction(ctx context.Context, request *types.MempoolTransactionRequest) (*types.MempoolTransactionResponse, *types.Error) {
tx, err := on.client.GetUnconfirmedTx(ctx, request.TransactionIdentifier.Hash)
if err != nil {
return nil, errors.ToRosetta(err)
}
return &types.MempoolTransactionResponse{
Transaction: tx,
}, nil
}
func (on OnlineNetwork) NetworkList(_ context.Context, _ *types.MetadataRequest) (*types.NetworkListResponse, *types.Error) {
return &types.NetworkListResponse{NetworkIdentifiers: []*types.NetworkIdentifier{on.network}}, nil
}
func (on OnlineNetwork) NetworkOptions(_ context.Context, _ *types.NetworkRequest) (*types.NetworkOptionsResponse, *types.Error) {
return on.networkOptions, nil
}
func (on OnlineNetwork) NetworkStatus(ctx context.Context, _ *types.NetworkRequest) (*types.NetworkStatusResponse, *types.Error) {
block, err := on.client.BlockByHeight(ctx, nil)
if err != nil {
return nil, errors.ToRosetta(err)
}
peers, err := on.client.Peers(ctx)
if err != nil {
return nil, errors.ToRosetta(err)
}
syncStatus, err := on.client.Status(ctx)
if err != nil {
return nil, errors.ToRosetta(err)
}
return &types.NetworkStatusResponse{
CurrentBlockIdentifier: block.Block,
CurrentBlockTimestamp: block.MillisecondTimestamp,
GenesisBlockIdentifier: on.genesisBlockIdentifier,
OldestBlockIdentifier: nil,
SyncStatus: syncStatus,
Peers: peers,
}, nil
}