Skip to content

Commit 4714928

Browse files
committed
feat(): add sync data record
1 parent 9d8563e commit 4714928

File tree

3 files changed

+131
-3
lines changed

3 files changed

+131
-3
lines changed

client.go

+109
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
"fmt"
88
"github.com/inconshreveable/log15"
99
"github.com/panjf2000/ants/v2"
10+
"github.com/tidwall/gjson"
11+
"gopkg.in/h2non/gentleman.v2"
1012
"io/ioutil"
1113
"math/big"
1214
"net/http"
@@ -63,6 +65,9 @@ func (c *Client) SetTimeout(timeout time.Duration) {
6365

6466
func (c *Client) GetInfo() (info *types.NetworkInfo, err error) {
6567
body, code, err := c.httpGet("info")
68+
if code == 429 {
69+
return nil, ErrRequestLimit
70+
}
6671
if err != nil {
6772
return nil, ErrBadGateway
6873
}
@@ -77,6 +82,9 @@ func (c *Client) GetInfo() (info *types.NetworkInfo, err error) {
7782

7883
func (c *Client) GetPeers() ([]string, error) {
7984
body, code, err := c.httpGet("peers")
85+
if code == 429 {
86+
return nil, ErrRequestLimit
87+
}
8088
if err != nil {
8189
return nil, ErrBadGateway
8290
}
@@ -121,6 +129,8 @@ func (c *Client) GetTransactionByID(id string) (tx *types.Transaction, err error
121129
return nil, ErrInvalidId
122130
case 404:
123131
return nil, ErrNotFound
132+
case 429:
133+
return nil, ErrRequestLimit
124134
default:
125135
return nil, ErrBadGateway
126136
}
@@ -143,6 +153,8 @@ func (c *Client) GetTransactionStatus(id string) (*types.TxStatus, error) {
143153
return nil, ErrPendingTx
144154
case 404:
145155
return nil, ErrNotFound
156+
case 429:
157+
return nil, ErrRequestLimit
146158
default:
147159
return nil, ErrBadGateway
148160
}
@@ -163,6 +175,8 @@ func (c *Client) GetTransactionField(id string, field string) (string, error) {
163175
return "", ErrInvalidId
164176
case 404:
165177
return "", ErrNotFound
178+
case 429:
179+
return "", ErrRequestLimit
166180
default:
167181
return "", ErrBadGateway
168182
}
@@ -208,6 +222,8 @@ func (c *Client) GetTransactionData(id string, extension ...string) ([]byte, err
208222
return nil, ErrPendingTx
209223
case 404:
210224
return nil, ErrNotFound
225+
case 429:
226+
return nil, ErrRequestLimit
211227
default:
212228
return nil, ErrBadGateway
213229
}
@@ -231,6 +247,8 @@ func (c *Client) GetTransactionDataByGateway(id string) (body []byte, err error)
231247
return nil, ErrNotFound
232248
case 410:
233249
return nil, ErrInvalidId
250+
case 429:
251+
return nil, ErrRequestLimit
234252
default:
235253
return nil, ErrBadGateway
236254
}
@@ -243,6 +261,9 @@ func (c *Client) GetTransactionPrice(data []byte, target *string) (reward int64,
243261
}
244262

245263
body, code, err := c.httpGet(url)
264+
if code == 429 {
265+
return 0, ErrRequestLimit
266+
}
246267
if err != nil {
247268
return
248269
}
@@ -264,6 +285,9 @@ func (c *Client) GetTransactionPrice(data []byte, target *string) (reward int64,
264285

265286
func (c *Client) GetTransactionAnchor() (anchor string, err error) {
266287
body, code, err := c.httpGet("tx_anchor")
288+
if code == 429 {
289+
return "", ErrRequestLimit
290+
}
267291
if err != nil {
268292
return
269293
}
@@ -318,6 +342,9 @@ func (c *Client) GraphQL(query string) ([]byte, error) {
318342

319343
// query from http client
320344
data, statusCode, err := c.httpPost("graphql", byQuery)
345+
if statusCode == 429 {
346+
return nil, ErrRequestLimit
347+
}
321348
if err != nil {
322349
return nil, err
323350
}
@@ -340,6 +367,9 @@ func (c *Client) GraphQL(query string) ([]byte, error) {
340367
// Wallet
341368
func (c *Client) GetWalletBalance(address string) (arAmount *big.Float, err error) {
342369
body, code, err := c.httpGet(fmt.Sprintf("wallet/%s/balance", address))
370+
if code == 429 {
371+
return nil, ErrRequestLimit
372+
}
343373
if err != nil {
344374
return
345375
}
@@ -360,6 +390,9 @@ func (c *Client) GetWalletBalance(address string) (arAmount *big.Float, err erro
360390

361391
func (c *Client) GetLastTransactionID(address string) (id string, err error) {
362392
body, code, err := c.httpGet(fmt.Sprintf("wallet/%s/last_tx", address))
393+
if code == 429 {
394+
return "", ErrRequestLimit
395+
}
363396
if err != nil {
364397
return
365398
}
@@ -377,6 +410,9 @@ func (c *Client) GetBlockByID(id string) (block *types.Block, err error) {
377410
if err != nil {
378411
return
379412
}
413+
if code == 429 {
414+
return nil, ErrRequestLimit
415+
}
380416

381417
if code != 200 {
382418
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)
390426
if err != nil {
391427
return
392428
}
429+
if code == 429 {
430+
return nil, ErrRequestLimit
431+
}
393432

394433
if code != 200 {
395434
return nil, fmt.Errorf("get block by height error: %s", string(body))
@@ -468,6 +507,9 @@ func (c *Client) getChunkData(offset int64) ([]byte, error) {
468507
func (c *Client) getTransactionOffset(id string) (*types.TransactionOffset, error) {
469508
_path := fmt.Sprintf("tx/%s/offset", id)
470509
body, statusCode, err := c.httpGet(_path)
510+
if statusCode == 429 {
511+
return nil, ErrRequestLimit
512+
}
471513
if statusCode != 200 {
472514
return nil, errors.New("not found tx offset")
473515
}
@@ -664,3 +706,70 @@ func (c *Client) GetBlockHashList(from, to int) ([]string, error) {
664706
}
665707
return res, nil
666708
}
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+
}

client_test.go

+12-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package goar
33
import (
44
"github.com/everFinance/goar/utils"
55
"github.com/stretchr/testify/assert"
6+
"io/ioutil"
67
"testing"
78
)
89

@@ -308,12 +309,21 @@ func TestClient_GetBlockHashList2(t *testing.T) {
308309

309310
func TestClient_ConcurrentDownloadChunkData(t *testing.T) {
310311
c := NewClient("https://arweave.net")
311-
arId := "hG478oYzU0ReX8fCsRMcsm4ywuO4eiElCqDUAsm0nDk"
312+
arId := "6G_gCR5ZlFzg5Ek3DDTgwFFJhOKEowKJjHaA6Bt48VA"
312313
data, err := c.ConcurrentDownloadChunkData(arId, 0)
314+
// data , err := c.DownloadChunkData(arId)
313315
assert.NoError(t, err)
314-
// ioutil.WriteFile("nannan.jpeg",data,0777)
316+
ioutil.WriteFile("nannan.gif", data, 0666)
315317
chunks := utils.GenerateChunks(data)
316318
dataRoot := utils.Base64Encode(chunks.DataRoot)
317319
t.Log(dataRoot)
318320
t.Log(len(data))
319321
}
322+
323+
func TestClient_ExistTxData(t *testing.T) {
324+
c := NewClient("https://arweave.net")
325+
arId := "cAC7ave2lo3aixlC1wdvRBpGa3ELX_s2M2zJ03u0AwI"
326+
exist, err := c.ExistTxData(arId)
327+
assert.NoError(t, err)
328+
t.Log(exist)
329+
}

go.mod

+10-1
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,26 @@ require (
66
github.com/btcsuite/btcd/btcutil v1.1.3
77
github.com/ethereum/go-ethereum v1.10.20
88
github.com/everFinance/arseeding v1.0.3
9+
github.com/everFinance/everpay-go v0.0.1
910
github.com/everFinance/goether v1.1.8
1011
github.com/everFinance/gojwk v1.0.0
1112
github.com/everFinance/ttcrsa v1.1.3
1213
github.com/hamba/avro v1.5.6
1314
github.com/inconshreveable/log15 v0.0.0-20201112154412-8562bdadbbac
15+
github.com/panjf2000/ants/v2 v2.6.0
1416
github.com/shopspring/decimal v1.2.0
1517
github.com/stretchr/testify v1.8.0
18+
github.com/tidwall/gjson v1.14.1
1619
)
1720

1821
require (
1922
github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect
2023
github.com/davecgh/go-spew v1.1.1 // indirect
2124
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect
2225
github.com/everFinance/ethrpc v1.0.4 // indirect
26+
github.com/getsentry/sentry-go v0.11.0 // indirect
2327
github.com/go-stack/stack v1.8.1 // indirect
28+
github.com/google/uuid v1.3.0 // indirect
2429
github.com/jinzhu/inflection v1.0.0 // indirect
2530
github.com/jinzhu/now v1.1.4 // indirect
2631
github.com/json-iterator/go v1.1.11 // indirect
@@ -29,10 +34,14 @@ require (
2934
github.com/mattn/go-isatty v0.0.14 // indirect
3035
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
3136
github.com/modern-go/reflect2 v1.0.1 // indirect
32-
github.com/panjf2000/ants/v2 v2.6.0 // indirect
3337
github.com/pmezard/go-difflib v1.0.0 // indirect
38+
github.com/tidwall/match v1.1.1 // indirect
39+
github.com/tidwall/pretty v1.2.0 // indirect
40+
github.com/tidwall/sjson v1.2.4 // indirect
3441
golang.org/x/crypto v0.3.0 // indirect
42+
golang.org/x/net v0.2.0 // indirect
3543
golang.org/x/sys v0.2.0 // indirect
44+
gopkg.in/h2non/gentleman.v2 v2.0.5 // indirect
3645
gopkg.in/yaml.v3 v3.0.1 // indirect
3746
gorm.io/datatypes v1.0.1 // indirect
3847
gorm.io/gorm v1.22.4 // indirect

0 commit comments

Comments
 (0)