7
7
"fmt"
8
8
"github.com/inconshreveable/log15"
9
9
"github.com/panjf2000/ants/v2"
10
+ "github.com/tidwall/gjson"
11
+ "gopkg.in/h2non/gentleman.v2"
10
12
"io/ioutil"
11
13
"math/big"
12
14
"net/http"
@@ -63,6 +65,9 @@ func (c *Client) SetTimeout(timeout time.Duration) {
63
65
64
66
func (c * Client ) GetInfo () (info * types.NetworkInfo , err error ) {
65
67
body , code , err := c .httpGet ("info" )
68
+ if code == 429 {
69
+ return nil , ErrRequestLimit
70
+ }
66
71
if err != nil {
67
72
return nil , ErrBadGateway
68
73
}
@@ -77,6 +82,9 @@ func (c *Client) GetInfo() (info *types.NetworkInfo, err error) {
77
82
78
83
func (c * Client ) GetPeers () ([]string , error ) {
79
84
body , code , err := c .httpGet ("peers" )
85
+ if code == 429 {
86
+ return nil , ErrRequestLimit
87
+ }
80
88
if err != nil {
81
89
return nil , ErrBadGateway
82
90
}
@@ -121,6 +129,8 @@ func (c *Client) GetTransactionByID(id string) (tx *types.Transaction, err error
121
129
return nil , ErrInvalidId
122
130
case 404 :
123
131
return nil , ErrNotFound
132
+ case 429 :
133
+ return nil , ErrRequestLimit
124
134
default :
125
135
return nil , ErrBadGateway
126
136
}
@@ -143,6 +153,8 @@ func (c *Client) GetTransactionStatus(id string) (*types.TxStatus, error) {
143
153
return nil , ErrPendingTx
144
154
case 404 :
145
155
return nil , ErrNotFound
156
+ case 429 :
157
+ return nil , ErrRequestLimit
146
158
default :
147
159
return nil , ErrBadGateway
148
160
}
@@ -163,6 +175,8 @@ func (c *Client) GetTransactionField(id string, field string) (string, error) {
163
175
return "" , ErrInvalidId
164
176
case 404 :
165
177
return "" , ErrNotFound
178
+ case 429 :
179
+ return "" , ErrRequestLimit
166
180
default :
167
181
return "" , ErrBadGateway
168
182
}
@@ -208,6 +222,8 @@ func (c *Client) GetTransactionData(id string, extension ...string) ([]byte, err
208
222
return nil , ErrPendingTx
209
223
case 404 :
210
224
return nil , ErrNotFound
225
+ case 429 :
226
+ return nil , ErrRequestLimit
211
227
default :
212
228
return nil , ErrBadGateway
213
229
}
@@ -231,6 +247,8 @@ func (c *Client) GetTransactionDataByGateway(id string) (body []byte, err error)
231
247
return nil , ErrNotFound
232
248
case 410 :
233
249
return nil , ErrInvalidId
250
+ case 429 :
251
+ return nil , ErrRequestLimit
234
252
default :
235
253
return nil , ErrBadGateway
236
254
}
@@ -243,6 +261,9 @@ func (c *Client) GetTransactionPrice(data []byte, target *string) (reward int64,
243
261
}
244
262
245
263
body , code , err := c .httpGet (url )
264
+ if code == 429 {
265
+ return 0 , ErrRequestLimit
266
+ }
246
267
if err != nil {
247
268
return
248
269
}
@@ -264,6 +285,9 @@ func (c *Client) GetTransactionPrice(data []byte, target *string) (reward int64,
264
285
265
286
func (c * Client ) GetTransactionAnchor () (anchor string , err error ) {
266
287
body , code , err := c .httpGet ("tx_anchor" )
288
+ if code == 429 {
289
+ return "" , ErrRequestLimit
290
+ }
267
291
if err != nil {
268
292
return
269
293
}
@@ -318,6 +342,9 @@ func (c *Client) GraphQL(query string) ([]byte, error) {
318
342
319
343
// query from http client
320
344
data , statusCode , err := c .httpPost ("graphql" , byQuery )
345
+ if statusCode == 429 {
346
+ return nil , ErrRequestLimit
347
+ }
321
348
if err != nil {
322
349
return nil , err
323
350
}
@@ -340,6 +367,9 @@ func (c *Client) GraphQL(query string) ([]byte, error) {
340
367
// Wallet
341
368
func (c * Client ) GetWalletBalance (address string ) (arAmount * big.Float , err error ) {
342
369
body , code , err := c .httpGet (fmt .Sprintf ("wallet/%s/balance" , address ))
370
+ if code == 429 {
371
+ return nil , ErrRequestLimit
372
+ }
343
373
if err != nil {
344
374
return
345
375
}
@@ -360,6 +390,9 @@ func (c *Client) GetWalletBalance(address string) (arAmount *big.Float, err erro
360
390
361
391
func (c * Client ) GetLastTransactionID (address string ) (id string , err error ) {
362
392
body , code , err := c .httpGet (fmt .Sprintf ("wallet/%s/last_tx" , address ))
393
+ if code == 429 {
394
+ return "" , ErrRequestLimit
395
+ }
363
396
if err != nil {
364
397
return
365
398
}
@@ -377,6 +410,9 @@ func (c *Client) GetBlockByID(id string) (block *types.Block, err error) {
377
410
if err != nil {
378
411
return
379
412
}
413
+ if code == 429 {
414
+ return nil , ErrRequestLimit
415
+ }
380
416
381
417
if code != 200 {
382
418
return nil , fmt .Errorf ("get block by id error: %s" , string (body ))
@@ -390,6 +426,9 @@ func (c *Client) GetBlockByHeight(height int64) (block *types.Block, err error)
390
426
if err != nil {
391
427
return
392
428
}
429
+ if code == 429 {
430
+ return nil , ErrRequestLimit
431
+ }
393
432
394
433
if code != 200 {
395
434
return nil , fmt .Errorf ("get block by height error: %s" , string (body ))
@@ -468,6 +507,9 @@ func (c *Client) getChunkData(offset int64) ([]byte, error) {
468
507
func (c * Client ) getTransactionOffset (id string ) (* types.TransactionOffset , error ) {
469
508
_path := fmt .Sprintf ("tx/%s/offset" , id )
470
509
body , statusCode , err := c .httpGet (_path )
510
+ if statusCode == 429 {
511
+ return nil , ErrRequestLimit
512
+ }
471
513
if statusCode != 200 {
472
514
return nil , errors .New ("not found tx offset" )
473
515
}
@@ -664,3 +706,70 @@ func (c *Client) GetBlockHashList(from, to int) ([]string, error) {
664
706
}
665
707
return res , nil
666
708
}
709
+
710
+ func (c * Client ) ExistTxData (arId string ) (bool , error ) {
711
+ offsetResponse , err := c .getTransactionOffset (arId )
712
+ if err != nil {
713
+ return false , err
714
+ }
715
+ endOffset := offsetResponse .Offset
716
+
717
+ records , err := c .DataSyncRecord (endOffset , 1 )
718
+ if err != nil {
719
+ return false , err
720
+ }
721
+ if len (records ) == 0 {
722
+ return false , errors .New ("c.DataSyncRecord(endOffset,1) is null" )
723
+ }
724
+ record := records [0 ]
725
+
726
+ // if tx data has end offset 145 and size 10 (you can see it in GET /tx/<id>/offset),
727
+ // you can query GET /data_sync_record/145/1
728
+ // - you will receive {"<end>": "<start>"} => the node has the tx data if start =< 145 - 10
729
+ mmp := gjson .Parse (record ).Map ()
730
+ start := ""
731
+ for _ , val := range mmp {
732
+ start = val .String ()
733
+ break
734
+ }
735
+ startNum , err := strconv .Atoi (start )
736
+ if err != nil {
737
+ return false , err
738
+ }
739
+ endOffsetNum , err := strconv .Atoi (endOffset )
740
+ if err != nil {
741
+ return false , err
742
+ }
743
+ sizeNum , err := strconv .Atoi (offsetResponse .Size )
744
+ if err != nil {
745
+ return false , err
746
+ }
747
+
748
+ return startNum <= endOffsetNum - sizeNum , nil
749
+ }
750
+
751
+ // DataSyncRecord you can use GET /data_sync_record/<end_offset>/<number_of_intervals>
752
+ // to fetch the first intervals with end offset >= end_offset;
753
+ // set Content-Type: application/json to get the reply in JSON
754
+ func (c * Client ) DataSyncRecord (endOffset string , intervalsNum int ) ([]string , error ) {
755
+ req := gentleman .New ().URL (c .url ).Request ()
756
+ req .AddPath ("/data_sync_record/" + endOffset + "/" + strconv .Itoa (intervalsNum ))
757
+ req .SetHeader ("Content-Type" , "application/json" )
758
+ resp , err := req .Send ()
759
+ if err != nil {
760
+ return nil , err
761
+ }
762
+ if resp .StatusCode == 429 {
763
+ return nil , ErrRequestLimit
764
+ }
765
+ if ! resp .Ok {
766
+ return nil , errors .New ("resp ok is false" )
767
+ }
768
+ defer resp .Close ()
769
+ ss := gjson .ParseBytes (resp .Bytes ()).Array ()
770
+ result := make ([]string , 0 , len (ss ))
771
+ for _ , s := range ss {
772
+ result = append (result , s .String ())
773
+ }
774
+ return result , nil
775
+ }
0 commit comments