1
1
package graph
2
2
3
3
import (
4
+ "context"
4
5
"encoding/hex"
5
6
"errors"
6
7
"fmt"
8
+ "log"
7
9
"strconv"
8
10
"strings"
9
11
10
12
"github.com/ethereum/go-ethereum/common"
13
+ "github.com/gin-gonic/gin"
11
14
"github.com/itzmeanjan/ette/app/data"
15
+ _db "github.com/itzmeanjan/ette/app/db"
12
16
"github.com/itzmeanjan/ette/app/rest/graph/model"
13
17
"github.com/lib/pq"
14
18
"gorm.io/gorm"
@@ -22,12 +26,75 @@ func GetDatabaseConnection(conn *gorm.DB) {
22
26
db = conn
23
27
}
24
28
29
+ // Attempting to recover router context i.e. which holds client `APIKey` in request header,
30
+ // in graphql handler context, so that we can do some accounting job
31
+ func routerContextFromGraphQLContext (ctx context.Context ) (* gin.Context , error ) {
32
+
33
+ ginContext := ctx .Value ("RouterContextInGraphQL" )
34
+ if ginContext == nil {
35
+ return nil , errors .New ("Failed to retrieve router context" )
36
+ }
37
+
38
+ gc , ok := ginContext .(* gin.Context )
39
+ if ! ok {
40
+ return nil , errors .New ("Type assert of router context failed" )
41
+ }
42
+
43
+ return gc , nil
44
+
45
+ }
46
+
47
+ // Attempts to extract out `APIKey` used passed along
48
+ // with request, in graphql handler function, to be used for
49
+ // doing some book keeping work
50
+ func getAPIKey (ctx context.Context ) string {
51
+
52
+ routerCtx , err := routerContextFromGraphQLContext (ctx )
53
+ if err != nil {
54
+
55
+ log .Printf ("[!] Failed to get `APIKey` : %s\n " , err .Error ())
56
+ return ""
57
+
58
+ }
59
+
60
+ return routerCtx .GetHeader ("APIKey" )
61
+
62
+ }
63
+
64
+ // Attempts to recover `APIKey` from router context, which is
65
+ // then used for looking up user, so that data delivery information can
66
+ // be persisted into DB
67
+ func doBookKeeping (ctx context.Context , _data []byte ) error {
68
+
69
+ if _data == nil {
70
+ return errors .New ("JSON marshalling failed" )
71
+ }
72
+
73
+ user := _db .GetUserFromAPIKey (db , getAPIKey (ctx ))
74
+ if user == nil {
75
+ return errors .New ("Failed to get user from `APIKey`" )
76
+ }
77
+
78
+ _db .PutDataDeliveryInfo (db , user .Address , "/v1/graphql" , uint64 (len (_data )))
79
+ return nil
80
+
81
+ }
82
+
25
83
// Converting block data to graphQL compatible data structure
26
- func getGraphQLCompatibleBlock (block * data.Block ) (* model.Block , error ) {
84
+ func getGraphQLCompatibleBlock (ctx context.Context , block * data.Block , bookKeeping bool ) (* model.Block , error ) {
85
+
27
86
if block == nil {
28
87
return nil , errors .New ("Found nothing" )
29
88
}
30
89
90
+ // to be `false` when calling from `getGraphQLCompatibleBlocks(...)`
91
+ // because that function will then take care of it's own book keeping logic
92
+ if bookKeeping {
93
+ if err := doBookKeeping (ctx , block .ToJSON ()); err != nil {
94
+ return nil , errors .New ("Book keeping failed" )
95
+ }
96
+ }
97
+
31
98
return & model.Block {
32
99
Hash : block .Hash ,
33
100
Number : fmt .Sprintf ("%d" , block .Number ),
@@ -42,10 +109,11 @@ func getGraphQLCompatibleBlock(block *data.Block) (*model.Block, error) {
42
109
TxRootHash : block .TransactionRootHash ,
43
110
ReceiptRootHash : block .ReceiptRootHash ,
44
111
}, nil
112
+
45
113
}
46
114
47
115
// Converting block array to graphQL compatible data structure
48
- func getGraphQLCompatibleBlocks (blocks * data.Blocks ) ([]* model.Block , error ) {
116
+ func getGraphQLCompatibleBlocks (ctx context. Context , blocks * data.Blocks ) ([]* model.Block , error ) {
49
117
if blocks == nil {
50
118
return nil , errors .New ("Found nothing" )
51
119
}
@@ -54,18 +122,22 @@ func getGraphQLCompatibleBlocks(blocks *data.Blocks) ([]*model.Block, error) {
54
122
return nil , errors .New ("Found nothing" )
55
123
}
56
124
125
+ if err := doBookKeeping (ctx , blocks .ToJSON ()); err != nil {
126
+ return nil , errors .New ("Book keeping failed" )
127
+ }
128
+
57
129
_blocks := make ([]* model.Block , len (blocks .Blocks ))
58
130
59
131
for k , v := range blocks .Blocks {
60
- _v , _ := getGraphQLCompatibleBlock (v )
132
+ _v , _ := getGraphQLCompatibleBlock (ctx , v , false )
61
133
_blocks [k ] = _v
62
134
}
63
135
64
136
return _blocks , nil
65
137
}
66
138
67
139
// Converting transaction data to graphQL compatible data structure
68
- func getGraphQLCompatibleTransaction (tx * data.Transaction ) (* model.Transaction , error ) {
140
+ func getGraphQLCompatibleTransaction (ctx context. Context , tx * data.Transaction , bookKeeping bool ) (* model.Transaction , error ) {
69
141
if tx == nil {
70
142
return nil , errors .New ("Found nothing" )
71
143
}
@@ -75,6 +147,14 @@ func getGraphQLCompatibleTransaction(tx *data.Transaction) (*model.Transaction,
75
147
data = fmt .Sprintf ("0x%s" , _h )
76
148
}
77
149
150
+ // to be `false` when calling from `getGraphQLCompatibleTransactions(...)`
151
+ // because that function will then take care of it's own book keeping logic
152
+ if bookKeeping {
153
+ if err := doBookKeeping (ctx , tx .ToJSON ()); err != nil {
154
+ return nil , errors .New ("Book keeping failed" )
155
+ }
156
+ }
157
+
78
158
if ! strings .HasPrefix (tx .Contract , "0x" ) {
79
159
return & model.Transaction {
80
160
Hash : tx .Hash ,
@@ -109,7 +189,7 @@ func getGraphQLCompatibleTransaction(tx *data.Transaction) (*model.Transaction,
109
189
}
110
190
111
191
// Converting transaction array to graphQL compatible data structure
112
- func getGraphQLCompatibleTransactions (tx * data.Transactions ) ([]* model.Transaction , error ) {
192
+ func getGraphQLCompatibleTransactions (ctx context. Context , tx * data.Transactions ) ([]* model.Transaction , error ) {
113
193
if tx == nil {
114
194
return nil , errors .New ("Found nothing" )
115
195
}
@@ -118,18 +198,22 @@ func getGraphQLCompatibleTransactions(tx *data.Transactions) ([]*model.Transacti
118
198
return nil , errors .New ("Found nothing" )
119
199
}
120
200
201
+ if err := doBookKeeping (ctx , tx .ToJSON ()); err != nil {
202
+ return nil , errors .New ("Book keeping failed" )
203
+ }
204
+
121
205
_tx := make ([]* model.Transaction , len (tx .Transactions ))
122
206
123
207
for k , v := range tx .Transactions {
124
- _v , _ := getGraphQLCompatibleTransaction (v )
208
+ _v , _ := getGraphQLCompatibleTransaction (ctx , v , false )
125
209
_tx [k ] = _v
126
210
}
127
211
128
212
return _tx , nil
129
213
}
130
214
131
215
// Converting event data to graphQL compatible data structure
132
- func getGraphQLCompatibleEvent (event * data.Event ) (* model.Event , error ) {
216
+ func getGraphQLCompatibleEvent (ctx context. Context , event * data.Event , bookKeeping bool ) (* model.Event , error ) {
133
217
if event == nil {
134
218
return nil , errors .New ("Found nothing" )
135
219
}
@@ -139,6 +223,14 @@ func getGraphQLCompatibleEvent(event *data.Event) (*model.Event, error) {
139
223
data = fmt .Sprintf ("0x%s" , _h )
140
224
}
141
225
226
+ // to be `false` when calling from `getGraphQLCompatibleEvents(...)`
227
+ // because that function will then take care of it's own book keeping logic
228
+ if bookKeeping {
229
+ if err := doBookKeeping (ctx , event .ToJSON ()); err != nil {
230
+ return nil , errors .New ("Book keeping failed" )
231
+ }
232
+ }
233
+
142
234
return & model.Event {
143
235
Origin : event .Origin ,
144
236
Index : fmt .Sprintf ("%d" , event .Index ),
@@ -150,7 +242,7 @@ func getGraphQLCompatibleEvent(event *data.Event) (*model.Event, error) {
150
242
}
151
243
152
244
// Converting event array to graphQL compatible data structure
153
- func getGraphQLCompatibleEvents (events * data.Events ) ([]* model.Event , error ) {
245
+ func getGraphQLCompatibleEvents (ctx context. Context , events * data.Events ) ([]* model.Event , error ) {
154
246
if events == nil {
155
247
return nil , errors .New ("Found nothing" )
156
248
}
@@ -159,10 +251,14 @@ func getGraphQLCompatibleEvents(events *data.Events) ([]*model.Event, error) {
159
251
return nil , errors .New ("Found nothing" )
160
252
}
161
253
254
+ if err := doBookKeeping (ctx , events .ToJSON ()); err != nil {
255
+ return nil , errors .New ("Book keeping failed" )
256
+ }
257
+
162
258
_events := make ([]* model.Event , len (events .Events ))
163
259
164
260
for k , v := range events .Events {
165
- _v , _ := getGraphQLCompatibleEvent (v )
261
+ _v , _ := getGraphQLCompatibleEvent (ctx , v , false )
166
262
_events [k ] = _v
167
263
}
168
264
0 commit comments