From 1b5a530f5692beac71a5d1825b71986cc6669012 Mon Sep 17 00:00:00 2001 From: "Laisky.Cai" Date: Mon, 20 May 2024 06:16:06 +0000 Subject: [PATCH] fix: Implement context-aware APIs for better concurrency and robustness closes #56 Here is the commit message: **Summary** This commit adds support for context parameters to various functions across the codebase, enabling cancellation of long-running operations and improving error handling. **Key Changes** - Added context support to various functions, such as `GetTransactionData`, `BroadcastData`, `Send*`, and `WarpTransfer`, allowing for cancellation and improved error handling. - Updated multiple files to use the `context` package and its functions. - Modified several functions to take a `context.Context` as an argument, enabling cancellation and better error handling. --- client.go | 30 +++++++++++++++++----------- client_broadcast.go | 6 ++++-- client_test.go | 11 ++++++---- example/api_example_test.go | 7 +++++-- example/chunks_tx_test.go | 14 ++++++++----- example/local_data_test.go | 7 +++++-- types/const.go | 16 +++++++-------- types/types.go | 2 +- uploader.go | 24 +++++++++++----------- utils/hash_test.go | 4 ++-- utils/tags_test.go | 8 ++++---- wallet.go | 40 ++++++++++++++++++------------------- wallet_test.go | 7 +++++-- warp.go | 10 ++++++---- 14 files changed, 106 insertions(+), 80 deletions(-) diff --git a/client.go b/client.go index ec64767..64c1489 100644 --- a/client.go +++ b/client.go @@ -2,6 +2,7 @@ package goar import ( "bytes" + "context" "encoding/json" "errors" "fmt" @@ -372,38 +373,38 @@ func (c *Client) GetTransactionAnchor() (anchor string, err error) { return } -func (c *Client) SubmitTransaction(tx *types.Transaction) (status string, code int, err error) { +func (c *Client) SubmitTransaction(ctx context.Context, tx *types.Transaction) (status string, code int, err error) { by, err := json.Marshal(tx) if err != nil { return } - body, statusCode, err := c.httpPost("tx", by) + body, statusCode, err := c.httpPost(ctx, "tx", by) status = string(body) code = statusCode return } -func (c *Client) SubmitChunks(gc *types.GetChunk) (status string, code int, err error) { +func (c *Client) SubmitChunks(ctx context.Context, gc *types.GetChunk) (status string, code int, err error) { byteGc, err := gc.Marshal() if err != nil { return } var body []byte - body, code, err = c.httpPost("chunk", byteGc) + body, code, err = c.httpPost(ctx, "chunk", byteGc) status = string(body) return } // Arql is Deprecated, recommended to use GraphQL -func (c *Client) Arql(arql string) (ids []string, err error) { - body, _, err := c.httpPost("arql", []byte(arql)) +func (c *Client) Arql(ctx context.Context, arql string) (ids []string, err error) { + body, _, err := c.httpPost(ctx, "arql", []byte(arql)) err = json.Unmarshal(body, &ids) return } -func (c *Client) GraphQL(query string) ([]byte, error) { +func (c *Client) GraphQL(ctx context.Context, query string) ([]byte, error) { // generate query graQuery := struct { Query string `json:"query"` @@ -414,7 +415,7 @@ func (c *Client) GraphQL(query string) ([]byte, error) { } // query from http client - data, statusCode, err := c.httpPost("graphql", byQuery) + data, statusCode, err := c.httpPost(ctx, "graphql", byQuery) if statusCode == 429 { return nil, ErrRequestLimit } @@ -529,7 +530,7 @@ func (c *Client) httpGet(_path string) (body []byte, statusCode int, err error) return } -func (c *Client) httpPost(_path string, payload []byte) (body []byte, statusCode int, err error) { +func (c *Client) httpPost(ctx context.Context, _path string, payload []byte) (body []byte, statusCode int, err error) { u, err := url.Parse(c.url) if err != nil { return @@ -537,7 +538,12 @@ func (c *Client) httpPost(_path string, payload []byte) (body []byte, statusCode u.Path = path.Join(u.Path, _path) - resp, err := c.client.Post(u.String(), "application/json", bytes.NewReader(payload)) + req, err := http.NewRequestWithContext(ctx, "POST", u.String(), bytes.NewReader(payload)) + if err != nil { + return + } + + resp, err := c.client.Do(req) if err != nil { return } @@ -1029,7 +1035,7 @@ func (c *Client) DataSyncRecord(endOffset string, intervalsNum int) ([]string, e return result, nil } -func (c *Client) SubmitToWarp(tx *types.Transaction) ([]byte, error) { +func (c *Client) SubmitToWarp(ctx context.Context, tx *types.Transaction) ([]byte, error) { by, err := json.Marshal(tx) if err != nil { return nil, err @@ -1040,7 +1046,7 @@ func (c *Client) SubmitToWarp(tx *types.Transaction) ([]byte, error) { } u.Path = path.Join(u.Path, "/gateway/sequencer/register") - req, err := http.NewRequest("POST", u.String(), bytes.NewReader(by)) + req, err := http.NewRequestWithContext(ctx, "POST", u.String(), bytes.NewReader(by)) if err != nil { return nil, err } diff --git a/client_broadcast.go b/client_broadcast.go index 4dd7463..d3ce788 100644 --- a/client_broadcast.go +++ b/client_broadcast.go @@ -1,12 +1,14 @@ package goar import ( + "context" "errors" "fmt" + "github.com/everFinance/goar/types" ) -func (c *Client) BroadcastData(txId string, data []byte, numOfNodes int64, peers ...string) error { +func (c *Client) BroadcastData(ctx context.Context, txId string, data []byte, numOfNodes int64, peers ...string) error { var err error if len(peers) == 0 { peers, err = c.GetPeers() @@ -24,7 +26,7 @@ func (c *Client) BroadcastData(txId string, data []byte, numOfNodes int64, peers continue } - if err = uploader.Once(); err != nil { + if err = uploader.Once(ctx); err != nil { continue } diff --git a/client_test.go b/client_test.go index 2114a1a..cb7050f 100644 --- a/client_test.go +++ b/client_test.go @@ -1,12 +1,14 @@ package goar import ( - "github.com/everFinance/goar/types" - "github.com/everFinance/goar/utils" - "github.com/stretchr/testify/assert" + "context" "os" "strconv" "testing" + + "github.com/everFinance/goar/types" + "github.com/everFinance/goar/utils" + "github.com/stretchr/testify/assert" ) // func TestGetTransactionByID(t *testing.T) { @@ -219,12 +221,13 @@ func Test_GetTxDataFromPeers(t *testing.T) { } func TestClient_BroadcastData(t *testing.T) { + ctx := context.Background() cli := NewClient("https://arweave.net") txId := "J5FY1Ovd6JJ49WFHfCf-1wDM1TbaPSdKnGIB_8ePErE" data, err := cli.GetTransactionData(txId, "json") assert.NoError(t, err) - err = cli.BroadcastData(txId, data, 20) + err = cli.BroadcastData(ctx, txId, data, 20) assert.NoError(t, err) } diff --git a/example/api_example_test.go b/example/api_example_test.go index c0ea9d9..d03289c 100644 --- a/example/api_example_test.go +++ b/example/api_example_test.go @@ -1,9 +1,11 @@ package example import ( + "context" + "testing" + "github.com/everFinance/goar/types" "github.com/everFinance/goar/utils" - "testing" "github.com/everFinance/goar" "github.com/stretchr/testify/assert" @@ -63,6 +65,7 @@ func Test_Arq1(t *testing.T) { } func Test_Arq(t *testing.T) { + ctx := context.Background() arqStr := `{ "op": "and", "expr1": { @@ -79,7 +82,7 @@ func Test_Arq(t *testing.T) { // create client arNode := "https://arweave.net" c := goar.NewClient(arNode) - ids, err := c.Arql(arqStr) + ids, err := c.Arql(ctx, arqStr) t.Log(len(ids)) assert.NoError(t, err) sstr := make([]string, 0) diff --git a/example/chunks_tx_test.go b/example/chunks_tx_test.go index ce1282f..cc707cf 100644 --- a/example/chunks_tx_test.go +++ b/example/chunks_tx_test.go @@ -1,6 +1,7 @@ package example import ( + "context" "crypto/rand" "crypto/rsa" "crypto/sha256" @@ -71,6 +72,7 @@ func assemblyDataTx(bigData []byte, wallet *goar.Wallet, tags []types.Tag) (*typ // test upload post big size data by chunks func Test_PostBigDataByChunks(t *testing.T) { + ctx := context.Background() filePath := "./testFile/2mbFile.pdf" bigData, err := os.ReadFile(filePath) assert.NoError(t, err) @@ -83,11 +85,12 @@ func Test_PostBigDataByChunks(t *testing.T) { // uploader Transaction uploader, err := goar.CreateUploader(wallet.Client, tx, nil) assert.NoError(t, err) - assert.NoError(t, uploader.Once()) + assert.NoError(t, uploader.Once(ctx)) } // test retry upload(断点重传) post big size data by tx id func Test_RetryUploadDataByTxId(t *testing.T) { + ctx := context.Background() filePath := "./testFile/3mPhoto.jpg" bigData, err := os.ReadFile(filePath) assert.NoError(t, err) @@ -100,7 +103,7 @@ func Test_RetryUploadDataByTxId(t *testing.T) { // 1. post this tx without data tx.Data = "" - body, status, err := wallet.Client.SubmitTransaction(tx) + body, status, err := wallet.Client.SubmitTransaction(ctx, tx) assert.NoError(t, err) t.Logf("post tx without data; body: %s, status: %d", string(body), status) @@ -124,11 +127,12 @@ func Test_RetryUploadDataByTxId(t *testing.T) { // get uploader by txId and post big data by chunks uploader, err := goar.CreateUploader(wallet.Client, tx.ID, bigData) assert.NoError(t, err) - assert.NoError(t, uploader.Once()) + assert.NoError(t, uploader.Once(ctx)) } // test continue upload(断点续传) big size data by last time uploader func Test_ContinueUploadDataByLastUploader(t *testing.T) { + ctx := context.Background() filePath := "./testFile/1.8mPhoto.jpg" bigData, err := os.ReadFile(filePath) assert.NoError(t, err) @@ -143,7 +147,7 @@ func Test_ContinueUploadDataByLastUploader(t *testing.T) { assert.NoError(t, err) // only upload 2 chunks to ar chain for !uploader.IsComplete() && uploader.ChunkIndex <= 2 { - err := uploader.UploadChunk() + err := uploader.UploadChunk(ctx) assert.NoError(t, err) } @@ -165,7 +169,7 @@ func Test_ContinueUploadDataByLastUploader(t *testing.T) { // new uploader object by last time uploader newUploader, err := goar.CreateUploader(wallet.Client, lastUploader.FormatSerializedUploader(), bigData) assert.NoError(t, err) - assert.NoError(t, newUploader.Once()) + assert.NoError(t, newUploader.Once(ctx)) // end remove jsonUploaderFile.json file _ = os.Remove("./jsonUploaderFile.json") diff --git a/example/local_data_test.go b/example/local_data_test.go index b2de6d1..eb24605 100644 --- a/example/local_data_test.go +++ b/example/local_data_test.go @@ -1,6 +1,7 @@ package example import ( + "context" "os" "testing" @@ -10,6 +11,7 @@ import ( ) func Test_SendData(t *testing.T) { + ctx := context.Background() arNode := "https://arweave.net" w, err := goar.NewWalletFromPath("./wallet/account1.json", arNode) // your wallet private key assert.NoError(t, err) @@ -22,7 +24,7 @@ func Test_SendData(t *testing.T) { {Name: "xxxx", Value: "sssss"}, {Name: "yyyyyy", Value: "kkkkkk"}, } - tx, err := w.SendDataSpeedUp(data, tags, 10) + tx, err := w.SendDataSpeedUp(ctx, data, tags, 10) assert.NoError(t, err) t.Logf("tx hash: %s", tx.ID) } @@ -61,6 +63,7 @@ func TestConcurrentDownloadStream(t *testing.T) { } func TestSendDataStream(t *testing.T) { + ctx := context.Background() arNode := "https://arweave.net" w, err := goar.NewWalletFromPath("./testKey.json", arNode) // your wallet private key assert.NoError(t, err) @@ -73,7 +76,7 @@ func TestSendDataStream(t *testing.T) { {Name: "Content-Type", Value: "img/jpeg"}, {Name: "test", Value: "kevin-test"}, } - tx, err := w.SendDataStreamSpeedUp(data, tags, 10) + tx, err := w.SendDataStreamSpeedUp(ctx, data, tags, 10) assert.NoError(t, err) t.Log(tx.ID) // test arId: k5IgHLTag_3bB6Sp5tTUhrFrPPvU5MjevV468dfxNKk diff --git a/types/const.go b/types/const.go index 886bb1e..939dce1 100644 --- a/types/const.go +++ b/types/const.go @@ -37,14 +37,14 @@ const ( // Errors from /chunk we should never try and continue on. var FATAL_CHUNK_UPLOAD_ERRORS = map[string]struct{}{ - "{\"error\":\"disk_full\"}": struct{}{}, - "{\"error\":\"invalid_json\"}": struct{}{}, - "{\"error\":\"chunk_too_big\"}": struct{}{}, - "{\"error\":\"data_path_too_big\"}": struct{}{}, - "{\"error\":\"offset_too_big\"}": struct{}{}, - "{\"error\":\"data_size_too_big\"}": struct{}{}, - "{\"error\":\"chunk_proof_ratio_not_attractive\"}": struct{}{}, - "{\"error\":\"invalid_proof\"}": struct{}{}, + "{\"error\":\"disk_full\"}": {}, + "{\"error\":\"invalid_json\"}": {}, + "{\"error\":\"chunk_too_big\"}": {}, + "{\"error\":\"data_path_too_big\"}": {}, + "{\"error\":\"offset_too_big\"}": {}, + "{\"error\":\"data_size_too_big\"}": {}, + "{\"error\":\"chunk_proof_ratio_not_attractive\"}": {}, + "{\"error\":\"invalid_proof\"}": {}, } // about bundle diff --git a/types/types.go b/types/types.go index 2fbd12f..ef1ce1d 100644 --- a/types/types.go +++ b/types/types.go @@ -35,5 +35,5 @@ type BundlrResp struct { N string `json:"n"` Public string `json:"public"` Block int64 `json:"block"` - ValidatorSignatures []string `json:"validatorSignatures"` + ValidatorSignatures []string `json:"validatorSignatures"` } diff --git a/uploader.go b/uploader.go index d5b55d8..0d10ed5 100644 --- a/uploader.go +++ b/uploader.go @@ -116,9 +116,9 @@ func CreateUploader(api *Client, upload interface{}, data []byte) (*TransactionU return uploader, err } -func (tt *TransactionUploader) Once() (err error) { +func (tt *TransactionUploader) Once(ctx context.Context) (err error) { for !tt.IsComplete() { - if err = tt.UploadChunk(); err != nil { + if err = tt.UploadChunk(ctx); err != nil { return } @@ -159,7 +159,7 @@ func (tt *TransactionUploader) PctComplete() float64 { func (tt *TransactionUploader) ConcurrentOnce(ctx context.Context, concurrentNum int) error { // post tx info - if err := tt.postTransaction(); err != nil { + if err := tt.postTransaction(ctx); err != nil { return err } @@ -193,7 +193,7 @@ func (tt *TransactionUploader) ConcurrentOnce(ctx context.Context, concurrentNum log.Error("GetChunk error", "err", err, "idx", idx) return } - body, statusCode, err := tt.Client.SubmitChunks(chunk) // always body is errMsg + body, statusCode, err := tt.Client.SubmitChunks(ctx, chunk) // always body is errMsg if statusCode == 200 { return } @@ -216,7 +216,7 @@ func (tt *TransactionUploader) ConcurrentOnce(ctx context.Context, concurrentNum time.Sleep(200 * time.Millisecond) } - body, statusCode, err = tt.Client.SubmitChunks(chunk) + body, statusCode, err = tt.Client.SubmitChunks(ctx, chunk) if statusCode == 200 { return } @@ -243,7 +243,7 @@ func (tt *TransactionUploader) ConcurrentOnce(ctx context.Context, concurrentNum * itself and on any subsequent calls uploads the * next chunk until it completes. */ -func (tt *TransactionUploader) UploadChunk() error { +func (tt *TransactionUploader) UploadChunk(ctx context.Context) error { defer func() { // if tt.TotalChunks() > 0 { // log.Debug("chunks", "uploads", fmt.Sprintf("%f%% completes, %d/%d", tt.PctComplete(), tt.UploadedChunks(), tt.TotalChunks())) @@ -278,7 +278,7 @@ func (tt *TransactionUploader) UploadChunk() error { tt.LastResponseError = "" if !tt.TxPosted { - return tt.postTransaction() + return tt.postTransaction(ctx) } var chunk *types.GetChunk @@ -317,7 +317,7 @@ func (tt *TransactionUploader) UploadChunk() error { if err != nil { return err } - body, statusCode, err := tt.Client.SubmitChunks(gc) // always body is errMsg + body, statusCode, err := tt.Client.SubmitChunks(ctx, gc) // always body is errMsg tt.LastRequestTimeEnd = time.Now().UnixNano() / 1000000 tt.LastResponseStatus = statusCode if statusCode == 200 { @@ -409,17 +409,17 @@ func (tt *TransactionUploader) FormatSerializedUploader() *SerializedUploader { } // POST to /tx -func (tt *TransactionUploader) postTransaction() error { +func (tt *TransactionUploader) postTransaction(ctx context.Context) error { var uploadInBody = tt.TotalChunks() <= types.MAX_CHUNKS_IN_BODY - return tt.uploadTx(uploadInBody) + return tt.uploadTx(ctx, uploadInBody) } -func (tt *TransactionUploader) uploadTx(withBody bool) error { +func (tt *TransactionUploader) uploadTx(ctx context.Context, withBody bool) error { // if withBody { // // Post the Transaction with Data. // tt.Transaction.Data = utils.Base64Encode(tt.Data) // } - body, statusCode, err := tt.Client.SubmitTransaction(tt.Transaction) + body, statusCode, err := tt.Client.SubmitTransaction(ctx, tt.Transaction) if err != nil || statusCode >= 400 { tt.LastResponseError = fmt.Sprintf("%v,%s", err, body) tt.LastResponseStatus = statusCode diff --git a/utils/hash_test.go b/utils/hash_test.go index 7b3f6f8..a3e0fb8 100644 --- a/utils/hash_test.go +++ b/utils/hash_test.go @@ -17,11 +17,11 @@ func TestDeepHash(t *testing.T) { assert.Equal(t, [48]uint8{0xe7, 0xb, 0xed, 0x22, 0x75, 0xe0, 0x4, 0xd, 0xf5, 0x3c, 0x97, 0xe9, 0x3f, 0x97, 0xa9, 0x5f, 0xa, 0x4d, 0x29, 0xc8, 0x5d, 0x76, 0x5f, 0x54, 0x9a, 0x32, 0x74, 0xb6, 0x6b, 0xf, 0x55, 0xa4, 0xb9, 0x2f, 0x23, 0x73, 0x34, 0xda, 0x1f, 0x25, 0xc1, 0xac, 0x59, 0x14, 0xfb, 0xe0, 0xfb, 0x89}, DeepHash(dataList)) dataList = append(dataList, [][]string{ - []string{ + { Base64Encode([]byte("APP")), Base64Encode([]byte("1.0")), }, - []string{ + { Base64Encode([]byte("Contract")), Base64Encode([]byte("0x000")), }, diff --git a/utils/tags_test.go b/utils/tags_test.go index f7e39a8..0e9e062 100644 --- a/utils/tags_test.go +++ b/utils/tags_test.go @@ -10,21 +10,21 @@ import ( func TestTags(t *testing.T) { tagsBase64 := []types.Tag{ - types.Tag{ + { Name: "QXBwLU5hbWU", Value: "U21hcnRXZWF2ZUFjdGlvbg", }, - types.Tag{ + { Name: "SW5wdXQ", Value: "eyJmdW5jdGlvbiI6InRyYW5zZmVyIiwicXR5Ijo1MDAsInRhcmdldCI6Ilp5aGhBTHdxazhuMnVyV1Y0RTNqSEJjNzd3YWE1RnItcUhscl9jdGlIQk0ifQ", }, } tags := []types.Tag{ - types.Tag{ + { Name: "App-Name", Value: "SmartWeaveAction", }, - types.Tag{ + { Name: "Input", Value: `{"function":"transfer","qty":500,"target":"ZyhhALwqk8n2urWV4E3jHBc77waa5Fr-qHlr_ctiHBM"}`, }, diff --git a/wallet.go b/wallet.go index 35914c6..51780bf 100644 --- a/wallet.go +++ b/wallet.go @@ -46,19 +46,19 @@ func (w *Wallet) Owner() string { return w.Signer.Owner() } -func (w *Wallet) SendAR(amount *big.Float, target string, tags []types.Tag) (types.Transaction, error) { - return w.SendWinstonSpeedUp(utils.ARToWinston(amount), target, tags, 0) +func (w *Wallet) SendAR(ctx context.Context, amount *big.Float, target string, tags []types.Tag) (types.Transaction, error) { + return w.SendWinstonSpeedUp(ctx, utils.ARToWinston(amount), target, tags, 0) } -func (w *Wallet) SendARSpeedUp(amount *big.Float, target string, tags []types.Tag, speedFactor int64) (types.Transaction, error) { - return w.SendWinstonSpeedUp(utils.ARToWinston(amount), target, tags, speedFactor) +func (w *Wallet) SendARSpeedUp(ctx context.Context, amount *big.Float, target string, tags []types.Tag, speedFactor int64) (types.Transaction, error) { + return w.SendWinstonSpeedUp(ctx, utils.ARToWinston(amount), target, tags, speedFactor) } -func (w *Wallet) SendWinston(amount *big.Int, target string, tags []types.Tag) (types.Transaction, error) { - return w.SendWinstonSpeedUp(amount, target, tags, 0) +func (w *Wallet) SendWinston(ctx context.Context, amount *big.Int, target string, tags []types.Tag) (types.Transaction, error) { + return w.SendWinstonSpeedUp(ctx, amount, target, tags, 0) } -func (w *Wallet) SendWinstonSpeedUp(amount *big.Int, target string, tags []types.Tag, speedFactor int64) (types.Transaction, error) { +func (w *Wallet) SendWinstonSpeedUp(ctx context.Context, amount *big.Int, target string, tags []types.Tag, speedFactor int64) (types.Transaction, error) { reward, err := w.Client.GetTransactionPrice(0, &target) if err != nil { return types.Transaction{}, err @@ -74,20 +74,20 @@ func (w *Wallet) SendWinstonSpeedUp(amount *big.Int, target string, tags []types Reward: fmt.Sprintf("%d", reward*(100+speedFactor)/100), } - return w.SendTransaction(tx) + return w.SendTransaction(ctx, tx) } -func (w *Wallet) SendData(data []byte, tags []types.Tag) (types.Transaction, error) { - return w.SendDataSpeedUp(data, tags, 0) +func (w *Wallet) SendData(ctx context.Context, data []byte, tags []types.Tag) (types.Transaction, error) { + return w.SendDataSpeedUp(ctx, data, tags, 0) } -func (w *Wallet) SendDataStream(data *os.File, tags []types.Tag) (types.Transaction, error) { - return w.SendDataStreamSpeedUp(data, tags, 0) +func (w *Wallet) SendDataStream(ctx context.Context, data *os.File, tags []types.Tag) (types.Transaction, error) { + return w.SendDataStreamSpeedUp(ctx, data, tags, 0) } // SendDataSpeedUp set speedFactor for speed up // eg: speedFactor = 10, reward = 1.1 * reward -func (w *Wallet) SendDataSpeedUp(data []byte, tags []types.Tag, speedFactor int64) (types.Transaction, error) { +func (w *Wallet) SendDataSpeedUp(ctx context.Context, data []byte, tags []types.Tag, speedFactor int64) (types.Transaction, error) { reward, err := w.Client.GetTransactionPrice(len(data), nil) if err != nil { return types.Transaction{}, err @@ -103,10 +103,10 @@ func (w *Wallet) SendDataSpeedUp(data []byte, tags []types.Tag, speedFactor int6 Reward: fmt.Sprintf("%d", reward*(100+speedFactor)/100), } - return w.SendTransaction(tx) + return w.SendTransaction(ctx, tx) } -func (w *Wallet) SendDataStreamSpeedUp(data *os.File, tags []types.Tag, speedFactor int64) (types.Transaction, error) { +func (w *Wallet) SendDataStreamSpeedUp(ctx context.Context, data *os.File, tags []types.Tag, speedFactor int64) (types.Transaction, error) { fileInfo, err := data.Stat() if err != nil { return types.Transaction{}, err @@ -127,7 +127,7 @@ func (w *Wallet) SendDataStreamSpeedUp(data *os.File, tags []types.Tag, speedFac Reward: fmt.Sprintf("%d", reward*(100+speedFactor)/100), } - return w.SendTransaction(tx) + return w.SendTransaction(ctx, tx) } func (w *Wallet) SendDataConcurrentSpeedUp(ctx context.Context, concurrentNum int, data interface{}, tags []types.Tag, speedFactor int64) (types.Transaction, error) { @@ -167,12 +167,12 @@ func (w *Wallet) SendDataConcurrentSpeedUp(ctx context.Context, concurrentNum in } // SendTransaction: if send success, should return pending -func (w *Wallet) SendTransaction(tx *types.Transaction) (types.Transaction, error) { +func (w *Wallet) SendTransaction(ctx context.Context, tx *types.Transaction) (types.Transaction, error) { uploader, err := w.getUploader(tx) if err != nil { return types.Transaction{}, err } - err = uploader.Once() + err = uploader.Once(ctx) return *tx, err } @@ -198,7 +198,7 @@ func (w *Wallet) getUploader(tx *types.Transaction) (*TransactionUploader, error return CreateUploader(w.Client, tx, nil) } -func (w *Wallet) SendPst(contractId string, target string, qty *big.Int, customTags []types.Tag, speedFactor int64) (types.Transaction, error) { +func (w *Wallet) SendPst(ctx context.Context, contractId string, target string, qty *big.Int, customTags []types.Tag, speedFactor int64) (types.Transaction, error) { maxQty := big.NewInt(9007199254740991) // swc support max js integer if qty.Cmp(maxQty) > 0 { return types.Transaction{}, fmt.Errorf("qty:%s can not more than max integer:%s", qty.String(), maxQty.String()) @@ -229,5 +229,5 @@ func (w *Wallet) SendPst(contractId string, target string, qty *big.Int, customT // rand data data := strconv.Itoa(rand.Intn(9999)) // send data tx - return w.SendDataSpeedUp([]byte(data), swcTags, speedFactor) + return w.SendDataSpeedUp(ctx, []byte(data), swcTags, speedFactor) } diff --git a/wallet_test.go b/wallet_test.go index fb9e710..9a3e781 100644 --- a/wallet_test.go +++ b/wallet_test.go @@ -1,6 +1,7 @@ package goar import ( + "context" "encoding/base64" "os" @@ -117,18 +118,20 @@ func Test_SendPstTransfer(t *testing.T) { } func TestWallet_WarpTransfer(t *testing.T) { + ctx := context.Background() warpGateWay := "https://gateway.warp.cc" w, err := NewWalletFromPath("./wallet/account1.json", warpGateWay) assert.NoError(t, err) contractId := "usjm4PCxUd5mtaon7zc97-dt-3qf67yPyqgzLnLqk5A" // vrt target := "Ii5wAMlLNz13n26nYY45mcZErwZLjICmYd46GZvn4ck" qty := int64(2) - id, err := w.WarpTransfer(contractId, target, qty) + id, err := w.WarpTransfer(ctx, contractId, target, qty) assert.NoError(t, err) t.Log(id) } func TestCreateUploader(t *testing.T) { + ctx := context.Background() w, err := NewWalletFromPath("./wallet/account1.json", "https://arweave.net") assert.NoError(t, err) t.Log(w.Signer.Address) @@ -140,7 +143,7 @@ func TestCreateUploader(t *testing.T) { tags := []types.Tag{ {Name: "Content-Type", Value: "video/mpeg4"}, } - tx, err := w.SendData(data, tags) + tx, err := w.SendData(ctx, data, tags) assert.NoError(t, err) t.Log(tx.ID) } diff --git a/warp.go b/warp.go index aa4b052..7db15b6 100644 --- a/warp.go +++ b/warp.go @@ -1,15 +1,17 @@ package goar import ( + "context" "fmt" + "math/rand" + "strconv" + "github.com/everFinance/goar/types" "github.com/everFinance/goar/utils" "github.com/tidwall/gjson" - "math/rand" - "strconv" ) -func (w *Wallet) WarpTransfer(contractId, target string, qty int64) (id string, err error) { +func (w *Wallet) WarpTransfer(ctx context.Context, contractId, target string, qty int64) (id string, err error) { tags, err := utils.PstTransferTags(contractId, target, qty, true) if err != nil { return @@ -34,7 +36,7 @@ func (w *Wallet) WarpTransfer(contractId, target string, qty int64) (id string, return } // send to wrap gateway - result, err := w.Client.SubmitToWarp(tx) // {"id":"BQQyqbsULPNpyKgwVSSn8z0-3Km_y1GPMiLU1-eR_lc"} + result, err := w.Client.SubmitToWarp(ctx, tx) // {"id":"BQQyqbsULPNpyKgwVSSn8z0-3Km_y1GPMiLU1-eR_lc"} if err != nil { return }